From 82a849ba8e1b95833d2ae7f3bcdd3e1c008bacb5 Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Sat, 18 Sep 2021 09:36:02 +0000 Subject: [PATCH 001/264] add options method --- programs/server/config.xml | 19 ++++++++++++++++++ src/Interpreters/ClientInfo.h | 5 +++-- src/Server/HTTPHandler.cpp | 37 +++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/programs/server/config.xml b/programs/server/config.xml index 6c98ac740fe..bec51de6126 100644 --- a/programs/server/config.xml +++ b/programs/server/config.xml @@ -62,6 +62,25 @@ --> + +
+ Access-Control-Allow-Origin + * +
+
+ Access-Control-Allow-Headers + origin, x-requested-with +
+
+ Access-Control-Allow-Methods + POST, GET, OPTIONS +
+
+ Access-Control-Max-Age + 86400 +
+
+ diff --git a/src/Interpreters/ClientInfo.h b/src/Interpreters/ClientInfo.h index 71570778645..294bf3b426c 100644 --- a/src/Interpreters/ClientInfo.h +++ b/src/Interpreters/ClientInfo.h @@ -35,8 +35,9 @@ public: enum class HTTPMethod : uint8_t { UNKNOWN = 0, - GET = 1, - POST = 2, + GET = 1, + POST = 2, + OPTIONS = 3 }; enum class QueryKind : uint8_t diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 0492b58dc88..99502261aa9 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -32,6 +32,7 @@ #include #include #include +#include "Server/HTTP/HTTPResponse.h" #if !defined(ARCADIA_BUILD) # include @@ -108,6 +109,37 @@ namespace ErrorCodes extern const int HTTP_LENGTH_REQUIRED; } +namespace +{ + /// Process options request. Usefull for CORS. + void processOptionsRequest(HTTPServerResponse & response, const Poco::Util::LayeredConfiguration & config) + { + /// If answer for options request was not defined, return 501 to client. + if (!config.has("http_options_response")) + { + response.setStatusAndReason(HTTPResponse::HTTP_NOT_IMPLEMENTED); + response.send(); + } + else + { + /// otherwise fill response. + Strings config_keys; + config.keys("http_options_response", config_keys); + for (const std::string & config_key : config_keys) + { + if (config_key == "header" || config_key.starts_with("header[")) + { + response.add(config.getString("http_options_response." + config_key + ".name", "Empty header"), + config.getString("http_options_response." + config_key + ".value", "")); + response.setKeepAlive(false); + } + } + response.setStatusAndReason(HTTPResponse::HTTP_NO_CONTENT); + response.send(); + } + } +} + static String base64Decode(const String & encoded) { String decoded; @@ -850,6 +882,11 @@ void HTTPHandler::handleRequest(HTTPServerRequest & request, HTTPServerResponse try { + if (request.getMethod() == HTTPServerRequest::HTTP_OPTIONS) + { + processOptionsRequest(response, server.config()); + return; + } response.setContentType("text/plain; charset=UTF-8"); response.set("X-ClickHouse-Server-Display-Name", server_display_name); /// For keep-alive to work. From 6277747e8aa22b75a788b3e97372678b5c5df756 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 20 Sep 2021 05:37:18 +0000 Subject: [PATCH 002/264] First draft --- .../functions/other-functions.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/en/sql-reference/functions/other-functions.md b/docs/en/sql-reference/functions/other-functions.md index 11cd522c622..af17954fec7 100644 --- a/docs/en/sql-reference/functions/other-functions.md +++ b/docs/en/sql-reference/functions/other-functions.md @@ -2354,3 +2354,39 @@ Result: │ 1 │ └─────────┘ ``` + +## shardNum {#shard-num} + +Returns the number of a shard which executes the query for a distributed query. +If query is not distributed then *constant value* is returned. + +**Syntax** + +``` sql +shardNum() +``` + +**Returned value** + +- Shard number. + +Type: [UInt32](../../sql-reference/data-types/int-uint.md). + +## shardCount {#shard-count} + +Returns the total number of shards which execute a distributed query. +If query is not distributed then *constant value* is returned. + +**Syntax** + +``` sql +shardCount() +``` + +**Returned value** + +- Total number of shards. + +Type: [UInt32](../../sql-reference/data-types/int-uint.md). + + From c8892ec7a71eac73a852ab1b8d200a86148b08c5 Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Wed, 22 Sep 2021 10:34:48 +0000 Subject: [PATCH 003/264] add options support --- src/Server/HTTPHandler.cpp | 19 +++++++++++++------ src/Server/HTTPHandlerFactory.cpp | 4 ++-- src/Server/HTTPHandlerFactory.h | 6 ++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 99502261aa9..017bc82a475 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include "common/logger_useful.h" #include #include #include @@ -111,10 +112,11 @@ namespace ErrorCodes namespace { - /// Process options request. Usefull for CORS. + /// Process options request. Useful for CORS. void processOptionsRequest(HTTPServerResponse & response, const Poco::Util::LayeredConfiguration & config) { - /// If answer for options request was not defined, return 501 to client. + /// If response for options request was not defined, return 501 to client. + /// TODO should it be here? if (!config.has("http_options_response")) { response.setStatusAndReason(HTTPResponse::HTTP_NOT_IMPLEMENTED); @@ -129,12 +131,17 @@ namespace { if (config_key == "header" || config_key.starts_with("header[")) { - response.add(config.getString("http_options_response." + config_key + ".name", "Empty header"), - config.getString("http_options_response." + config_key + ".value", "")); - response.setKeepAlive(false); + /// If there is empty header name, it will not be processed and message about it will be in logs + if (config.getString("http_options_response." + config_key + ".name", "").empty()) + LOG_WARNING(&Poco::Logger::get("processOptionsRequest"), "Empty header was found in config. It will not be processed."); + else + response.add(config.getString("http_options_response." + config_key + ".name", ""), + config.getString("http_options_response." + config_key + ".value", "")); + } } - response.setStatusAndReason(HTTPResponse::HTTP_NO_CONTENT); + response.setKeepAlive(false); + response.setStatusAndReason(HTTPResponse::HTTP_OK); response.send(); } } diff --git a/src/Server/HTTPHandlerFactory.cpp b/src/Server/HTTPHandlerFactory.cpp index 1e3d02b85ab..526b86a5c28 100644 --- a/src/Server/HTTPHandlerFactory.cpp +++ b/src/Server/HTTPHandlerFactory.cpp @@ -123,7 +123,7 @@ static inline HTTPRequestHandlerFactoryPtr createInterserverHTTPHandlerFactory(I addCommonDefaultHandlersFactory(*factory, server); auto main_handler = std::make_shared>(server); - main_handler->allowPostAndGetParamsRequest(); + main_handler->allowPostAndGetParamsAndOptionsRequest(); factory->addHandler(main_handler); return factory; @@ -180,7 +180,7 @@ void addDefaultHandlersFactory(HTTPRequestHandlerFactoryMain & factory, IServer addCommonDefaultHandlersFactory(factory, server); auto query_handler = std::make_shared>(server, "query"); - query_handler->allowPostAndGetParamsRequest(); + query_handler->allowPostAndGetParamsAndOptionsRequest(); factory.addHandler(query_handler); /// We check that prometheus handler will be served on current (default) port. diff --git a/src/Server/HTTPHandlerFactory.h b/src/Server/HTTPHandlerFactory.h index 6297f988eaa..5497d585d43 100644 --- a/src/Server/HTTPHandlerFactory.h +++ b/src/Server/HTTPHandlerFactory.h @@ -104,11 +104,13 @@ public: } /// Handle POST or GET with params - void allowPostAndGetParamsRequest() + void allowPostAndGetParamsAndOptionsRequest() { addFilter([](const auto & request) { - return request.getURI().find('?') != std::string::npos + return (request.getURI().find('?') != std::string::npos + && request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) + || request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS || request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST; }); } From 2cffa98a60677517a372f72a1fea746a19bb0328 Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Wed, 22 Sep 2021 12:22:21 +0000 Subject: [PATCH 004/264] add test and comments in config --- programs/server/config.xml | 6 ++++-- src/Server/HTTPHandler.cpp | 14 ++++--------- tests/config/config.d/CORS.xml | 20 +++++++++++++++++++ .../02029_test_options_requests.reference | 5 +++++ .../02029_test_options_requests.sh | 8 ++++++++ 5 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 tests/config/config.d/CORS.xml create mode 100644 tests/queries/0_stateless/02029_test_options_requests.reference create mode 100755 tests/queries/0_stateless/02029_test_options_requests.sh diff --git a/programs/server/config.xml b/programs/server/config.xml index bec51de6126..26c3107e972 100644 --- a/programs/server/config.xml +++ b/programs/server/config.xml @@ -62,7 +62,9 @@ --> - + + + random + + + 1 diff --git a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp index a4fe3649e6f..5bc10841726 100644 --- a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp +++ b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp @@ -29,9 +29,6 @@ void WriteBufferFromHTTPServerResponse::startSendHeaders() { headers_started_sending = true; - if (add_cors_header) - response.set("Access-Control-Allow-Origin", "*"); - setResponseDefaultHeaders(response, keep_alive_timeout); if (!is_http_method_head) diff --git a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h index b4ff454195f..7cebf5ca770 100644 --- a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h +++ b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h @@ -36,7 +36,6 @@ private: HTTPServerResponse & response; bool is_http_method_head; - bool add_cors_header = false; unsigned keep_alive_timeout = 0; bool compress = false; CompressionMethod compression_method; @@ -103,13 +102,6 @@ public: compression_level = level; } - /// Turn CORS on or off. - /// The setting has any effect only if HTTP headers haven't been sent yet. - void addHeaderCORS(bool enable_cors) - { - add_cors_header = enable_cors; - } - /// Don't send HTTP headers with progress more frequently. void setSendProgressInterval(size_t send_progress_interval_ms_) { diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index cec7e1c8b3d..c27d5343e90 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -33,7 +33,7 @@ #include #include #include -#include "Server/HTTP/HTTPResponse.h" +#include #if !defined(ARCADIA_BUILD) # include @@ -112,33 +112,41 @@ namespace ErrorCodes namespace { - /// Process options request. Useful for CORS. - void processOptionsRequest(HTTPServerResponse & response, const Poco::Util::LayeredConfiguration & config) +bool tryAddHeadersFromConfig(HTTPServerResponse & response, const Poco::Util::LayeredConfiguration & config) +{ + if (config.has("http_options_response")) { - /// If there is information for options request in cofing, fill response. - /// For this purpose find all headers related to http_options_response and add them with their values to response - if (config.has("http_options_response")) + Strings config_keys; + config.keys("http_options_response", config_keys); + for (const std::string & config_key : config_keys) { - Strings config_keys; - config.keys("http_options_response", config_keys); - for (const std::string & config_key : config_keys) + if (config_key == "header" || config_key.starts_with("header[")) { - if (config_key == "header" || config_key.starts_with("header[")) - { - /// If there is empty header name, it will not be processed and message about it will be in logs - if (config.getString("http_options_response." + config_key + ".name", "").empty()) - LOG_WARNING(&Poco::Logger::get("processOptionsRequest"), "Empty header was found in config. It will not be processed."); - else - response.add(config.getString("http_options_response." + config_key + ".name", ""), - config.getString("http_options_response." + config_key + ".value", "")); + /// If there is empty header name, it will not be processed and message about it will be in logs + if (config.getString("http_options_response." + config_key + ".name", "").empty()) + LOG_WARNING(&Poco::Logger::get("processOptionsRequest"), "Empty header was found in config. It will not be processed."); + else + response.add(config.getString("http_options_response." + config_key + ".name", ""), + config.getString("http_options_response." + config_key + ".value", "")); - } } - response.setKeepAlive(false); - response.setStatusAndReason(HTTPResponse::HTTP_NO_CONTENT); - response.send(); } + return true; } + return false; +} + +/// Process options request. Useful for CORS. +void processOptionsRequest(HTTPServerResponse & response, const Poco::Util::LayeredConfiguration & config) +{ + /// If can add some headers from config + if (tryAddHeadersFromConfig(response, config)) + { + response.setKeepAlive(false); + response.setStatusAndReason(HTTPResponse::HTTP_NO_CONTENT); + response.send(); + } +} } static String base64Decode(const String & encoded) @@ -739,9 +747,10 @@ void HTTPHandler::processQuery( if (in_post_compressed && settings.http_native_compression_disable_checksumming_on_decompress) static_cast(*in_post_maybe_compressed).disableChecksumming(); - /// Add CORS header if 'add_http_cors_header' setting is turned on and the client passed - /// Origin header. - used_output.out->addHeaderCORS(settings.add_http_cors_header && !request.get("Origin", "").empty()); + /// Add CORS header if 'add_http_cors_header' setting is turned on or config has http_options_response, + /// which means that there are some headers to be sent, and the client passed Origin header. + if ((settings.add_http_cors_header || config.has("http_options_response")) && !request.get("Origin", "").empty()) + tryAddHeadersFromConfig(response, config); auto append_callback = [context] (ProgressCallback callback) { From ce4193fe957367d28da59e6c94fc54aefb3038db Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Wed, 22 Sep 2021 17:10:15 +0000 Subject: [PATCH 008/264] small refactoring --- src/Server/HTTPHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index c27d5343e90..046e7bdfaad 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -749,7 +749,7 @@ void HTTPHandler::processQuery( /// Add CORS header if 'add_http_cors_header' setting is turned on or config has http_options_response, /// which means that there are some headers to be sent, and the client passed Origin header. - if ((settings.add_http_cors_header || config.has("http_options_response")) && !request.get("Origin", "").empty()) + if (settings.add_http_cors_header && config.has("http_options_response") && !request.get("Origin", "").empty()) tryAddHeadersFromConfig(response, config); auto append_callback = [context] (ProgressCallback callback) From 7bbd08cb5d4c90357fc23b0cbfe96f36cfecff33 Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Fri, 24 Sep 2021 15:40:27 +0300 Subject: [PATCH 009/264] Update HTTPHandler.cpp --- src/Server/HTTPHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index bd4452ac6cb..7357c56ad2e 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -125,7 +125,7 @@ bool tryAddHeadersFromConfig(HTTPServerResponse & response, const Poco::Util::La /// If there is empty header name, it will not be processed and message about it will be in logs if (config.getString("http_options_response." + config_key + ".name", "").empty()) LOG_WARNING(&Poco::Logger::get("processOptionsRequest"), "Empty header was found in config. It will not be processed."); - else + else response.add(config.getString("http_options_response." + config_key + ".name", ""), config.getString("http_options_response." + config_key + ".value", "")); From b3325772f78e5b91ca6aaaee9cc1dd9beafda089 Mon Sep 17 00:00:00 2001 From: Viachaslau Boben Date: Mon, 6 Sep 2021 02:25:22 +0300 Subject: [PATCH 010/264] Add normalizeUTF8 function with NFC normalization --- src/Common/ErrorCodes.cpp | 1 + src/Functions/normalizeString.cpp | 126 ++++++++++++++++++ src/Functions/registerFunctionsString.cpp | 8 ++ .../02011_normalize_utf8.reference | 3 + .../0_stateless/02011_normalize_utf8.sql | 19 +++ 5 files changed, 157 insertions(+) create mode 100644 src/Functions/normalizeString.cpp create mode 100644 tests/queries/0_stateless/02011_normalize_utf8.reference create mode 100644 tests/queries/0_stateless/02011_normalize_utf8.sql diff --git a/src/Common/ErrorCodes.cpp b/src/Common/ErrorCodes.cpp index 53276f5b196..b6d9b65c28b 100644 --- a/src/Common/ErrorCodes.cpp +++ b/src/Common/ErrorCodes.cpp @@ -588,6 +588,7 @@ M(618, LZ4_DECODER_FAILED) \ M(619, POSTGRESQL_REPLICATION_INTERNAL_ERROR) \ M(620, QUERY_NOT_ALLOWED) \ + M(621, CANNOT_NORMALIZE_STRING) \ \ M(999, KEEPER_EXCEPTION) \ M(1000, POCO_EXCEPTION) \ diff --git a/src/Functions/normalizeString.cpp b/src/Functions/normalizeString.cpp new file mode 100644 index 00000000000..178c2dc2cf1 --- /dev/null +++ b/src/Functions/normalizeString.cpp @@ -0,0 +1,126 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/logger_useful.h" +#include "Columns/ColumnString.h" +#include "Parsers/IAST_fwd.h" + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int CANNOT_NORMALIZE_STRING; +} + +namespace +{ + +struct NormalizeUTF8Impl +{ + + static void vector(const ColumnString::Chars & data, + const ColumnString::Offsets & offsets, + ColumnString::Chars & res_data, + ColumnString::Offsets & res_offsets) + { + UErrorCode err = U_ZERO_ERROR; + + const UNormalizer2 *normalizer = unorm2_getNFCInstance(&err); + if (U_FAILURE(err)) { + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); + } + + size_t size = offsets.size(); + res_offsets.resize(size); + + ColumnString::Offset current_from_offset = 0; + ColumnString::Offset current_to_offset = 0; + + icu::UnicodeString to_string; + + PODArray from_uchars; + PODArray to_uchars; + + for (size_t i = 0; i < size; ++i) + { + size_t from_size = offsets[i] - current_from_offset - 1; + + from_uchars.resize(from_size + 1); + int32_t from_code_points; + u_strFromUTF8( + from_uchars.data(), + from_uchars.size(), + &from_code_points, + reinterpret_cast(&data[current_from_offset]), + from_size, + &err); + if (U_FAILURE(err)) { + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); + } + + // NFC should produce no more than 3x code points + // https://unicode.org/faq/normalization.html#12 + to_uchars.resize(from_code_points * 3 + 1); + + int32_t to_code_points = unorm2_normalize( + normalizer, + from_uchars.data(), + from_code_points, + to_uchars.data(), + to_uchars.size(), + &err); + if (U_FAILURE(err)) { + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); + } + + size_t max_to_size = current_to_offset + 2 * to_code_points + 1; + if (res_data.size() < max_to_size) { + res_data.resize(max_to_size); + } + + int32_t to_size; + u_strToUTF8( + reinterpret_cast(&res_data[current_to_offset]), + res_data.size() - current_to_offset, + &to_size, + to_uchars.data(), + to_code_points, + &err); + if (U_FAILURE(err)) { + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); + } + + current_to_offset += to_size; + res_data[current_to_offset] = 0; + ++current_to_offset; + res_offsets[i] = current_to_offset; + + current_from_offset = offsets[i]; + } + } + + [[noreturn]] static void vectorFixed(const ColumnString::Chars &, size_t, ColumnString::Chars &) + { + throw Exception("Cannot apply function normalizeUTF8 to fixed string.", ErrorCodes::ILLEGAL_COLUMN); + } +}; + +struct NameNormalizeUTF8 +{ + static constexpr auto name = "normalizeUTF8"; +}; + +using FunctionNormalizeUTF8 = FunctionStringToString; +} + +void registerFunctionNormalizeUTF8(FunctionFactory & factory) { + factory.registerFunction(); +} + +} diff --git a/src/Functions/registerFunctionsString.cpp b/src/Functions/registerFunctionsString.cpp index ba6a294abba..f2439a3373b 100644 --- a/src/Functions/registerFunctionsString.cpp +++ b/src/Functions/registerFunctionsString.cpp @@ -52,6 +52,10 @@ void registerFunctionSynonyms(FunctionFactory &); void registerFunctionLemmatize(FunctionFactory &); #endif +#if USE_ICU +void registerFunctionNormalizeUTF8(FunctionFactory &); +#endif + void registerFunctionsString(FunctionFactory & factory) { registerFunctionRepeat(factory); @@ -97,6 +101,10 @@ void registerFunctionsString(FunctionFactory & factory) registerFunctionSynonyms(factory); registerFunctionLemmatize(factory); #endif + +#if USE_ICU + registerFunctionNormalizeUTF8(factory); +#endif } } diff --git a/tests/queries/0_stateless/02011_normalize_utf8.reference b/tests/queries/0_stateless/02011_normalize_utf8.reference new file mode 100644 index 00000000000..6878a38ca0d --- /dev/null +++ b/tests/queries/0_stateless/02011_normalize_utf8.reference @@ -0,0 +1,3 @@ +ё ё 2 4 ё ё 2 2 +ё 4 ё 2 +ё 2 ё 2 diff --git a/tests/queries/0_stateless/02011_normalize_utf8.sql b/tests/queries/0_stateless/02011_normalize_utf8.sql new file mode 100644 index 00000000000..c28a0c0a794 --- /dev/null +++ b/tests/queries/0_stateless/02011_normalize_utf8.sql @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS normalize_test; +CREATE TABLE normalize_test (value String) ENGINE = MergeTree ORDER BY value; + +SELECT + 'ё' AS norm, + 'ё' AS denorm, + length(norm), + length(denorm), + normalizeUTF8(norm), + normalizeUTF8(denorm), + length(normalizeUTF8(norm)), + length(normalizeUTF8(denorm)); + +INSERT INTO normalize_test (value) VALUES ('ё'); +INSERT INTO normalize_test (value) VALUES ('ё'); + +SELECT value, length(value), normalizeUTF8(value) AS normalized, length(normalized) FROM normalize_test; + +SELECT char(228) AS value, normalizeUTF8(value); -- { serverError 619 } From 762904adbda95dc24b771250b1f32ccd404db739 Mon Sep 17 00:00:00 2001 From: Viachaslau Boben Date: Mon, 27 Sep 2021 18:45:04 +0300 Subject: [PATCH 011/264] Add nfd and perf test --- src/Functions/normalizeString.cpp | 114 +++++++++++++----- tests/performance/normalize_utf8.xml | 15 +++ .../02011_normalize_utf8.reference | 12 +- .../0_stateless/02011_normalize_utf8.sql | 51 ++++++-- 4 files changed, 148 insertions(+), 44 deletions(-) create mode 100644 tests/performance/normalize_utf8.xml diff --git a/src/Functions/normalizeString.cpp b/src/Functions/normalizeString.cpp index 178c2dc2cf1..5beca566cd1 100644 --- a/src/Functions/normalizeString.cpp +++ b/src/Functions/normalizeString.cpp @@ -1,6 +1,10 @@ +#if !defined(ARCADIA_BUILD) +# include "config_core.h" +#endif + +#if USE_ICU #include #include -#include #include #include #include @@ -15,12 +19,67 @@ namespace DB namespace ErrorCodes { + extern const int ILLEGAL_COLUMN; extern const int CANNOT_NORMALIZE_STRING; } namespace { +// Expansion factors are specified for UTF-32, since icu uses UTF-32 for normalization +// Maximum expansion factors for different normalization forms +// https://unicode.org/faq/normalization.html#12 + +struct NormalizeNFCImpl +{ + static constexpr auto name = "normalizeUTF8NFC"; + + static constexpr auto expansionFactor = 3; + + static const UNormalizer2 *getNormalizer(UErrorCode *err) + { + return unorm2_getNFCInstance(err); + } +}; + +struct NormalizeNFDImpl +{ + static constexpr auto name = "normalizeUTF8NFD"; + + static constexpr auto expansionFactor = 4; + + static const UNormalizer2 *getNormalizer(UErrorCode *err) + { + return unorm2_getNFDInstance(err); + } +}; + +struct NormalizeNFKCImpl +{ + static constexpr auto name = "normalizeUTF8NFKC"; + + static constexpr auto expansionFactor = 18; + + static const UNormalizer2 *getNormalizer(UErrorCode *err) + { + return unorm2_getNFKCInstance(err); + } +}; + + +struct NormalizeNFKDImpl +{ + static constexpr auto name = "normalizeUTF8NFKD"; + + static constexpr auto expansionFactor = 18; + + static const UNormalizer2 *getNormalizer(UErrorCode *err) + { + return unorm2_getNFKDInstance(err); + } +}; + +template struct NormalizeUTF8Impl { @@ -31,10 +90,9 @@ struct NormalizeUTF8Impl { UErrorCode err = U_ZERO_ERROR; - const UNormalizer2 *normalizer = unorm2_getNFCInstance(&err); - if (U_FAILURE(err)) { - throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); - } + const UNormalizer2 *normalizer = NormalizeImpl::getNormalizer(&err); + if (U_FAILURE(err)) + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed (getNormalizer): {}", u_errorName(err)); size_t size = offsets.size(); res_offsets.resize(size); @@ -60,13 +118,10 @@ struct NormalizeUTF8Impl reinterpret_cast(&data[current_from_offset]), from_size, &err); - if (U_FAILURE(err)) { - throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); - } + if (U_FAILURE(err)) + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed (strFromUTF8): {}", u_errorName(err)); - // NFC should produce no more than 3x code points - // https://unicode.org/faq/normalization.html#12 - to_uchars.resize(from_code_points * 3 + 1); + to_uchars.resize(from_code_points * NormalizeImpl::expansionFactor + 1); int32_t to_code_points = unorm2_normalize( normalizer, @@ -75,14 +130,12 @@ struct NormalizeUTF8Impl to_uchars.data(), to_uchars.size(), &err); - if (U_FAILURE(err)) { - throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); - } + if (U_FAILURE(err)) + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed (normalize): {}", u_errorName(err)); - size_t max_to_size = current_to_offset + 2 * to_code_points + 1; - if (res_data.size() < max_to_size) { + size_t max_to_size = current_to_offset + 4 * to_code_points + 1; + if (res_data.size() < max_to_size) res_data.resize(max_to_size); - } int32_t to_size; u_strToUTF8( @@ -92,9 +145,8 @@ struct NormalizeUTF8Impl to_uchars.data(), to_code_points, &err); - if (U_FAILURE(err)) { - throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed: {}", u_errorName(err)); - } + if (U_FAILURE(err)) + throw Exception(ErrorCodes::CANNOT_NORMALIZE_STRING, "Normalization failed (strToUTF8): {}", u_errorName(err)); current_to_offset += to_size; res_data[current_to_offset] = 0; @@ -111,16 +163,20 @@ struct NormalizeUTF8Impl } }; -struct NameNormalizeUTF8 +using FunctionNormalizeUTF8NFC = FunctionStringToString, NormalizeNFCImpl>; +using FunctionNormalizeUTF8NFD = FunctionStringToString, NormalizeNFDImpl>; +using FunctionNormalizeUTF8NFKC = FunctionStringToString, NormalizeNFKCImpl>; +using FunctionNormalizeUTF8NFKD = FunctionStringToString, NormalizeNFKDImpl>; +} + +void registerFunctionNormalizeUTF8(FunctionFactory & factory) { - static constexpr auto name = "normalizeUTF8"; -}; - -using FunctionNormalizeUTF8 = FunctionStringToString; -} - -void registerFunctionNormalizeUTF8(FunctionFactory & factory) { - factory.registerFunction(); + factory.registerFunction(); + factory.registerFunction(); + factory.registerFunction(); + factory.registerFunction(); } } + +#endif diff --git a/tests/performance/normalize_utf8.xml b/tests/performance/normalize_utf8.xml new file mode 100644 index 00000000000..de9bd87fdf8 --- /dev/null +++ b/tests/performance/normalize_utf8.xml @@ -0,0 +1,15 @@ + + + hits_10m_single + + + CREATE TABLE strings (words String) ENGINE Memory + INSERT INTO strings SELECT SearchPhrase FROM hits_10m_single WHERE length(SearchPhrase) > 0 + + SELECT normalizeUTF8NFC(words) FROM strings FORMAT Null + SELECT normalizeUTF8NFD(words) FROM strings FORMAT Null + SELECT normalizeUTF8NFKC(words) FROM strings FORMAT Null + SELECT normalizeUTF8NFKD(words) FROM strings FORMAT Null + + DROP TABLE IF EXISTS strings + diff --git a/tests/queries/0_stateless/02011_normalize_utf8.reference b/tests/queries/0_stateless/02011_normalize_utf8.reference index 6878a38ca0d..b97f0ee5a01 100644 --- a/tests/queries/0_stateless/02011_normalize_utf8.reference +++ b/tests/queries/0_stateless/02011_normalize_utf8.reference @@ -1,3 +1,11 @@ ё ё 2 4 ё ё 2 2 -ё 4 ё 2 -ё 2 ё 2 +1 ё 4 ё 2 ё 4 ё 2 ё 4 +2 ё 2 ё 2 ё 4 ё 2 ё 4 +3 జ్ఞ‌ా 15 జ్ఞ‌ా 15 జ్ఞ‌ా 15 జ్ఞ‌ా 15 జ్ఞ‌ా 15 +4 本気ですか 15 本気ですか 15 本気ですか 18 本気ですか 15 本気ですか 18 +5 ﷺ 3 ﷺ 3 ﷺ 3 صلى الله عليه وسلم 33 صلى الله عليه وسلم 33 +6 ᾂ 3 ᾂ 3 ᾂ 8 ᾂ 3 ᾂ 8 +7 ΐ 2 ΐ 2 ΐ 6 ΐ 2 ΐ 6 +8 שּׁ 6 שּׁ 6 שּׁ 6 שּׁ 6 שּׁ 6 +9 𝅘𝅥𝅮 12 𝅘𝅥𝅮 12 𝅘𝅥𝅮 12 𝅘𝅥𝅮 12 𝅘𝅥𝅮 12 +10 Q̹̣̩̭̰̰̹̄ͬ̿͋̃ṷ̬̰ͥe̘͚͈̰̺̍͐s͎̜̖t͔̣̯̲̜̠ͣ̑ͨ̉̈̈o̲͙̺͊ͯͣ̐̋̂̔ ̳͉͍̒̂è̗ͥͯͨ̍ͮ͛ ̦̹̣̰̐̅̑͑̅̂t͙̭̻̖͛̾e̺͙ͣ͒̚ṣ̠͉͓͔̲̦̎t̖͖̝͓̣ͭ͑̈́̂ỏ̥͕͈͛̓ ̀ͦ̽ͅZͯ̑̎a͆l̻ͨ̋ͧͣͨͬg͉̙̟̾̅̾ͬo̠ͮ͒ 281 Q̹̣̩̭̰̰̹̄ͬ̿͋̃ṷ̬̰ͥe̘͚͈̰̺̍͐s͎̜̖t͔̣̯̲̜̠ͣ̑ͨ̉̈̈o̲͙̺͊ͯͣ̐̋̂̔ ̳͉͍̒̂è̗ͥͯͨ̍ͮ͛ ̦̹̣̰̐̅̑͑̅̂t͙̭̻̖͛̾e̺͙ͣ͒̚ṣ̠͉͓͔̲̦̎t̖͖̝͓̣ͭ͑̈́̂ỏ̥͕͈͛̓ ̀ͦ̽ͅZͯ̑̎a͆l̻ͨ̋ͧͣͨͬg͉̙̟̾̅̾ͬo̠ͮ͒ 281 Q̹̣̩̭̰̰̹̄ͬ̿͋̃ṷ̬̰ͥe̘͚͈̰̺̍͐s͎̜̖t͔̣̯̲̜̠ͣ̑ͨ̉̈̈o̲͙̺͊ͯͣ̐̋̂̔ ̳͉͍̒̂è̗ͥͯͨ̍ͮ͛ ̦̹̣̰̐̅̑͑̅̂t͙̭̻̖͛̾e̺͙ͣ͒̚ṣ̠͉͓͔̲̦̎t̖͖̝͓̣ͭ͑̈́̂ỏ̥͕͈͛̓ ̀ͦ̽ͅZͯ̑̎a͆l̻ͨ̋ͧͣͨͬg͉̙̟̾̅̾ͬo̠ͮ͒ 282 Q̹̣̩̭̰̰̹̄ͬ̿͋̃ṷ̬̰ͥe̘͚͈̰̺̍͐s͎̜̖t͔̣̯̲̜̠ͣ̑ͨ̉̈̈o̲͙̺͊ͯͣ̐̋̂̔ ̳͉͍̒̂è̗ͥͯͨ̍ͮ͛ ̦̹̣̰̐̅̑͑̅̂t͙̭̻̖͛̾e̺͙ͣ͒̚ṣ̠͉͓͔̲̦̎t̖͖̝͓̣ͭ͑̈́̂ỏ̥͕͈͛̓ ̀ͦ̽ͅZͯ̑̎a͆l̻ͨ̋ͧͣͨͬg͉̙̟̾̅̾ͬo̠ͮ͒ 281 Q̹̣̩̭̰̰̹̄ͬ̿͋̃ṷ̬̰ͥe̘͚͈̰̺̍͐s͎̜̖t͔̣̯̲̜̠ͣ̑ͨ̉̈̈o̲͙̺͊ͯͣ̐̋̂̔ ̳͉͍̒̂è̗ͥͯͨ̍ͮ͛ ̦̹̣̰̐̅̑͑̅̂t͙̭̻̖͛̾e̺͙ͣ͒̚ṣ̠͉͓͔̲̦̎t̖͖̝͓̣ͭ͑̈́̂ỏ̥͕͈͛̓ ̀ͦ̽ͅZͯ̑̎a͆l̻ͨ̋ͧͣͨͬg͉̙̟̾̅̾ͬo̠ͮ͒ 282 diff --git a/tests/queries/0_stateless/02011_normalize_utf8.sql b/tests/queries/0_stateless/02011_normalize_utf8.sql index c28a0c0a794..5abb6b4d8fb 100644 --- a/tests/queries/0_stateless/02011_normalize_utf8.sql +++ b/tests/queries/0_stateless/02011_normalize_utf8.sql @@ -1,19 +1,44 @@ +-- Tags: no-fasttest + DROP TABLE IF EXISTS normalize_test; -CREATE TABLE normalize_test (value String) ENGINE = MergeTree ORDER BY value; +CREATE TABLE normalize_test (id int, value String) ENGINE = MergeTree ORDER BY value; + SELECT - 'ё' AS norm, - 'ё' AS denorm, - length(norm), - length(denorm), - normalizeUTF8(norm), - normalizeUTF8(denorm), - length(normalizeUTF8(norm)), - length(normalizeUTF8(denorm)); + 'ё' AS norm, 'ё' AS denorm, + length(norm), length(denorm), + normalizeUTF8NFC(norm) AS norm_nfc, + normalizeUTF8NFC(denorm) AS denorm_nfc, + length(norm_nfc), + length(denorm_nfc); -INSERT INTO normalize_test (value) VALUES ('ё'); -INSERT INTO normalize_test (value) VALUES ('ё'); -SELECT value, length(value), normalizeUTF8(value) AS normalized, length(normalized) FROM normalize_test; +INSERT INTO normalize_test (id, value) VALUES (1, 'ё'); +INSERT INTO normalize_test (id, value) VALUES (2, 'ё'); +INSERT INTO normalize_test (id, value) VALUES (3, 'జ్ఞ‌ా'); +INSERT INTO normalize_test (id, value) VALUES (4, '本気ですか'); +INSERT INTO normalize_test (id, value) VALUES (5, 'ﷺ'); +INSERT INTO normalize_test (id, value) VALUES (6, 'ᾂ'); +INSERT INTO normalize_test (id, value) VALUES (7, 'ΐ'); +INSERT INTO normalize_test (id, value) VALUES (8, 'שּׁ'); +INSERT INTO normalize_test (id, value) VALUES (9, '𝅘𝅥𝅮'); -SELECT char(228) AS value, normalizeUTF8(value); -- { serverError 619 } + +INSERT INTO normalize_test (id, value) VALUES (10, 'Q̹̣̩̭̰̰̹̄ͬ̿͋̃ṷ̬̰ͥe̘͚͈̰̺̍͐s͎̜̖t͔̣̯̲̜̠ͣ̑ͨ̉̈̈o̲͙̺͊ͯͣ̐̋̂̔ ̳͉͍̒̂è̗ͥͯͨ̍ͮ͛ ̦̹̣̰̐̅̑͑̅̂t͙̭̻̖͛̾e̺͙ͣ͒̚ṣ̠͉͓͔̲̦̎t̖͖̝͓̣ͭ͑̈́̂ỏ̥͕͈͛̓ ̀ͦ̽ͅZͯ̑̎a͆l̻ͨ̋ͧͣͨͬg͉̙̟̾̅̾ͬo̠ͮ͒'); + + + +SELECT + id, value, length(value), + normalizeUTF8NFC(value) AS nfc, length(nfc) AS nfc_len, + normalizeUTF8NFD(value) AS nfd, length(nfd) AS nfd_len, + normalizeUTF8NFKC(value) AS nfkc, length(nfkc) AS nfkc_len, + normalizeUTF8NFKD(value) AS nfkd, length(nfkd) AS nfkd_len +FROM normalize_test +ORDER BY id; + + +SELECT char(228) AS value, normalizeUTF8NFC(value); -- { serverError 621 } +SELECT char(228) AS value, normalizeUTF8NFD(value); -- { serverError 621 } +SELECT char(228) AS value, normalizeUTF8NFKC(value); -- { serverError 621 } +SELECT char(228) AS value, normalizeUTF8NFKD(value); -- { serverError 621 } From fcebf7b9853452caaffc39d91a31d19ae55a45ba Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Wed, 29 Sep 2021 11:29:24 +0000 Subject: [PATCH 012/264] correct tests --- src/Server/HTTPHandlerFactory.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Server/HTTPHandlerFactory.h b/src/Server/HTTPHandlerFactory.h index e81955ef2b2..f6d96189d92 100644 --- a/src/Server/HTTPHandlerFactory.h +++ b/src/Server/HTTPHandlerFactory.h @@ -108,8 +108,7 @@ public: { addFilter([](const auto & request) { - return (request.getURI().find('?') != std::string::npos - && request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) + return request.getURI().find('?') != std::string::npos || request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS || request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST; }); From 36b699659e466c1deaf4737f973adcfc95fe378b Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Wed, 29 Sep 2021 14:32:04 +0300 Subject: [PATCH 013/264] Update CORS.xml --- tests/config/config.d/CORS.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/config/config.d/CORS.xml b/tests/config/config.d/CORS.xml index 9dd7d402416..873821478dc 100644 --- a/tests/config/config.d/CORS.xml +++ b/tests/config/config.d/CORS.xml @@ -1,4 +1,4 @@ - +
Access-Control-Allow-Origin @@ -17,5 +17,5 @@ 86400
- + From d75136c3b1b3040b87dde90463e9a0e8a087b16b Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 29 Sep 2021 16:59:56 +0300 Subject: [PATCH 014/264] Update hash functions (SHA) en --- .../sql-reference/functions/hash-functions.md | 145 +++++++++++++++++- 1 file changed, 144 insertions(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/hash-functions.md b/docs/en/sql-reference/functions/hash-functions.md index 227e2885417..a3154e5c200 100644 --- a/docs/en/sql-reference/functions/hash-functions.md +++ b/docs/en/sql-reference/functions/hash-functions.md @@ -139,17 +139,160 @@ It works faster than intHash32. Average quality. ## SHA1 {#sha1} +Calculates SHA-1 hash from a string and returns the resulting set of bytes as [FixedString(20)](../data-types/fixedstring.md). + +**Syntax** + +``` sql +SHA1('s') +``` + +**Arguments** + +- `s` — Input string for SHA-1 hash calculation. [String](..data-types/string.md). + +**Returned value** + +- SHA-1 hash as a hex-unencoded FixedString(10). + +Type: [FixedString](../data-types/fixedstring.md). + +**Example** + +Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. + +Query: + +``` sql +SELECT hex(SHA1('abc')); +``` + +Result: + +``` text +┌─hex(SHA1('abc'))─────────────────────────┐ +│ A9993E364706816ABA3E25717850C26C9CD0D89D │ +└──────────────────────────────────────────┘ +``` + ## SHA224 {#sha224} +Calculates SHA-224 hash from a string and returns the resulting set of bytes as [FixedString(28)](../data-types/fixedstring.md). + +**Syntax** + +``` sql +SHA224('s') +``` + +**Arguments** + +- `s` — Input string for SHA-224 hash calculation. [String](..data-types/string.md). + +**Returned value** + +- SHA-224 hash as a hex-unencoded FixedString(28). + +Type: [FixedString](../data-types/fixedstring.md). + +**Example** + +Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. + +Query: + +``` sql +SELECT hex(SHA224('abc')); +``` + +Result: + +``` text +┌─hex(SHA224('abc'))───────────────────────────────────────┐ +│ 23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7 │ +└──────────────────────────────────────────────────────────┘ +``` + ## SHA256 {#sha256} +Calculates SHA-256 hash from a string and returns the resulting set of bytes as [FixedString(32)](../data-types/fixedstring.md). + +**Syntax** + +``` sql +SHA256('s') +``` + +**Arguments** + +- `s` — Input string for SHA-256 hash calculation. [String](..data-types/string.md). + +**Returned value** + +- SHA-256 hash as a hex-unencoded FixedString(32). + +Type: [FixedString](../data-types/fixedstring.md). + +**Example** + +Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. + +Query: + +``` sql +SELECT hex(SHA256('abc')); +``` + +Result: + +``` text +┌─hex(SHA256('abc'))───────────────────────────────────────────────┐ +│ BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD │ +└──────────────────────────────────────────────────────────────────┘ +``` + ## SHA512 {#sha512} -Calculates SHA-1, SHA-224, SHA-256 or SHA-512 from a string and returns the resulting set of bytes as FixedString(20), FixedString(28), FixedString(32), or FixedString(64). +Calculates SHA-512 hash from a string and returns the resulting set of bytes as [FixedString(64)](../data-types/fixedstring.md). + +**Syntax** + +``` sql +SHA512('s') +``` + The function works fairly slowly (SHA-1 processes about 5 million short strings per second per processor core, while SHA-224 and SHA-256 process about 2.2 million). We recommend using this function only in cases when you need a specific hash function and you can’t select it. Even in these cases, we recommend applying the function offline and pre-calculating values when inserting them into the table, instead of applying it in SELECTS. +**Arguments** + +- `s` — Input string for SHA-512 hash calculation. [String](..data-types/string.md). + +**Returned value** + +- SHA-512 hash as a hex-unencoded FixedString(64). + +Type: [FixedString](../data-types/fixedstring.md). + +**Example** + +Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. + +Query: + +``` sql +SELECT hex(SHA512('abc')); +``` + +Result: + +``` text +┌─hex(SHA512('abc'))───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + ## URLHash(url\[, N\]) {#urlhashurl-n} A fast, decent-quality non-cryptographic hash function for a string obtained from a URL using some type of normalization. From e312156b1c2a6a8a79177fb543c5d110ea47a058 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 29 Sep 2021 17:52:39 +0300 Subject: [PATCH 015/264] Add note about Materialized views --- docs/en/sql-reference/functions/hash-functions.md | 2 +- docs/en/sql-reference/statements/create/view.md | 7 +++---- docs/ru/sql-reference/statements/create/view.md | 5 ++++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/en/sql-reference/functions/hash-functions.md b/docs/en/sql-reference/functions/hash-functions.md index a3154e5c200..dc4c749865a 100644 --- a/docs/en/sql-reference/functions/hash-functions.md +++ b/docs/en/sql-reference/functions/hash-functions.md @@ -263,7 +263,7 @@ SHA512('s') The function works fairly slowly (SHA-1 processes about 5 million short strings per second per processor core, while SHA-224 and SHA-256 process about 2.2 million). We recommend using this function only in cases when you need a specific hash function and you can’t select it. -Even in these cases, we recommend applying the function offline and pre-calculating values when inserting them into the table, instead of applying it in SELECTS. +Even in these cases, we recommend applying the function offline and pre-calculating values when inserting them into the table, instead of applying it in `SELECT` queries. **Arguments** diff --git a/docs/en/sql-reference/statements/create/view.md b/docs/en/sql-reference/statements/create/view.md index b6a09e25f95..84213020925 100644 --- a/docs/en/sql-reference/statements/create/view.md +++ b/docs/en/sql-reference/statements/create/view.md @@ -50,14 +50,13 @@ When creating a materialized view with `TO [db].[table]`, you must not use `POPU A materialized view is implemented as follows: when inserting data to the table specified in `SELECT`, part of the inserted data is converted by this `SELECT` query, and the result is inserted in the view. !!! important "Important" - Materialized views in ClickHouse use **column names** instead of column order during insertion into destination table. If some column names are not present in `SELECT`'s result ClickHouse will use a default value, even if column is not `Nullable`. A safe practice would be to add aliases for every column when using Materialized views. + Materialized views in ClickHouse use **column names** instead of column order during insertion into destination table. If some column names are not present in `SELECT`'s result ClickHouse will use a default value, even if column is not [Nullable](../data-types/nullable.md). A safe practice would be to add aliases for every column when using Materialized views. -!!! important "Important" Materialized views in ClickHouse are implemented more like insert triggers. If there’s some aggregation in the view query, it’s applied only to the batch of freshly inserted data. Any changes to existing data of source table (like update, delete, drop partition, etc.) does not change the materialized view. -If you specify `POPULATE`, the existing table data is inserted in the view when creating it, as if making a `CREATE TABLE ... AS SELECT ...` . Otherwise, the query contains only the data inserted in the table after creating the view. We **do not recommend** using POPULATE, since data inserted in the table during the view creation will not be inserted in it. +If you specify `POPULATE`, the existing table data is inserted in the view when creating it, as if making a `CREATE TABLE ... AS SELECT ...` . Otherwise, the query contains only the data inserted in the table after creating the view. We **do not recommend** using `POPULATE`, since data inserted in the table during the view creation will not be inserted in it. -A `SELECT` query can contain `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`… Note that the corresponding conversions are performed independently on each block of inserted data. For example, if `GROUP BY` is set, data is aggregated during insertion, but only within a single packet of inserted data. The data won’t be further aggregated. The exception is when using an `ENGINE` that independently performs data aggregation, such as `SummingMergeTree`. +A `SELECT` query can contain `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`. Note that the corresponding conversions are performed independently on each block of inserted data. For example, if `GROUP BY` is set, data is aggregated during insertion, but only within a single packet of inserted data. The data won’t be further aggregated. The exception is when using an `ENGINE` that independently performs data aggregation, such as `SummingMergeTree`. The execution of [ALTER](../../../sql-reference/statements/alter/view.md) queries on materialized views has limitations, so they might be inconvenient. If the materialized view uses the construction `TO [db.]name`, you can `DETACH` the view, run `ALTER` for the target table, and then `ATTACH` the previously detached (`DETACH`) view. diff --git a/docs/ru/sql-reference/statements/create/view.md b/docs/ru/sql-reference/statements/create/view.md index ccbf79baa73..53d75b78dd1 100644 --- a/docs/ru/sql-reference/statements/create/view.md +++ b/docs/ru/sql-reference/statements/create/view.md @@ -48,9 +48,12 @@ CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]na Материализованное представление устроено следующим образом: при вставке данных в таблицу, указанную в SELECT-е, кусок вставляемых данных преобразуется этим запросом SELECT, и полученный результат вставляется в представление. !!! important "Важно" + + Материализованные представления в ClickHouse используют **имена столбцов** вместо порядка следования столбцов при вставке в целевую таблицу. Если в результатах запроса `SELECT` некоторые имена столбцов отсутствуют, то ClickHouse будет использовать значение по умолчанию, даже если столбец не является [Nullable](../data-types/nullable.md). Безопасной практикой, при использовании материализованных представлений, считается добавление псевдонимов для каждого столбца. + Материализованные представления в ClickHouse больше похожи на `after insert` триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление. -Если указано `POPULATE`, то при создании представления, в него будут вставлены имеющиеся данные таблицы, как если бы был сделан запрос `CREATE TABLE ... AS SELECT ...` . Иначе, представление будет содержать только данные, вставляемые в таблицу после создания представления. Не рекомендуется использовать POPULATE, так как вставляемые в таблицу данные во время создания представления, не попадут в него. +Если указано `POPULATE`, то при создании представления, в него будут вставлены имеющиеся данные таблицы, как если бы был сделан запрос `CREATE TABLE ... AS SELECT ...` . Иначе, представление будет содержать только данные, вставляемые в таблицу после создания представления. Не рекомендуется использовать `POPULATE`, так как вставляемые в таблицу данные во время создания представления, не попадут в него. Запрос `SELECT` может содержать `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`… Следует иметь ввиду, что соответствующие преобразования будут выполняться независимо, на каждый блок вставляемых данных. Например, при наличии `GROUP BY`, данные будут агрегироваться при вставке, но только в рамках одной пачки вставляемых данных. Далее, данные не будут доагрегированы. Исключение - использование ENGINE, производящего агрегацию данных самостоятельно, например, `SummingMergeTree`. From b226429435eeda0cae88b7553f471b6e413cff3d Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 29 Sep 2021 18:41:15 +0300 Subject: [PATCH 016/264] Fix links, add 512 translation. --- .../sql-reference/functions/hash-functions.md | 8 ++-- .../sql-reference/functions/hash-functions.md | 45 ++++++++++++++++++- 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/docs/en/sql-reference/functions/hash-functions.md b/docs/en/sql-reference/functions/hash-functions.md index dc4c749865a..e28594540be 100644 --- a/docs/en/sql-reference/functions/hash-functions.md +++ b/docs/en/sql-reference/functions/hash-functions.md @@ -149,7 +149,7 @@ SHA1('s') **Arguments** -- `s` — Input string for SHA-1 hash calculation. [String](..data-types/string.md). +- `s` — Input string for SHA-1 hash calculation. [String](../data-types/string.md). **Returned value** @@ -187,7 +187,7 @@ SHA224('s') **Arguments** -- `s` — Input string for SHA-224 hash calculation. [String](..data-types/string.md). +- `s` — Input string for SHA-224 hash calculation. [String](../data-types/string.md). **Returned value** @@ -225,7 +225,7 @@ SHA256('s') **Arguments** -- `s` — Input string for SHA-256 hash calculation. [String](..data-types/string.md). +- `s` — Input string for SHA-256 hash calculation. [String](../data-types/string.md). **Returned value** @@ -267,7 +267,7 @@ Even in these cases, we recommend applying the function offline and pre-calculat **Arguments** -- `s` — Input string for SHA-512 hash calculation. [String](..data-types/string.md). +- `s` — Input string for SHA-512 hash calculation. [String](../data-types/string.md). **Returned value** diff --git a/docs/ru/sql-reference/functions/hash-functions.md b/docs/ru/sql-reference/functions/hash-functions.md index 07c741e0588..d7e86d5a540 100644 --- a/docs/ru/sql-reference/functions/hash-functions.md +++ b/docs/ru/sql-reference/functions/hash-functions.md @@ -143,10 +143,51 @@ SELECT groupBitXor(cityHash64(*)) FROM table ## SHA256 {#sha256} -Вычисляет SHA-1, SHA-224, SHA-256 от строки и возвращает полученный набор байт в виде FixedString(20), FixedString(28), FixedString(32). + + +## SHA512 {#sha512} + +Вычисляет SHA-1, SHA-224, SHA-256 хеш строки и возвращает полученный набор байт в виде FixedString(20), FixedString(28), FixedString(32), [FixedString(64)](../data-types/fixedstring.md) + +Вычисляет SHA-512 хеш строки и возвращает полученный набор байт в виде [FixedString(64)](../data-types/fixedstring.md) + +**Синтаксис** + +``` sql +SHA512('s') +``` + Функция работает достаточно медленно (SHA-1 - примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 - примерно 2.2 миллионов). Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хэш-функция и вы не можете её выбрать. -Даже в этих случаях, рекомендуется применять функцию оффлайн - заранее вычисляя значения при вставке в таблицу, вместо того, чтобы применять её при SELECT-ах. +Даже в этих случаях, рекомендуется применять функцию оффлайн - заранее вычисляя значения при вставке в таблицу, вместо того, чтобы применять её при выполнении `SELECT`. + +**Параметры** + +- `s` — входная строка для вычисления хеша SHA-512. [String](../data-types/string.md). + +**Возвращаемое значение** + +- Хеш SHA-512 в виде шестнадцатеричной некодированной строки FixedString(64). + +Тип: [FixedString](../data-types/fixedstring.md). + +**Пример** + +Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. + +Запрос: + +``` sql +SELECT hex(SHA512('abc')); +``` + +Результат: + +``` text +┌─hex(SHA512('abc'))───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ +│ DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F │ +└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ +``` ## URLHash(url\[, N\]) {#urlhashurl-n} From cac28833d247617804627e3059589da17c09de1d Mon Sep 17 00:00:00 2001 From: Artur Filatenkov <613623@mail.ru> Date: Wed, 29 Sep 2021 18:54:04 +0300 Subject: [PATCH 017/264] apply added config in tests --- tests/config/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/config/install.sh b/tests/config/install.sh index df62cba0ea9..936c44a4e7b 100755 --- a/tests/config/install.sh +++ b/tests/config/install.sh @@ -37,6 +37,7 @@ ln -sf $SRC_PATH/config.d/tcp_with_proxy.xml $DEST_SERVER_PATH/config.d/ ln -sf $SRC_PATH/config.d/top_level_domains_lists.xml $DEST_SERVER_PATH/config.d/ ln -sf $SRC_PATH/config.d/top_level_domains_path.xml $DEST_SERVER_PATH/config.d/ ln -sf $SRC_PATH/config.d/encryption.xml $DEST_SERVER_PATH/config.d/ +ln -sf $SRC_PATH/config.d/CORS.xml $DEST_SERVER_PATH/config.d/ ln -sf $SRC_PATH/config.d/zookeeper_log.xml $DEST_SERVER_PATH/config.d/ ln -sf $SRC_PATH/config.d/logger.xml $DEST_SERVER_PATH/config.d/ ln -sf $SRC_PATH/users.d/log_queries.xml $DEST_SERVER_PATH/users.d/ @@ -57,7 +58,6 @@ ln -sf $SRC_PATH/strings_dictionary.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/decimals_dictionary.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/executable_dictionary.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/executable_pool_dictionary.xml $DEST_SERVER_PATH/ -ln -sf $SRC_PATH/test_function.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/top_level_domains $DEST_SERVER_PATH/ From 02205492e5cef5119455bbed48d339349cb4575e Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 29 Sep 2021 19:55:11 +0300 Subject: [PATCH 018/264] Update hash-functions.md Add ru translation. --- .../sql-reference/functions/hash-functions.md | 110 +++++++++++++++++- 1 file changed, 107 insertions(+), 3 deletions(-) diff --git a/docs/ru/sql-reference/functions/hash-functions.md b/docs/ru/sql-reference/functions/hash-functions.md index d7e86d5a540..98b5ed6df27 100644 --- a/docs/ru/sql-reference/functions/hash-functions.md +++ b/docs/ru/sql-reference/functions/hash-functions.md @@ -139,16 +139,120 @@ SELECT groupBitXor(cityHash64(*)) FROM table ## SHA1 {#sha1} +Вычисляет SHA-1 хеш строки и возвращает полученный набор байт в виде [FixedString(20)](../data-types/fixedstring.md). + +**Синтаксис** + +``` sql +SHA1('s') +``` + +**Параметры** + +- `s` — входная строка для вычисления хеша SHA-1. [String](../data-types/string.md). + +**Возвращаемое значение** + +- Хеш SHA-1 в виде шестнадцатеричной некодированной строки FixedString(20). + +Тип: [FixedString](../data-types/fixedstring.md). + +**Пример** + +Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. + +Запрос: + +``` sql +SELECT hex(SHA1('abc')); +``` + +Результат: + +``` text +┌─hex(SHA1('abc'))─────────────────────────┐ +│ A9993E364706816ABA3E25717850C26C9CD0D89D │ +└──────────────────────────────────────────┘ +``` + ## SHA224 {#sha224} +Вычисляет SHA-224 хеш строки и возвращает полученный набор байт в виде [FixedString(28)](../data-types/fixedstring.md). + +**Синтаксис** + +``` sql +SHA224('s') +``` + +**Параметры** + +- `s` — входная строка для вычисления хеша SHA-224. [String](../data-types/string.md). + +**Возвращаемое значение** + +- Хеш SHA-224 в виде шестнадцатеричной некодированной строки FixedString(28). + +Тип: [FixedString](../data-types/fixedstring.md). + +**Пример** + +Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. + +Запрос: + +``` sql +SELECT hex(SHA224('abc')); +``` + +Результат: + +``` text +┌─hex(SHA224('abc'))───────────────────────────────────────┐ +│ 23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7 │ +└──────────────────────────────────────────────────────────┘ +``` + ## SHA256 {#sha256} +Вычисляет SHA-256 хеш строки и возвращает полученный набор байт в виде [FixedString(32)](../data-types/fixedstring.md). +**Синтаксис** + +``` sql +SHA256('s') +``` + +**Параметры** + +- `s` — входная строка для вычисления хеша SHA-256. [String](../data-types/string.md). + +**Возвращаемое значение** + +- Хеш SHA-256 в виде шестнадцатеричной некодированной строки FixedString(32). + +Тип: [FixedString](../data-types/fixedstring.md). + +**Пример** + +Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. + +Запрос: + +``` sql +SELECT hex(SHA256('abc')); +``` + +Результат: + +``` text +┌─hex(SHA256('abc'))───────────────────────────────────────────────┐ +│ BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD │ +└──────────────────────────────────────────────────────────────────┘ +``` ## SHA512 {#sha512} -Вычисляет SHA-1, SHA-224, SHA-256 хеш строки и возвращает полученный набор байт в виде FixedString(20), FixedString(28), FixedString(32), [FixedString(64)](../data-types/fixedstring.md) - Вычисляет SHA-512 хеш строки и возвращает полученный набор байт в виде [FixedString(64)](../data-types/fixedstring.md) **Синтаксис** @@ -157,7 +261,7 @@ SELECT groupBitXor(cityHash64(*)) FROM table SHA512('s') ``` -Функция работает достаточно медленно (SHA-1 - примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 - примерно 2.2 миллионов). +Функция работает достаточно медленно (SHA-1 — примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 — примерно 2.2 миллионов). Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хэш-функция и вы не можете её выбрать. Даже в этих случаях, рекомендуется применять функцию оффлайн - заранее вычисляя значения при вставке в таблицу, вместо того, чтобы применять её при выполнении `SELECT`. From 66bb857a1a7988ec0f94bc9c83668ff662b651b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Wed, 29 Sep 2021 19:11:38 +0200 Subject: [PATCH 019/264] Add test for JOIN engine deadlock --- .../02033_join_engine_deadlock.reference | 0 .../0_stateless/02033_join_engine_deadlock.sh | 71 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 tests/queries/0_stateless/02033_join_engine_deadlock.reference create mode 100755 tests/queries/0_stateless/02033_join_engine_deadlock.sh diff --git a/tests/queries/0_stateless/02033_join_engine_deadlock.reference b/tests/queries/0_stateless/02033_join_engine_deadlock.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/02033_join_engine_deadlock.sh b/tests/queries/0_stateless/02033_join_engine_deadlock.sh new file mode 100755 index 00000000000..7a4ca1c8bb1 --- /dev/null +++ b/tests/queries/0_stateless/02033_join_engine_deadlock.sh @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# Tags: deadlock + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +# shellcheck source=../shell_config.sh +. "$CURDIR"/../shell_config.sh + +create_table () { + $CLICKHOUSE_CLIENT --query " + CREATE TABLE join_block_test + ( + id String, + num Int64 + ) + ENGINE = Join(ANY, LEFT, id) + " +} + +drop_table () { + # Force a sync drop to free the memory before ending the test + # Otherwise things get interesting if you run the test many times before the database is finally dropped + $CLICKHOUSE_CLIENT --query " + DROP TABLE join_block_test SYNC + " +} + +populate_table_bg () { + ( + $CLICKHOUSE_CLIENT --query " + INSERT INTO join_block_test + SELECT toString(number) as id, number * number as num + FROM system.numbers LIMIT 3000000 + " --lock_acquire_timeout=20 >/dev/null + ) & +} + +read_table_bg () { + ( + $CLICKHOUSE_CLIENT --query " + SELECT * + FROM + ( + SELECT toString(number) AS user_id + FROM system.numbers LIMIT 10000 OFFSET 20000 + ) AS t1 + LEFT JOIN + ( + SELECT + * + FROM join_block_test AS i1 + ANY LEFT JOIN + ( + SELECT * + FROM join_block_test + ) AS i2 ON i1.id = toString(i2.num) + ) AS t2 ON t1.user_id = t2.id + " --lock_acquire_timeout=20 >/dev/null + ) & +} + +create_table +for _ in {1..5}; +do + populate_table_bg + sleep 0.05 + read_table_bg + sleep 0.05 +done + +wait +drop_table From 0ee5c0bff570ec676a394e2e60dc934b1e640b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Wed, 29 Sep 2021 19:30:07 +0200 Subject: [PATCH 020/264] Use RWLock in StorageJoin to avoid deadlocks --- src/Functions/FunctionJoinGet.cpp | 6 +-- src/Functions/FunctionJoinGet.h | 16 +++++--- src/Interpreters/ExpressionAnalyzer.cpp | 2 +- src/Interpreters/HashJoin.cpp | 2 +- src/Interpreters/HashJoin.h | 7 ++-- src/Storages/IStorage.h | 1 + src/Storages/StorageJoin.cpp | 53 +++++++++++++++---------- src/Storages/StorageJoin.h | 13 +++--- src/Storages/StorageSet.cpp | 21 +++++----- src/Storages/StorageSet.h | 8 ++-- 10 files changed, 76 insertions(+), 53 deletions(-) diff --git a/src/Functions/FunctionJoinGet.cpp b/src/Functions/FunctionJoinGet.cpp index f0dff0ac7e4..df131538275 100644 --- a/src/Functions/FunctionJoinGet.cpp +++ b/src/Functions/FunctionJoinGet.cpp @@ -25,14 +25,14 @@ ColumnPtr ExecutableFunctionJoinGet::executeImpl(const ColumnsWithTypeA auto key = arguments[i]; keys.emplace_back(std::move(key)); } - return storage_join->joinGet(keys, result_columns).column; + return storage_join->joinGet(keys, result_columns, getContext()).column; } template ExecutableFunctionPtr FunctionJoinGet::prepare(const ColumnsWithTypeAndName &) const { Block result_columns {{return_type->createColumn(), return_type, attr_name}}; - return std::make_unique>(table_lock, storage_join, result_columns); + return std::make_unique>(getContext(), table_lock, storage_join, result_columns); } static std::pair, String> @@ -89,7 +89,7 @@ FunctionBasePtr JoinGetOverloadResolver::buildImpl(const ColumnsWithTyp auto return_type = storage_join->joinGetCheckAndGetReturnType(data_types, attr_name, or_null); auto table_lock = storage_join->lockForShare(getContext()->getInitialQueryId(), getContext()->getSettingsRef().lock_acquire_timeout); - return std::make_unique>(table_lock, storage_join, attr_name, argument_types, return_type); + return std::make_unique>(getContext(), table_lock, storage_join, attr_name, argument_types, return_type); } void registerFunctionJoinGet(FunctionFactory & factory) diff --git a/src/Functions/FunctionJoinGet.h b/src/Functions/FunctionJoinGet.h index 3ddab51e2d9..2dd0cb9fdea 100644 --- a/src/Functions/FunctionJoinGet.h +++ b/src/Functions/FunctionJoinGet.h @@ -14,13 +14,15 @@ class StorageJoin; using StorageJoinPtr = std::shared_ptr; template -class ExecutableFunctionJoinGet final : public IExecutableFunction +class ExecutableFunctionJoinGet final : public IExecutableFunction, WithContext { public: - ExecutableFunctionJoinGet(TableLockHolder table_lock_, + ExecutableFunctionJoinGet(ContextPtr context_, + TableLockHolder table_lock_, StorageJoinPtr storage_join_, const DB::Block & result_columns_) - : table_lock(std::move(table_lock_)) + : WithContext(context_) + , table_lock(std::move(table_lock_)) , storage_join(std::move(storage_join_)) , result_columns(result_columns_) {} @@ -42,15 +44,17 @@ private: }; template -class FunctionJoinGet final : public IFunctionBase +class FunctionJoinGet final : public IFunctionBase, WithContext { public: static constexpr auto name = or_null ? "joinGetOrNull" : "joinGet"; - FunctionJoinGet(TableLockHolder table_lock_, + FunctionJoinGet(ContextPtr context_, + TableLockHolder table_lock_, StorageJoinPtr storage_join_, String attr_name_, DataTypes argument_types_, DataTypePtr return_type_) - : table_lock(std::move(table_lock_)) + : WithContext(context_) + , table_lock(std::move(table_lock_)) , storage_join(storage_join_) , attr_name(std::move(attr_name_)) , argument_types(std::move(argument_types_)) diff --git a/src/Interpreters/ExpressionAnalyzer.cpp b/src/Interpreters/ExpressionAnalyzer.cpp index 566ee60a3e6..89d7624f203 100644 --- a/src/Interpreters/ExpressionAnalyzer.cpp +++ b/src/Interpreters/ExpressionAnalyzer.cpp @@ -938,7 +938,7 @@ JoinPtr SelectQueryExpressionAnalyzer::makeTableJoin( if (auto storage = analyzed_join->getStorageJoin()) { std::tie(left_convert_actions, right_convert_actions) = analyzed_join->createConvertingActions(left_columns, {}); - return storage->getJoinLocked(analyzed_join); + return storage->getJoinLocked(analyzed_join, getContext()); } joined_plan = buildJoinedPlan(getContext(), join_element, *analyzed_join, query_options); diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index 07872df8ce5..d88df9d3e30 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -744,7 +744,7 @@ bool HashJoin::addJoinedBlock(const Block & source_block, bool check_limits) size_t total_rows = 0; size_t total_bytes = 0; { - if (storage_join_lock.mutex()) + if (storage_join_lock) throw DB::Exception("addJoinedBlock called when HashJoin locked to prevent updates", ErrorCodes::LOGICAL_ERROR); diff --git a/src/Interpreters/HashJoin.h b/src/Interpreters/HashJoin.h index 07fd6d5b89f..f1f1198e7d9 100644 --- a/src/Interpreters/HashJoin.h +++ b/src/Interpreters/HashJoin.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -334,9 +335,9 @@ public: /// We keep correspondence between used_flags and hash table internal buffer. /// Hash table cannot be modified during HashJoin lifetime and must be protected with lock. - void setLock(std::shared_mutex & rwlock) + void setLock(RWLockImpl::LockHolder rwlock_holder) { - storage_join_lock = std::shared_lock(rwlock); + storage_join_lock = rwlock_holder; } void reuseJoinedData(const HashJoin & join); @@ -391,7 +392,7 @@ private: /// Should be set via setLock to protect hash table from modification from StorageJoin /// If set HashJoin instance is not available for modification (addJoinedBlock) - std::shared_lock storage_join_lock; + RWLockImpl::LockHolder storage_join_lock = nullptr; void dataMapInit(MapsVariant &); diff --git a/src/Storages/IStorage.h b/src/Storages/IStorage.h index 6ce17552ba1..2013cc5ecb6 100644 --- a/src/Storages/IStorage.h +++ b/src/Storages/IStorage.h @@ -219,6 +219,7 @@ private: /// without locks. MultiVersionStorageMetadataPtr metadata; +protected: RWLockImpl::LockHolder tryLockTimed( const RWLock & rwlock, RWLockImpl::Type type, const String & query_id, const std::chrono::milliseconds & acquire_timeout) const; diff --git a/src/Storages/StorageJoin.cpp b/src/Storages/StorageJoin.cpp index e45183591f2..e5574708de0 100644 --- a/src/Storages/StorageJoin.cpp +++ b/src/Storages/StorageJoin.cpp @@ -1,13 +1,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include @@ -67,6 +67,14 @@ StorageJoin::StorageJoin( restore(); } +RWLockImpl::LockHolder StorageJoin::tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr ctx) const +{ + const String query_id = ctx ? ctx->getInitialQueryId() : RWLockImpl::NO_QUERY; + const std::chrono::milliseconds acquire_timeout + = ctx ? ctx->getSettingsRef().lock_acquire_timeout : std::chrono::seconds(DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC); + return tryLockTimed(lock, type, query_id, acquire_timeout); +} + SinkToStoragePtr StorageJoin::write(const ASTPtr & query, const StorageMetadataPtr & metadata_snapshot, ContextPtr context) { std::lock_guard mutate_lock(mutate_mutex); @@ -74,10 +82,10 @@ SinkToStoragePtr StorageJoin::write(const ASTPtr & query, const StorageMetadataP } void StorageJoin::truncate( - const ASTPtr &, const StorageMetadataPtr & metadata_snapshot, ContextPtr, TableExclusiveLockHolder&) + const ASTPtr &, const StorageMetadataPtr & metadata_snapshot, ContextPtr ctx, TableExclusiveLockHolder&) { std::lock_guard mutate_lock(mutate_mutex); - std::unique_lock lock(rwlock); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, ctx); disk->removeRecursive(path); disk->createDirectories(path); @@ -128,7 +136,7 @@ void StorageJoin::mutate(const MutationCommands & commands, ContextPtr context) } /// Now acquire exclusive lock and modify storage. - std::unique_lock lock(rwlock); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, context); join = std::move(new_data); increment = 1; @@ -152,7 +160,7 @@ void StorageJoin::mutate(const MutationCommands & commands, ContextPtr context) } } -HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join) const +HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join, ContextPtr ctx) const { auto metadata_snapshot = getInMemoryMetadataPtr(); if (!analyzed_join->sameStrictnessAndKind(strictness, kind)) @@ -171,34 +179,36 @@ HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join) analyzed_join->setRightKeys(key_names); HashJoinPtr join_clone = std::make_shared(analyzed_join, metadata_snapshot->getSampleBlock().sortColumns()); - join_clone->setLock(rwlock); + + RWLockImpl::LockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, ctx); + join_clone->setLock(holder); join_clone->reuseJoinedData(*join); return join_clone; } -void StorageJoin::insertBlock(const Block & block) +void StorageJoin::insertBlock(const Block & block, ContextPtr ctx) { - std::unique_lock lock(rwlock); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, ctx); join->addJoinedBlock(block, true); } -size_t StorageJoin::getSize() const +size_t StorageJoin::getSize(ContextPtr ctx) const { - std::shared_lock lock(rwlock); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, ctx); return join->getTotalRowCount(); } -std::optional StorageJoin::totalRows(const Settings &) const +std::optional StorageJoin::totalRows(const Settings &settings) const { - std::shared_lock lock(rwlock); + TableLockHolder holder = tryLockTimed(rwlock, RWLockImpl::Read, RWLockImpl::NO_QUERY, settings.lock_acquire_timeout); return join->getTotalRowCount(); } -std::optional StorageJoin::totalBytes(const Settings &) const +std::optional StorageJoin::totalBytes(const Settings &settings) const { - std::shared_lock lock(rwlock); + TableLockHolder holder = tryLockTimed(rwlock, RWLockImpl::Read, RWLockImpl::NO_QUERY, settings.lock_acquire_timeout); return join->getTotalByteCount(); } @@ -207,9 +217,9 @@ DataTypePtr StorageJoin::joinGetCheckAndGetReturnType(const DataTypes & data_typ return join->joinGetCheckAndGetReturnType(data_types, column_name, or_null); } -ColumnWithTypeAndName StorageJoin::joinGet(const Block & block, const Block & block_with_columns_to_add) const +ColumnWithTypeAndName StorageJoin::joinGet(const Block & block, const Block & block_with_columns_to_add, ContextPtr ctx) const { - std::shared_lock lock(rwlock); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, ctx); return join->joinGet(block, block_with_columns_to_add); } @@ -370,10 +380,10 @@ size_t rawSize(const StringRef & t) class JoinSource : public SourceWithProgress { public: - JoinSource(HashJoinPtr join_, std::shared_mutex & rwlock, UInt64 max_block_size_, Block sample_block_) + JoinSource(HashJoinPtr join_, TableLockHolder lock_holder_, UInt64 max_block_size_, Block sample_block_) : SourceWithProgress(sample_block_) , join(join_) - , lock(rwlock) + , lock_holder(lock_holder_) , max_block_size(max_block_size_) , sample_block(std::move(sample_block_)) { @@ -421,7 +431,7 @@ protected: private: HashJoinPtr join; - std::shared_lock lock; + TableLockHolder lock_holder; UInt64 max_block_size; Block sample_block; @@ -571,7 +581,7 @@ Pipe StorageJoin::read( const Names & column_names, const StorageMetadataPtr & metadata_snapshot, SelectQueryInfo & /*query_info*/, - ContextPtr /*context*/, + ContextPtr context, QueryProcessingStage::Enum /*processed_stage*/, size_t max_block_size, unsigned /*num_streams*/) @@ -579,7 +589,8 @@ Pipe StorageJoin::read( metadata_snapshot->check(column_names, getVirtuals(), getStorageID()); Block source_sample_block = metadata_snapshot->getSampleBlockForColumns(column_names, getVirtuals(), getStorageID()); - return Pipe(std::make_shared(join, rwlock, max_block_size, source_sample_block)); + RWLockImpl::LockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, context); + return Pipe(std::make_shared(join, std::move(holder), max_block_size, source_sample_block)); } } diff --git a/src/Storages/StorageJoin.h b/src/Storages/StorageJoin.h index 6a08773ecc8..4926194433c 100644 --- a/src/Storages/StorageJoin.h +++ b/src/Storages/StorageJoin.h @@ -2,7 +2,9 @@ #include +#include #include +#include #include #include @@ -35,7 +37,7 @@ public: /// Return instance of HashJoin holding lock that protects from insertions to StorageJoin. /// HashJoin relies on structure of hash table that's why we need to return it with locked mutex. - HashJoinPtr getJoinLocked(std::shared_ptr analyzed_join) const; + HashJoinPtr getJoinLocked(std::shared_ptr analyzed_join, ContextPtr ctx) const; /// Get result type for function "joinGet(OrNull)" DataTypePtr joinGetCheckAndGetReturnType(const DataTypes & data_types, const String & column_name, bool or_null) const; @@ -43,7 +45,7 @@ public: /// Execute function "joinGet(OrNull)" on data block. /// Takes rwlock for read to prevent parallel StorageJoin updates during processing data block /// (but not during processing whole query, it's safe for joinGet that doesn't involve `used_flags` from HashJoin) - ColumnWithTypeAndName joinGet(const Block & block, const Block & block_with_columns_to_add) const; + ColumnWithTypeAndName joinGet(const Block & block, const Block & block_with_columns_to_add, ContextPtr context) const; SinkToStoragePtr write(const ASTPtr & query, const StorageMetadataPtr & metadata_snapshot, ContextPtr context) override; @@ -73,12 +75,13 @@ private: /// Protect state for concurrent use in insertFromBlock and joinBlock. /// Lock is stored in HashJoin instance during query and blocks concurrent insertions. - mutable std::shared_mutex rwlock; + mutable RWLock rwlock = RWLockImpl::create(); mutable std::mutex mutate_mutex; - void insertBlock(const Block & block) override; + void insertBlock(const Block & block, ContextPtr ctx) override; void finishInsert() override {} - size_t getSize() const override; + size_t getSize(ContextPtr context) const override; + RWLockImpl::LockHolder tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr ctx) const; protected: StorageJoin( diff --git a/src/Storages/StorageSet.cpp b/src/Storages/StorageSet.cpp index fe55123335a..c57dadf6d52 100644 --- a/src/Storages/StorageSet.cpp +++ b/src/Storages/StorageSet.cpp @@ -34,11 +34,11 @@ namespace ErrorCodes } -class SetOrJoinSink : public SinkToStorage +class SetOrJoinSink : public SinkToStorage, WithContext { public: SetOrJoinSink( - StorageSetOrJoinBase & table_, const StorageMetadataPtr & metadata_snapshot_, + ContextPtr ctx, StorageSetOrJoinBase & table_, const StorageMetadataPtr & metadata_snapshot_, const String & backup_path_, const String & backup_tmp_path_, const String & backup_file_name_, bool persistent_); @@ -60,6 +60,7 @@ private: SetOrJoinSink::SetOrJoinSink( + ContextPtr ctx, StorageSetOrJoinBase & table_, const StorageMetadataPtr & metadata_snapshot_, const String & backup_path_, @@ -67,6 +68,7 @@ SetOrJoinSink::SetOrJoinSink( const String & backup_file_name_, bool persistent_) : SinkToStorage(metadata_snapshot_->getSampleBlock()) + , WithContext(ctx) , table(table_) , metadata_snapshot(metadata_snapshot_) , backup_path(backup_path_) @@ -84,7 +86,7 @@ void SetOrJoinSink::consume(Chunk chunk) /// Sort columns in the block. This is necessary, since Set and Join count on the same column order in different blocks. Block sorted_block = getHeader().cloneWithColumns(chunk.detachColumns()).sortColumns(); - table.insertBlock(sorted_block); + table.insertBlock(sorted_block, getContext()); if (persistent) backup_stream.write(sorted_block); } @@ -104,10 +106,10 @@ void SetOrJoinSink::onFinish() } -SinkToStoragePtr StorageSetOrJoinBase::write(const ASTPtr & /*query*/, const StorageMetadataPtr & metadata_snapshot, ContextPtr /*context*/) +SinkToStoragePtr StorageSetOrJoinBase::write(const ASTPtr & /*query*/, const StorageMetadataPtr & metadata_snapshot, ContextPtr ctx) { UInt64 id = ++increment; - return std::make_shared(*this, metadata_snapshot, path, fs::path(path) / "tmp/", toString(id) + ".bin", persistent); + return std::make_shared(ctx, *this, metadata_snapshot, path, fs::path(path) / "tmp/", toString(id) + ".bin", persistent); } @@ -155,10 +157,10 @@ StorageSet::StorageSet( } -void StorageSet::insertBlock(const Block & block) { set->insertFromBlock(block.getColumnsWithTypeAndName()); } +void StorageSet::insertBlock(const Block & block, ContextPtr) { set->insertFromBlock(block.getColumnsWithTypeAndName()); } void StorageSet::finishInsert() { set->finishInsert(); } -size_t StorageSet::getSize() const { return set->getTotalRowCount(); } +size_t StorageSet::getSize(ContextPtr) const { return set->getTotalRowCount(); } std::optional StorageSet::totalRows(const Settings &) const { return set->getTotalRowCount(); } std::optional StorageSet::totalBytes(const Settings &) const { return set->getTotalByteCount(); } @@ -210,6 +212,7 @@ void StorageSetOrJoinBase::restore() void StorageSetOrJoinBase::restoreFromFile(const String & file_path) { + ContextPtr ctx = nullptr; auto backup_buf = disk->readFile(file_path); CompressedReadBuffer compressed_backup_buf(*backup_buf); NativeBlockInputStream backup_stream(compressed_backup_buf, 0); @@ -217,14 +220,14 @@ void StorageSetOrJoinBase::restoreFromFile(const String & file_path) backup_stream.readPrefix(); while (Block block = backup_stream.read()) - insertBlock(block); + insertBlock(block, ctx); finishInsert(); backup_stream.readSuffix(); /// TODO Add speed, compressed bytes, data volume in memory, compression ratio ... Generalize all statistics logging in project. LOG_INFO(&Poco::Logger::get("StorageSetOrJoinBase"), "Loaded from backup file {}. {} rows, {}. State has {} unique rows.", - file_path, backup_stream.getProfileInfo().rows, ReadableSize(backup_stream.getProfileInfo().bytes), getSize()); + file_path, backup_stream.getProfileInfo().rows, ReadableSize(backup_stream.getProfileInfo().bytes), getSize(ctx)); } diff --git a/src/Storages/StorageSet.h b/src/Storages/StorageSet.h index 1166557ec8e..1b78676b6c5 100644 --- a/src/Storages/StorageSet.h +++ b/src/Storages/StorageSet.h @@ -51,10 +51,10 @@ private: void restoreFromFile(const String & file_path); /// Insert the block into the state. - virtual void insertBlock(const Block & block) = 0; + virtual void insertBlock(const Block & block, ContextPtr context) = 0; /// Call after all blocks were inserted. virtual void finishInsert() = 0; - virtual size_t getSize() const = 0; + virtual size_t getSize(ContextPtr context) const = 0; }; @@ -81,9 +81,9 @@ public: private: SetPtr set; - void insertBlock(const Block & block) override; + void insertBlock(const Block & block, ContextPtr) override; void finishInsert() override; - size_t getSize() const override; + size_t getSize(ContextPtr) const override; protected: StorageSet( From c0ba8d1a043c962c365c142e64a75a8e5db993b0 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 29 Sep 2021 21:31:18 +0300 Subject: [PATCH 021/264] Fix crosslink. --- docs/en/sql-reference/statements/create/view.md | 2 +- docs/ru/sql-reference/statements/create/view.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/sql-reference/statements/create/view.md b/docs/en/sql-reference/statements/create/view.md index 84213020925..39c5760ecf3 100644 --- a/docs/en/sql-reference/statements/create/view.md +++ b/docs/en/sql-reference/statements/create/view.md @@ -50,7 +50,7 @@ When creating a materialized view with `TO [db].[table]`, you must not use `POPU A materialized view is implemented as follows: when inserting data to the table specified in `SELECT`, part of the inserted data is converted by this `SELECT` query, and the result is inserted in the view. !!! important "Important" - Materialized views in ClickHouse use **column names** instead of column order during insertion into destination table. If some column names are not present in `SELECT`'s result ClickHouse will use a default value, even if column is not [Nullable](../data-types/nullable.md). A safe practice would be to add aliases for every column when using Materialized views. + Materialized views in ClickHouse use **column names** instead of column order during insertion into destination table. If some column names are not present in `SELECT`'s result ClickHouse will use a default value, even if column is not [Nullable](../../data-types/nullable.md). A safe practice would be to add aliases for every column when using Materialized views. Materialized views in ClickHouse are implemented more like insert triggers. If there’s some aggregation in the view query, it’s applied only to the batch of freshly inserted data. Any changes to existing data of source table (like update, delete, drop partition, etc.) does not change the materialized view. diff --git a/docs/ru/sql-reference/statements/create/view.md b/docs/ru/sql-reference/statements/create/view.md index 53d75b78dd1..9eb0baf5a98 100644 --- a/docs/ru/sql-reference/statements/create/view.md +++ b/docs/ru/sql-reference/statements/create/view.md @@ -49,7 +49,7 @@ CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]na !!! important "Важно" - Материализованные представления в ClickHouse используют **имена столбцов** вместо порядка следования столбцов при вставке в целевую таблицу. Если в результатах запроса `SELECT` некоторые имена столбцов отсутствуют, то ClickHouse будет использовать значение по умолчанию, даже если столбец не является [Nullable](../data-types/nullable.md). Безопасной практикой, при использовании материализованных представлений, считается добавление псевдонимов для каждого столбца. + Материализованные представления в ClickHouse используют **имена столбцов** вместо порядка следования столбцов при вставке в целевую таблицу. Если в результатах запроса `SELECT` некоторые имена столбцов отсутствуют, то ClickHouse будет использовать значение по умолчанию, даже если столбец не является [Nullable](../../data-types/nullable.md). Безопасной практикой, при использовании материализованных представлений, считается добавление псевдонимов для каждого столбца. Материализованные представления в ClickHouse больше похожи на `after insert` триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление. From e53a48fb3089ab114b8fa907fc2efa3e27a1c960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Thu, 30 Sep 2021 10:15:44 +0200 Subject: [PATCH 022/264] Raise lock acquire timeout for the test Needed for check test under ASAN --- tests/queries/0_stateless/02033_join_engine_deadlock.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/queries/0_stateless/02033_join_engine_deadlock.sh b/tests/queries/0_stateless/02033_join_engine_deadlock.sh index 7a4ca1c8bb1..f4ae564e2a7 100755 --- a/tests/queries/0_stateless/02033_join_engine_deadlock.sh +++ b/tests/queries/0_stateless/02033_join_engine_deadlock.sh @@ -30,7 +30,7 @@ populate_table_bg () { INSERT INTO join_block_test SELECT toString(number) as id, number * number as num FROM system.numbers LIMIT 3000000 - " --lock_acquire_timeout=20 >/dev/null + " >/dev/null ) & } @@ -54,7 +54,7 @@ read_table_bg () { FROM join_block_test ) AS i2 ON i1.id = toString(i2.num) ) AS t2 ON t1.user_id = t2.id - " --lock_acquire_timeout=20 >/dev/null + " >/dev/null ) & } From f58742014c0a72e9d02d9c02d4172b3d36989461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Thu, 30 Sep 2021 10:47:15 +0200 Subject: [PATCH 023/264] Consistent naming --- src/Storages/StorageJoin.cpp | 27 +++++++++++++-------------- src/Storages/StorageJoin.h | 6 +++--- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Storages/StorageJoin.cpp b/src/Storages/StorageJoin.cpp index e5574708de0..b17315106ce 100644 --- a/src/Storages/StorageJoin.cpp +++ b/src/Storages/StorageJoin.cpp @@ -67,11 +67,11 @@ StorageJoin::StorageJoin( restore(); } -RWLockImpl::LockHolder StorageJoin::tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr ctx) const +RWLockImpl::LockHolder StorageJoin::tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr context) const { - const String query_id = ctx ? ctx->getInitialQueryId() : RWLockImpl::NO_QUERY; + const String query_id = context ? context->getInitialQueryId() : RWLockImpl::NO_QUERY; const std::chrono::milliseconds acquire_timeout - = ctx ? ctx->getSettingsRef().lock_acquire_timeout : std::chrono::seconds(DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC); + = context ? context->getSettingsRef().lock_acquire_timeout : std::chrono::seconds(DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC); return tryLockTimed(lock, type, query_id, acquire_timeout); } @@ -81,11 +81,10 @@ SinkToStoragePtr StorageJoin::write(const ASTPtr & query, const StorageMetadataP return StorageSetOrJoinBase::write(query, metadata_snapshot, context); } -void StorageJoin::truncate( - const ASTPtr &, const StorageMetadataPtr & metadata_snapshot, ContextPtr ctx, TableExclusiveLockHolder&) +void StorageJoin::truncate(const ASTPtr &, const StorageMetadataPtr & metadata_snapshot, ContextPtr context, TableExclusiveLockHolder &) { std::lock_guard mutate_lock(mutate_mutex); - TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, ctx); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, context); disk->removeRecursive(path); disk->createDirectories(path); @@ -160,7 +159,7 @@ void StorageJoin::mutate(const MutationCommands & commands, ContextPtr context) } } -HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join, ContextPtr ctx) const +HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join, ContextPtr context) const { auto metadata_snapshot = getInMemoryMetadataPtr(); if (!analyzed_join->sameStrictnessAndKind(strictness, kind)) @@ -180,7 +179,7 @@ HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join, HashJoinPtr join_clone = std::make_shared(analyzed_join, metadata_snapshot->getSampleBlock().sortColumns()); - RWLockImpl::LockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, ctx); + RWLockImpl::LockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, context); join_clone->setLock(holder); join_clone->reuseJoinedData(*join); @@ -188,15 +187,15 @@ HashJoinPtr StorageJoin::getJoinLocked(std::shared_ptr analyzed_join, } -void StorageJoin::insertBlock(const Block & block, ContextPtr ctx) +void StorageJoin::insertBlock(const Block & block, ContextPtr context) { - TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, ctx); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Write, context); join->addJoinedBlock(block, true); } -size_t StorageJoin::getSize(ContextPtr ctx) const +size_t StorageJoin::getSize(ContextPtr context) const { - TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, ctx); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, context); return join->getTotalRowCount(); } @@ -217,9 +216,9 @@ DataTypePtr StorageJoin::joinGetCheckAndGetReturnType(const DataTypes & data_typ return join->joinGetCheckAndGetReturnType(data_types, column_name, or_null); } -ColumnWithTypeAndName StorageJoin::joinGet(const Block & block, const Block & block_with_columns_to_add, ContextPtr ctx) const +ColumnWithTypeAndName StorageJoin::joinGet(const Block & block, const Block & block_with_columns_to_add, ContextPtr context) const { - TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, ctx); + TableLockHolder holder = tryLockTimedWithContext(rwlock, RWLockImpl::Read, context); return join->joinGet(block, block_with_columns_to_add); } diff --git a/src/Storages/StorageJoin.h b/src/Storages/StorageJoin.h index 4926194433c..cdc47531999 100644 --- a/src/Storages/StorageJoin.h +++ b/src/Storages/StorageJoin.h @@ -37,7 +37,7 @@ public: /// Return instance of HashJoin holding lock that protects from insertions to StorageJoin. /// HashJoin relies on structure of hash table that's why we need to return it with locked mutex. - HashJoinPtr getJoinLocked(std::shared_ptr analyzed_join, ContextPtr ctx) const; + HashJoinPtr getJoinLocked(std::shared_ptr analyzed_join, ContextPtr context) const; /// Get result type for function "joinGet(OrNull)" DataTypePtr joinGetCheckAndGetReturnType(const DataTypes & data_types, const String & column_name, bool or_null) const; @@ -78,10 +78,10 @@ private: mutable RWLock rwlock = RWLockImpl::create(); mutable std::mutex mutate_mutex; - void insertBlock(const Block & block, ContextPtr ctx) override; + void insertBlock(const Block & block, ContextPtr context) override; void finishInsert() override {} size_t getSize(ContextPtr context) const override; - RWLockImpl::LockHolder tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr ctx) const; + RWLockImpl::LockHolder tryLockTimedWithContext(const RWLock & lock, RWLockImpl::Type type, ContextPtr context) const; protected: StorageJoin( From cfb9875acf3df38fe3f28188a0c79aff7a3e7a97 Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Thu, 30 Sep 2021 13:47:12 +0000 Subject: [PATCH 024/264] Trigger Build From 6f2447c027526d06e6f0125ea496815f01d40052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Thu, 30 Sep 2021 15:48:54 +0200 Subject: [PATCH 025/264] clang-tidy fix --- src/Storages/StorageSet.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Storages/StorageSet.cpp b/src/Storages/StorageSet.cpp index c57dadf6d52..fd06c2975b6 100644 --- a/src/Storages/StorageSet.cpp +++ b/src/Storages/StorageSet.cpp @@ -106,10 +106,11 @@ void SetOrJoinSink::onFinish() } -SinkToStoragePtr StorageSetOrJoinBase::write(const ASTPtr & /*query*/, const StorageMetadataPtr & metadata_snapshot, ContextPtr ctx) +SinkToStoragePtr StorageSetOrJoinBase::write(const ASTPtr & /*query*/, const StorageMetadataPtr & metadata_snapshot, ContextPtr context) { UInt64 id = ++increment; - return std::make_shared(ctx, *this, metadata_snapshot, path, fs::path(path) / "tmp/", toString(id) + ".bin", persistent); + return std::make_shared( + context, *this, metadata_snapshot, path, fs::path(path) / "tmp/", toString(id) + ".bin", persistent); } From b2d13d0b199c7b648718247da310d33774e4f164 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Sun, 12 Sep 2021 16:43:22 +0300 Subject: [PATCH 026/264] Add test for expanding macros in RabbitMQ settings. --- .../test_storage_rabbitmq/configs/macros.xml | 8 +++++ .../integration/test_storage_rabbitmq/test.py | 33 ++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/integration/test_storage_rabbitmq/configs/macros.xml diff --git a/tests/integration/test_storage_rabbitmq/configs/macros.xml b/tests/integration/test_storage_rabbitmq/configs/macros.xml new file mode 100644 index 00000000000..6e9f3390b39 --- /dev/null +++ b/tests/integration/test_storage_rabbitmq/configs/macros.xml @@ -0,0 +1,8 @@ + + + rabbitmq1 + 5672 + macro + JSONEachRow + + diff --git a/tests/integration/test_storage_rabbitmq/test.py b/tests/integration/test_storage_rabbitmq/test.py index 9e2752438f8..696294f4bde 100644 --- a/tests/integration/test_storage_rabbitmq/test.py +++ b/tests/integration/test_storage_rabbitmq/test.py @@ -18,7 +18,7 @@ from . import rabbitmq_pb2 cluster = ClickHouseCluster(__file__) instance = cluster.add_instance('instance', - main_configs=['configs/rabbitmq.xml'], + main_configs=['configs/rabbitmq.xml', 'configs/macros.xml'], with_rabbitmq=True) @@ -233,6 +233,37 @@ def test_rabbitmq_tsv_with_delimiter(rabbitmq_cluster): rabbitmq_check_result(result, True) +def test_rabbitmq_macros(rabbitmq_cluster): + instance.query(''' + CREATE TABLE test.rabbitmq (key UInt64, value UInt64) + ENGINE = RabbitMQ + SETTINGS rabbitmq_host_port = '{rabbitmq_host}:{rabbitmq_port}', + rabbitmq_exchange_name = '{rabbitmq_exchange_name}', + rabbitmq_format = '{rabbitmq_format}' + ''') + + credentials = pika.PlainCredentials('root', 'clickhouse') + parameters = pika.ConnectionParameters(rabbitmq_cluster.rabbitmq_ip, rabbitmq_cluster.rabbitmq_port, '/', credentials) + connection = pika.BlockingConnection(parameters) + channel = connection.channel() + + message = '' + for i in range(50): + message += json.dumps({'key': i, 'value': i}) + '\n' + channel.basic_publish(exchange='macro', routing_key='', body=message) + + connection.close() + time.sleep(1) + + result = '' + while True: + result += instance.query('SELECT * FROM test.rabbitmq ORDER BY key', ignore_error=True) + if rabbitmq_check_result(result): + break + + rabbitmq_check_result(result, True) + + def test_rabbitmq_materialized_view(rabbitmq_cluster): instance.query(''' DROP TABLE IF EXISTS test.view; From ccdcaa21ff1696a1566374117caf49acece8358d Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Fri, 1 Oct 2021 16:13:10 +0300 Subject: [PATCH 027/264] Update install.sh --- tests/config/install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/config/install.sh b/tests/config/install.sh index f39bd951f46..764bc891c28 100755 --- a/tests/config/install.sh +++ b/tests/config/install.sh @@ -48,6 +48,7 @@ ln -sf $SRC_PATH/users.d/opentelemetry.xml $DEST_SERVER_PATH/users.d/ ln -sf $SRC_PATH/users.d/remote_queries.xml $DEST_SERVER_PATH/users.d/ ln -sf $SRC_PATH/users.d/session_log_test.xml $DEST_SERVER_PATH/users.d/ ln -sf $SRC_PATH/users.d/memory_profiler.xml $DEST_SERVER_PATH/users.d/ +ln -sf $SRC_PATH/test_function.xml $DEST_SERVER_PATH/ # FIXME DataPartsExchange may hang for http_send_timeout seconds # when nobody is going to read from the other side of socket (due to "Fetching of part was cancelled"), From 77081f33c29ebc436aec415d220c6a8ffb88e38f Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Fri, 1 Oct 2021 16:13:51 +0300 Subject: [PATCH 028/264] Update install.sh --- tests/config/install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/config/install.sh b/tests/config/install.sh index 764bc891c28..94ad55504a8 100755 --- a/tests/config/install.sh +++ b/tests/config/install.sh @@ -48,7 +48,6 @@ ln -sf $SRC_PATH/users.d/opentelemetry.xml $DEST_SERVER_PATH/users.d/ ln -sf $SRC_PATH/users.d/remote_queries.xml $DEST_SERVER_PATH/users.d/ ln -sf $SRC_PATH/users.d/session_log_test.xml $DEST_SERVER_PATH/users.d/ ln -sf $SRC_PATH/users.d/memory_profiler.xml $DEST_SERVER_PATH/users.d/ -ln -sf $SRC_PATH/test_function.xml $DEST_SERVER_PATH/ # FIXME DataPartsExchange may hang for http_send_timeout seconds # when nobody is going to read from the other side of socket (due to "Fetching of part was cancelled"), @@ -60,6 +59,7 @@ ln -sf $SRC_PATH/strings_dictionary.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/decimals_dictionary.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/executable_dictionary.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/executable_pool_dictionary.xml $DEST_SERVER_PATH/ +ln -sf $SRC_PATH/test_function.xml $DEST_SERVER_PATH/ ln -sf $SRC_PATH/top_level_domains $DEST_SERVER_PATH/ From d41ef6a9f8b4ae47aadf8c572cd90c04208ad087 Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Fri, 1 Oct 2021 17:08:22 +0300 Subject: [PATCH 029/264] Update CORS.xml --- tests/config/config.d/CORS.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/config/config.d/CORS.xml b/tests/config/config.d/CORS.xml index 873821478dc..b96209866a7 100644 --- a/tests/config/config.d/CORS.xml +++ b/tests/config/config.d/CORS.xml @@ -17,5 +17,4 @@ 86400
- - + From 50ef202b12aba727011ea2fe14f588f56e66a2d5 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 1 Oct 2021 18:25:57 +0300 Subject: [PATCH 030/264] Update docs/en/sql-reference/statements/create/view.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/en/sql-reference/statements/create/view.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/statements/create/view.md b/docs/en/sql-reference/statements/create/view.md index 39c5760ecf3..f174d561cc6 100644 --- a/docs/en/sql-reference/statements/create/view.md +++ b/docs/en/sql-reference/statements/create/view.md @@ -50,7 +50,7 @@ When creating a materialized view with `TO [db].[table]`, you must not use `POPU A materialized view is implemented as follows: when inserting data to the table specified in `SELECT`, part of the inserted data is converted by this `SELECT` query, and the result is inserted in the view. !!! important "Important" - Materialized views in ClickHouse use **column names** instead of column order during insertion into destination table. If some column names are not present in `SELECT`'s result ClickHouse will use a default value, even if column is not [Nullable](../../data-types/nullable.md). A safe practice would be to add aliases for every column when using Materialized views. + Materialized views in ClickHouse use **column names** instead of column order during insertion into destination table. If some column names are not present in the `SELECT` query result, ClickHouse uses a default value, even if the column is not [Nullable](../../data-types/nullable.md). A safe practice would be to add aliases for every column when using Materialized views. Materialized views in ClickHouse are implemented more like insert triggers. If there’s some aggregation in the view query, it’s applied only to the batch of freshly inserted data. Any changes to existing data of source table (like update, delete, drop partition, etc.) does not change the materialized view. From bb5c92276d0d9b5d838624b5cc345f33bbb41fdf Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 1 Oct 2021 18:26:09 +0300 Subject: [PATCH 031/264] Update docs/en/sql-reference/statements/create/view.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/en/sql-reference/statements/create/view.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/statements/create/view.md b/docs/en/sql-reference/statements/create/view.md index f174d561cc6..ec34c57a4cd 100644 --- a/docs/en/sql-reference/statements/create/view.md +++ b/docs/en/sql-reference/statements/create/view.md @@ -54,7 +54,7 @@ A materialized view is implemented as follows: when inserting data to the table Materialized views in ClickHouse are implemented more like insert triggers. If there’s some aggregation in the view query, it’s applied only to the batch of freshly inserted data. Any changes to existing data of source table (like update, delete, drop partition, etc.) does not change the materialized view. -If you specify `POPULATE`, the existing table data is inserted in the view when creating it, as if making a `CREATE TABLE ... AS SELECT ...` . Otherwise, the query contains only the data inserted in the table after creating the view. We **do not recommend** using `POPULATE`, since data inserted in the table during the view creation will not be inserted in it. +If you specify `POPULATE`, the existing table data is inserted into the view when creating it, as if making a `CREATE TABLE ... AS SELECT ...` . Otherwise, the query contains only the data inserted in the table after creating the view. We **do not recommend** using `POPULATE`, since data inserted in the table during the view creation will not be inserted in it. A `SELECT` query can contain `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`. Note that the corresponding conversions are performed independently on each block of inserted data. For example, if `GROUP BY` is set, data is aggregated during insertion, but only within a single packet of inserted data. The data won’t be further aggregated. The exception is when using an `ENGINE` that independently performs data aggregation, such as `SummingMergeTree`. From fbe95f9c9d1834e09edd6c04b58ce58d09732f4e Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 1 Oct 2021 18:26:17 +0300 Subject: [PATCH 032/264] Update docs/ru/sql-reference/functions/hash-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/hash-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/hash-functions.md b/docs/ru/sql-reference/functions/hash-functions.md index 98b5ed6df27..975efdae71c 100644 --- a/docs/ru/sql-reference/functions/hash-functions.md +++ b/docs/ru/sql-reference/functions/hash-functions.md @@ -263,7 +263,7 @@ SHA512('s') Функция работает достаточно медленно (SHA-1 — примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 — примерно 2.2 миллионов). Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хэш-функция и вы не можете её выбрать. -Даже в этих случаях, рекомендуется применять функцию оффлайн - заранее вычисляя значения при вставке в таблицу, вместо того, чтобы применять её при выполнении `SELECT`. +Даже в этих случаях рекомендуется применять функцию офлайн — заранее вычисляя значения при вставке в таблицу, вместо того чтобы применять её при выполнении `SELECT`. **Параметры** From 7d5ea307f1d51b434ca44072eaf51aba6e57e992 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 1 Oct 2021 18:26:25 +0300 Subject: [PATCH 033/264] Update docs/ru/sql-reference/functions/hash-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/hash-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/hash-functions.md b/docs/ru/sql-reference/functions/hash-functions.md index 975efdae71c..18197f88ce3 100644 --- a/docs/ru/sql-reference/functions/hash-functions.md +++ b/docs/ru/sql-reference/functions/hash-functions.md @@ -262,7 +262,7 @@ SHA512('s') ``` Функция работает достаточно медленно (SHA-1 — примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 — примерно 2.2 миллионов). -Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хэш-функция и вы не можете её выбрать. +Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хеш-функция и вы не можете её выбрать. Даже в этих случаях рекомендуется применять функцию офлайн — заранее вычисляя значения при вставке в таблицу, вместо того чтобы применять её при выполнении `SELECT`. **Параметры** From 89f4830180ae0120797d75cc81e46ab5abd2ff2e Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 1 Oct 2021 18:26:33 +0300 Subject: [PATCH 034/264] Update docs/ru/sql-reference/statements/create/view.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/statements/create/view.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/statements/create/view.md b/docs/ru/sql-reference/statements/create/view.md index 9eb0baf5a98..77bdc7249c7 100644 --- a/docs/ru/sql-reference/statements/create/view.md +++ b/docs/ru/sql-reference/statements/create/view.md @@ -49,7 +49,7 @@ CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]na !!! important "Важно" - Материализованные представления в ClickHouse используют **имена столбцов** вместо порядка следования столбцов при вставке в целевую таблицу. Если в результатах запроса `SELECT` некоторые имена столбцов отсутствуют, то ClickHouse будет использовать значение по умолчанию, даже если столбец не является [Nullable](../../data-types/nullable.md). Безопасной практикой, при использовании материализованных представлений, считается добавление псевдонимов для каждого столбца. + Материализованные представления в ClickHouse используют **имена столбцов** вместо порядка следования столбцов при вставке в целевую таблицу. Если в результатах запроса `SELECT` некоторые имена столбцов отсутствуют, то ClickHouse использует значение по умолчанию, даже если столбец не является [Nullable](../../data-types/nullable.md). Безопасной практикой при использовании материализованных представлений считается добавление псевдонимов для каждого столбца. Материализованные представления в ClickHouse больше похожи на `after insert` триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление. From 61a7db9612ed67ce4320bda3c193ec07669f4242 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 1 Oct 2021 18:26:55 +0300 Subject: [PATCH 035/264] Update docs/ru/sql-reference/statements/create/view.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/statements/create/view.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/statements/create/view.md b/docs/ru/sql-reference/statements/create/view.md index 77bdc7249c7..7ebb154d6b6 100644 --- a/docs/ru/sql-reference/statements/create/view.md +++ b/docs/ru/sql-reference/statements/create/view.md @@ -53,7 +53,7 @@ CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [ON CLUSTER] [TO[db.]na Материализованные представления в ClickHouse больше похожи на `after insert` триггеры. Если в запросе материализованного представления есть агрегирование, оно применяется только к вставляемому блоку записей. Любые изменения существующих данных исходной таблицы (например обновление, удаление, удаление раздела и т.д.) не изменяют материализованное представление. -Если указано `POPULATE`, то при создании представления, в него будут вставлены имеющиеся данные таблицы, как если бы был сделан запрос `CREATE TABLE ... AS SELECT ...` . Иначе, представление будет содержать только данные, вставляемые в таблицу после создания представления. Не рекомендуется использовать `POPULATE`, так как вставляемые в таблицу данные во время создания представления, не попадут в него. +Если указано `POPULATE`, то при создании представления в него будут добавлены данные, уже содержащиеся в исходной таблице, как если бы был сделан запрос `CREATE TABLE ... AS SELECT ...` . Если `POPULATE` не указано, представление будет содержать только данные, добавленные в таблицу после создания представления. Использовать `POPULATE` не рекомендуется, так как в представление не попадут данные, добавляемые в таблицу во время создания представления. Запрос `SELECT` может содержать `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`… Следует иметь ввиду, что соответствующие преобразования будут выполняться независимо, на каждый блок вставляемых данных. Например, при наличии `GROUP BY`, данные будут агрегироваться при вставке, но только в рамках одной пачки вставляемых данных. Далее, данные не будут доагрегированы. Исключение - использование ENGINE, производящего агрегацию данных самостоятельно, например, `SummingMergeTree`. From a99a6fccc7289fb75bb55a3b47cfda8d144478b0 Mon Sep 17 00:00:00 2001 From: WangZengrui Date: Sat, 2 Oct 2021 02:34:53 +0800 Subject: [PATCH 036/264] init --- src/Interpreters/getOSKernelVersion.cpp | 37 +++++++++++++++++++++++++ src/Interpreters/getOSKernelVersion.h | 31 +++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/Interpreters/getOSKernelVersion.cpp create mode 100644 src/Interpreters/getOSKernelVersion.h diff --git a/src/Interpreters/getOSKernelVersion.cpp b/src/Interpreters/getOSKernelVersion.cpp new file mode 100644 index 00000000000..44df948be3c --- /dev/null +++ b/src/Interpreters/getOSKernelVersion.cpp @@ -0,0 +1,37 @@ +#if defined(OS_LINUX) +#include + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int BAD_ARGUMENTS; +} + +String getOSKernelVersion() +{ + struct utsname os_kernel_version; + int buf = uname(&os_kernel_version); + if (buf < 0) + { + throw Exception( + "EFAULT buf is not valid.", + ErrorCodes::BAD_ARGUMENTS); + } + else + { + // std::cout <<"sysname: " << os_kernel_version.sysname << " nodename: " << os_kernel_version.nodename + // << " release: " << os_kernel_version.release << " version: " << os_kernel_version.version + // << " machine: " << os_kernel_version.machine << std::endl; + + return "sysname: " + String(os_kernel_version.sysname) + " nodename: " + String(os_kernel_version.nodename) + + " release: " + String(os_kernel_version.release) + " version: " + String(os_kernel_version.version) + + " machine: " + String(os_kernel_version.machine); + } +} + +} + +#endif \ No newline at end of file diff --git a/src/Interpreters/getOSKernelVersion.h b/src/Interpreters/getOSKernelVersion.h new file mode 100644 index 00000000000..14b42d2a19a --- /dev/null +++ b/src/Interpreters/getOSKernelVersion.h @@ -0,0 +1,31 @@ +#if defined(OS_LINUX) +#pragma once + +#include + +#include +#include + +namespace DB +{ + +/// Returns String with OS Kernel version. +/* To get name and information about current kernel. + For simplicity, the function can be implemented only for Linux. +*/ + +String getOSKernelVersion(); + +// String getSysName(); + +// String getNodeName(); + +// String getReleaseName(); + +// String getVersion(); + +// String getMachineName(); + +} + +#endif \ No newline at end of file From 271f7995c03f5e24a047e692fad06f81181c0d93 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Mon, 4 Oct 2021 00:19:37 +0300 Subject: [PATCH 037/264] Fix PR comments. --- .../sql-reference/functions/hash-functions.md | 130 ++--------------- .../sql-reference/functions/hash-functions.md | 132 ++---------------- 2 files changed, 19 insertions(+), 243 deletions(-) diff --git a/docs/en/sql-reference/functions/hash-functions.md b/docs/en/sql-reference/functions/hash-functions.md index e28594540be..20fe6d14e86 100644 --- a/docs/en/sql-reference/functions/hash-functions.md +++ b/docs/en/sql-reference/functions/hash-functions.md @@ -137,23 +137,29 @@ This is a relatively fast non-cryptographic hash function of average quality for Calculates a 64-bit hash code from any type of integer. It works faster than intHash32. Average quality. -## SHA1 {#sha1} +## SHA1, SHA224, SHA256, SHA512 {#sha} -Calculates SHA-1 hash from a string and returns the resulting set of bytes as [FixedString(20)](../data-types/fixedstring.md). +Calculates SHA-1, SHA-224, SHA-256, SHA-512 hash from a string and returns the resulting set of bytes as [FixedString](../data-types/fixedstring.md). **Syntax** ``` sql SHA1('s') +... +SHA512('s') ``` +The function works fairly slowly (SHA-1 processes about 5 million short strings per second per processor core, while SHA-224 and SHA-256 process about 2.2 million). +We recommend using this function only in cases when you need a specific hash function and you can’t select it. +Even in these cases, we recommend applying the function offline and pre-calculating values when inserting them into the table, instead of applying it in `SELECT` queries. + **Arguments** - `s` — Input string for SHA-1 hash calculation. [String](../data-types/string.md). **Returned value** -- SHA-1 hash as a hex-unencoded FixedString(10). +- SHA hash as a hex-unencoded FixedString. SHA-1 returns as FixedString(20), SHA-224 as FixedString(28), SHA-256 — FixedString(32), SHA-512 — FixedString(64). Type: [FixedString](../data-types/fixedstring.md). @@ -175,124 +181,6 @@ Result: └──────────────────────────────────────────┘ ``` -## SHA224 {#sha224} - -Calculates SHA-224 hash from a string and returns the resulting set of bytes as [FixedString(28)](../data-types/fixedstring.md). - -**Syntax** - -``` sql -SHA224('s') -``` - -**Arguments** - -- `s` — Input string for SHA-224 hash calculation. [String](../data-types/string.md). - -**Returned value** - -- SHA-224 hash as a hex-unencoded FixedString(28). - -Type: [FixedString](../data-types/fixedstring.md). - -**Example** - -Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. - -Query: - -``` sql -SELECT hex(SHA224('abc')); -``` - -Result: - -``` text -┌─hex(SHA224('abc'))───────────────────────────────────────┐ -│ 23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7 │ -└──────────────────────────────────────────────────────────┘ -``` - -## SHA256 {#sha256} - -Calculates SHA-256 hash from a string and returns the resulting set of bytes as [FixedString(32)](../data-types/fixedstring.md). - -**Syntax** - -``` sql -SHA256('s') -``` - -**Arguments** - -- `s` — Input string for SHA-256 hash calculation. [String](../data-types/string.md). - -**Returned value** - -- SHA-256 hash as a hex-unencoded FixedString(32). - -Type: [FixedString](../data-types/fixedstring.md). - -**Example** - -Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. - -Query: - -``` sql -SELECT hex(SHA256('abc')); -``` - -Result: - -``` text -┌─hex(SHA256('abc'))───────────────────────────────────────────────┐ -│ BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD │ -└──────────────────────────────────────────────────────────────────┘ -``` - -## SHA512 {#sha512} - -Calculates SHA-512 hash from a string and returns the resulting set of bytes as [FixedString(64)](../data-types/fixedstring.md). - -**Syntax** - -``` sql -SHA512('s') -``` - -The function works fairly slowly (SHA-1 processes about 5 million short strings per second per processor core, while SHA-224 and SHA-256 process about 2.2 million). -We recommend using this function only in cases when you need a specific hash function and you can’t select it. -Even in these cases, we recommend applying the function offline and pre-calculating values when inserting them into the table, instead of applying it in `SELECT` queries. - -**Arguments** - -- `s` — Input string for SHA-512 hash calculation. [String](../data-types/string.md). - -**Returned value** - -- SHA-512 hash as a hex-unencoded FixedString(64). - -Type: [FixedString](../data-types/fixedstring.md). - -**Example** - -Use the [hex](../functions/encoding-functions.md#hex) function to represent the result as a hex-encoded string. - -Query: - -``` sql -SELECT hex(SHA512('abc')); -``` - -Result: - -``` text -┌─hex(SHA512('abc'))───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F │ -└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -``` - ## URLHash(url\[, N\]) {#urlhashurl-n} A fast, decent-quality non-cryptographic hash function for a string obtained from a URL using some type of normalization. diff --git a/docs/ru/sql-reference/functions/hash-functions.md b/docs/ru/sql-reference/functions/hash-functions.md index 18197f88ce3..f3b14625a8c 100644 --- a/docs/ru/sql-reference/functions/hash-functions.md +++ b/docs/ru/sql-reference/functions/hash-functions.md @@ -137,23 +137,29 @@ SELECT groupBitXor(cityHash64(*)) FROM table Вычисляет 64-битный хэш-код от целого числа любого типа. Работает быстрее, чем intHash32. Качество среднее. -## SHA1 {#sha1} +## SHA1, SHA224, SHA256, SHA512 {#sha} -Вычисляет SHA-1 хеш строки и возвращает полученный набор байт в виде [FixedString(20)](../data-types/fixedstring.md). +Вычисляет SHA-1, SHA-224, SHA-256, SHA-512 хеш строки и возвращает полученный набор байт в виде [FixedString](../data-types/fixedstring.md). **Синтаксис** ``` sql SHA1('s') +... +SHA512('s') ``` +Функция работает достаточно медленно (SHA-1 — примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 — примерно 2.2 миллионов). +Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хеш-функция и вы не можете её выбрать. +Даже в этих случаях рекомендуется применять функцию офлайн — заранее вычисляя значения при вставке в таблицу, вместо того чтобы применять её при выполнении `SELECT`. + **Параметры** -- `s` — входная строка для вычисления хеша SHA-1. [String](../data-types/string.md). +- `s` — входная строка для вычисления хеша SHA. [String](../data-types/string.md). **Возвращаемое значение** -- Хеш SHA-1 в виде шестнадцатеричной некодированной строки FixedString(20). +- Хеш SHA в виде шестнадцатеричной некодированной строки FixedString. SHA-1 хеш как FixedString(20), SHA-224 как FixedString(28), SHA-256 — FixedString(32), SHA-512 — FixedString(64). Тип: [FixedString](../data-types/fixedstring.md). @@ -175,124 +181,6 @@ SELECT hex(SHA1('abc')); └──────────────────────────────────────────┘ ``` -## SHA224 {#sha224} - -Вычисляет SHA-224 хеш строки и возвращает полученный набор байт в виде [FixedString(28)](../data-types/fixedstring.md). - -**Синтаксис** - -``` sql -SHA224('s') -``` - -**Параметры** - -- `s` — входная строка для вычисления хеша SHA-224. [String](../data-types/string.md). - -**Возвращаемое значение** - -- Хеш SHA-224 в виде шестнадцатеричной некодированной строки FixedString(28). - -Тип: [FixedString](../data-types/fixedstring.md). - -**Пример** - -Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. - -Запрос: - -``` sql -SELECT hex(SHA224('abc')); -``` - -Результат: - -``` text -┌─hex(SHA224('abc'))───────────────────────────────────────┐ -│ 23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7 │ -└──────────────────────────────────────────────────────────┘ -``` - -## SHA256 {#sha256} - -Вычисляет SHA-256 хеш строки и возвращает полученный набор байт в виде [FixedString(32)](../data-types/fixedstring.md). - -**Синтаксис** - -``` sql -SHA256('s') -``` - -**Параметры** - -- `s` — входная строка для вычисления хеша SHA-256. [String](../data-types/string.md). - -**Возвращаемое значение** - -- Хеш SHA-256 в виде шестнадцатеричной некодированной строки FixedString(32). - -Тип: [FixedString](../data-types/fixedstring.md). - -**Пример** - -Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. - -Запрос: - -``` sql -SELECT hex(SHA256('abc')); -``` - -Результат: - -``` text -┌─hex(SHA256('abc'))───────────────────────────────────────────────┐ -│ BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD │ -└──────────────────────────────────────────────────────────────────┘ -``` - -## SHA512 {#sha512} - -Вычисляет SHA-512 хеш строки и возвращает полученный набор байт в виде [FixedString(64)](../data-types/fixedstring.md) - -**Синтаксис** - -``` sql -SHA512('s') -``` - -Функция работает достаточно медленно (SHA-1 — примерно 5 миллионов коротких строк в секунду на одном процессорном ядре, SHA-224 и SHA-256 — примерно 2.2 миллионов). -Рекомендуется использовать эти функции лишь в тех случаях, когда вам нужна конкретная хеш-функция и вы не можете её выбрать. -Даже в этих случаях рекомендуется применять функцию офлайн — заранее вычисляя значения при вставке в таблицу, вместо того чтобы применять её при выполнении `SELECT`. - -**Параметры** - -- `s` — входная строка для вычисления хеша SHA-512. [String](../data-types/string.md). - -**Возвращаемое значение** - -- Хеш SHA-512 в виде шестнадцатеричной некодированной строки FixedString(64). - -Тип: [FixedString](../data-types/fixedstring.md). - -**Пример** - -Используйте функцию [hex](../functions/encoding-functions.md#hex) для представления результата в виде строки с шестнадцатеричной кодировкой. - -Запрос: - -``` sql -SELECT hex(SHA512('abc')); -``` - -Результат: - -``` text -┌─hex(SHA512('abc'))───────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F │ -└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -``` - ## URLHash(url\[, N\]) {#urlhashurl-n} Быстрая не криптографическая хэш-функция неплохого качества для строки, полученной из URL путём некоторой нормализации. From 57c5d9d3828b69935a71d6f472762bdbce93bb46 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Mon, 4 Oct 2021 00:29:46 +0300 Subject: [PATCH 038/264] Update hash-functions.md minor fix --- docs/en/sql-reference/functions/hash-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/functions/hash-functions.md b/docs/en/sql-reference/functions/hash-functions.md index d8659b406df..21ed8d33098 100644 --- a/docs/en/sql-reference/functions/hash-functions.md +++ b/docs/en/sql-reference/functions/hash-functions.md @@ -159,7 +159,7 @@ Even in these cases, we recommend applying the function offline and pre-calculat **Arguments** -- `s` — Input string for SHA-1 hash calculation. [String](../data-types/string.md). +- `s` — Input string for SHA hash calculation. [String](../data-types/string.md). **Returned value** From 4497f5094e518f0a9d16068c152c88b6bc4c5c98 Mon Sep 17 00:00:00 2001 From: Mikhail <71978106+michon470@users.noreply.github.com> Date: Mon, 4 Oct 2021 16:19:51 +0300 Subject: [PATCH 039/264] Moved changes to this new branch --- .../sql-reference/statements/alter/column.md | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/en/sql-reference/statements/alter/column.md b/docs/en/sql-reference/statements/alter/column.md index 801690afbb2..8f9273c81ba 100644 --- a/docs/en/sql-reference/statements/alter/column.md +++ b/docs/en/sql-reference/statements/alter/column.md @@ -10,7 +10,7 @@ A set of queries that allow changing the table structure. Syntax: ``` sql -ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ... +ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|RENAME|CLEAR|COMMENT|MODIFY|MATERIALIZE COLUMN ... ``` In the query, specify a list of one or more comma-separated actions. @@ -25,6 +25,7 @@ The following actions are supported: - [COMMENT COLUMN](#alter_comment-column) — Adds a text comment to the column. - [MODIFY COLUMN](#alter_modify-column) — Changes column’s type, default expression and TTL. - [MODIFY COLUMN REMOVE](#modify-remove) — Removes one of the column properties. +- [MATERIALIZE COLUMN](#materialize-column) — Materializes the column in the parts where the column is missing. These actions are described in detail below. @@ -193,6 +194,39 @@ ALTER TABLE table_with_ttl MODIFY COLUMN column_ttl REMOVE TTL; - [REMOVE TTL](ttl.md). +## MATERIALIZE COLUMN {#materialize-column} + +Materializes the column in the parts where the column is missing. This is useful in case of creating a new column with complicated `DEFAULT` or `MATERIALIZED` expression. Calculation of the column directly on `SELECT` query can cause bigger request execution time, so it is reasonable to use `MATERIALIZE COLUMN` for such columns. To perform same manipulation for existing column, use `FINAL` modifier as shown below. + +Syntax: + +```sql +ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; +``` + +**Example:** + +```sql +DROP TABLE IF EXISTS tmp; +SET mutations_sync = 2; +CREATE TABLE tmp (x Int64) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY tuple(); +INSERT INTO tmp SELECT * FROM system.numbers LIMIT 20; +ALTER TABLE tmp ADD COLUMN s String MATERIALIZED toString(x); +SELECT groupArray(x), groupArray(s) FROM tmp; +``` + +**Result:** + +```sql +┌─groupArray(x)───────────────────────────────────────┬─groupArray(s)───────────────────────────────────────────────────────────────────────────────┐ +│ [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] │ ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19'] │ +└─────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +**See Also** + +- [MATERIALIZED](../../statements/create/table.md#materialized). + ## Limitations {#alter-query-limitations} The `ALTER` query lets you create and delete separate elements (columns) in nested data structures, but not whole nested data structures. To add a nested data structure, you can add columns with a name like `name.nested_name` and the type `Array(T)`. A nested data structure is equivalent to multiple array columns with a name that has the same prefix before the dot. From 52c5f2da7203eaaae8ea819bc8ef405dafacb1c2 Mon Sep 17 00:00:00 2001 From: Mikhail <71978106+michon470@users.noreply.github.com> Date: Mon, 4 Oct 2021 16:41:50 +0300 Subject: [PATCH 040/264] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B2=D0=BE?= =?UTF-8?q?=D0=B4=20+=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B0=D0=BD=D0=B3=D0=BB=20=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D1=81=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sql-reference/statements/alter/column.md | 2 +- .../sql-reference/statements/alter/column.md | 38 +++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/docs/en/sql-reference/statements/alter/column.md b/docs/en/sql-reference/statements/alter/column.md index 8f9273c81ba..31874ef208d 100644 --- a/docs/en/sql-reference/statements/alter/column.md +++ b/docs/en/sql-reference/statements/alter/column.md @@ -204,7 +204,7 @@ Syntax: ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; ``` -**Example:** +**Example with the creation of new column:** ```sql DROP TABLE IF EXISTS tmp; diff --git a/docs/ru/sql-reference/statements/alter/column.md b/docs/ru/sql-reference/statements/alter/column.md index 9f59c79bfdd..366caf6a2a0 100644 --- a/docs/ru/sql-reference/statements/alter/column.md +++ b/docs/ru/sql-reference/statements/alter/column.md @@ -10,7 +10,7 @@ toc_title: "Манипуляции со столбцами" Синтаксис: ``` sql -ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ... +ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|RENAME|CLEAR|COMMENT|MODIFY|MATERIALIZE COLUMN ... ``` В запросе можно указать сразу несколько действий над одной таблицей через запятую. @@ -20,11 +20,12 @@ ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN - [ADD COLUMN](#alter_add-column) — добавляет столбец в таблицу; - [DROP COLUMN](#alter_drop-column) — удаляет столбец; -- [RENAME COLUMN](#alter_rename-column) — переименовывает существующий столбец. +- [RENAME COLUMN](#alter_rename-column) — переименовывает существующий столбец; - [CLEAR COLUMN](#alter_clear-column) — сбрасывает все значения в столбце для заданной партиции; - [COMMENT COLUMN](#alter_comment-column) — добавляет комментарий к столбцу; -- [MODIFY COLUMN](#alter_modify-column) — изменяет тип столбца, выражение для значения по умолчанию и TTL. -- [MODIFY COLUMN REMOVE](#modify-remove) — удаляет какое-либо из свойств столбца. +- [MODIFY COLUMN](#alter_modify-column) — изменяет тип столбца, выражение для значения по умолчанию и TTL; +- [MODIFY COLUMN REMOVE](#modify-remove) — удаляет какое-либо из свойств столбца; +- [MATERIALIZE COLUMN](#materialize-column) — делает столбец материализованным (MATERIALIZED) в его частях, у которых отсутствуют значения. Подробное описание для каждого действия приведено ниже. @@ -193,6 +194,35 @@ ALTER TABLE table_with_ttl MODIFY COLUMN column_ttl REMOVE TTL; - [REMOVE TTL](ttl.md). +## MATERIALIZE COLUMN {#materialize-column} + +С помощью этого запроса можно сделать столбец таблицы материализованным (`MATERIALIZED`) в его частях, у которых отсутствуют значения. Это полезно, если необходимо создать новый столбец со сложным материализованным выражением или выражением для заполнения по умолчанию (`DEFAULT`). Если вычисление такого столбца прямо во время выполнения запроса `SELECT` оказывается ощутимо большим, для него может оказаться целесообразным использовать `MATERIALIZE COLUMN`. Чтобы совершить ту же операцию для существующего столбца, используйте модификатор `FINAL`, как показано ниже. + +Синтаксис: + +```sql +ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; +``` + +**Пример использования при создании нового столбца:** + +```sql +DROP TABLE IF EXISTS tmp; +SET mutations_sync = 2; +CREATE TABLE tmp (x Int64) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY tuple(); +INSERT INTO tmp SELECT * FROM system.numbers LIMIT 20; +ALTER TABLE tmp ADD COLUMN s String MATERIALIZED toString(x); +SELECT groupArray(x), groupArray(s) FROM tmp; +``` + +**Результат:** + +```sql +┌─groupArray(x)───────────────────────────────────────┬─groupArray(s)───────────────────────────────────────────────────────────────────────────────┐ +│ [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] │ ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19'] │ +└─────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘ +``` + ## Ограничения запроса ALTER {#ogranicheniia-zaprosa-alter} Запрос `ALTER` позволяет создавать и удалять отдельные элементы (столбцы) вложенных структур данных, но не вложенные структуры данных целиком. Для добавления вложенной структуры данных, вы можете добавить столбцы с именем вида `name.nested_name` и типом `Array(T)` - вложенная структура данных полностью эквивалентна нескольким столбцам-массивам с именем, имеющим одинаковый префикс до точки. From a638c40fdcfd1b8b01153713e070664c1c38976f Mon Sep 17 00:00:00 2001 From: WangZengrui Date: Tue, 5 Oct 2021 09:08:16 +0800 Subject: [PATCH 041/264] add getOSKernelVersion --- src/Interpreters/getOSKernelVersion.cpp | 18 ++++++------------ src/Interpreters/getOSKernelVersion.h | 12 +----------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/Interpreters/getOSKernelVersion.cpp b/src/Interpreters/getOSKernelVersion.cpp index 44df948be3c..c4b4564f46e 100644 --- a/src/Interpreters/getOSKernelVersion.cpp +++ b/src/Interpreters/getOSKernelVersion.cpp @@ -7,28 +7,22 @@ namespace DB namespace ErrorCodes { - extern const int BAD_ARGUMENTS; + extern const int SYSTEM_ERROR; } String getOSKernelVersion() { - struct utsname os_kernel_version; - int buf = uname(&os_kernel_version); + struct utsname os_kernel_info; + int buf = uname(&os_kernel_info); if (buf < 0) { throw Exception( - "EFAULT buf is not valid.", - ErrorCodes::BAD_ARGUMENTS); + "EFAULT buffer is not valid.", + ErrorCodes::SYSTEM_ERROR); } else { - // std::cout <<"sysname: " << os_kernel_version.sysname << " nodename: " << os_kernel_version.nodename - // << " release: " << os_kernel_version.release << " version: " << os_kernel_version.version - // << " machine: " << os_kernel_version.machine << std::endl; - - return "sysname: " + String(os_kernel_version.sysname) + " nodename: " + String(os_kernel_version.nodename) - + " release: " + String(os_kernel_version.release) + " version: " + String(os_kernel_version.version) - + " machine: " + String(os_kernel_version.machine); + return String(os_kernel_info.sysname) + " " + String(os_kernel_info.release); } } diff --git a/src/Interpreters/getOSKernelVersion.h b/src/Interpreters/getOSKernelVersion.h index 14b42d2a19a..fc3c7583aef 100644 --- a/src/Interpreters/getOSKernelVersion.h +++ b/src/Interpreters/getOSKernelVersion.h @@ -1,5 +1,5 @@ -#if defined(OS_LINUX) #pragma once +#if defined(OS_LINUX) #include @@ -16,16 +16,6 @@ namespace DB String getOSKernelVersion(); -// String getSysName(); - -// String getNodeName(); - -// String getReleaseName(); - -// String getVersion(); - -// String getMachineName(); - } #endif \ No newline at end of file From 82e6ac8fa2cdba5ef016bbe4278d7c17888dafb7 Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Tue, 5 Oct 2021 13:39:18 +0300 Subject: [PATCH 042/264] Update HTTPHandler.cpp --- src/Server/HTTPHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 413cfe18696..1036d5031f7 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -24,7 +24,7 @@ #include #include #include -#include "common/logger_useful.h" +#include #include #include #include From 9b1a39fdb9c4b79d2f045f88d97a1ce33c7d4797 Mon Sep 17 00:00:00 2001 From: Artur Filatenkov <613623@mail.ru> Date: Tue, 5 Oct 2021 17:43:33 +0300 Subject: [PATCH 043/264] refactor after move common to base --- src/Server/HTTPHandler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 1036d5031f7..9edef8a7223 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -24,15 +24,15 @@ #include #include #include -#include +#include #include #include #include #include #include -#include -#include +#include +#include #include #if !defined(ARCADIA_BUILD) From fbfdd605eea214466bbd8d32a58f214aa5e5ca8e Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Tue, 5 Oct 2021 21:58:49 +0300 Subject: [PATCH 044/264] Update metrica.md Update ru with for hits_100m_obfuscated --- docs/ru/getting-started/example-datasets/metrica.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index c82048a445e..27105ca8488 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -38,6 +38,9 @@ $ curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads= $ # теперь создадим таблицу $ clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" $ clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" +# for hits_100m_obfuscated +clickhouse-client --query="CREATE TABLE hits_100m_obfuscated (WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, Refresh UInt8, RefererCategoryID UInt16, RefererRegionID UInt32, URLCategoryID UInt16, URLRegionID UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, OriginalURL String, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), LocalEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, RemoteIP UInt32, WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming UInt32, DNSTiming UInt32, ConnectTiming UInt32, ResponseStartTiming UInt32, ResponseEndTiming UInt32, FetchTiming UInt32, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" + $ # импортируем данные $ cat hits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.hits_v1 FORMAT TSV" --max_insert_block_size=100000 $ # опционально можно оптимизировать таблицу From af94e30a955dbfe271f412ee5ebe384994448f8e Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Tue, 5 Oct 2021 22:12:44 +0300 Subject: [PATCH 045/264] Update H3 functions Update en and add ru draft. --- docs/en/sql-reference/functions/geo/h3.md | 14 +-- docs/ru/sql-reference/functions/geo/h3.md | 112 +++++++++++++++++++++- 2 files changed, 118 insertions(+), 8 deletions(-) diff --git a/docs/en/sql-reference/functions/geo/h3.md b/docs/en/sql-reference/functions/geo/h3.md index 3c3ed7b8932..9cdd3bcf947 100644 --- a/docs/en/sql-reference/functions/geo/h3.md +++ b/docs/en/sql-reference/functions/geo/h3.md @@ -481,7 +481,7 @@ Type: [UInt64](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT h3ToParent(599405990164561919, 3) as parent; +SELECT h3ToParent(599405990164561919, 3) AS parent; ``` Result: @@ -515,7 +515,7 @@ Type: [String](../../../sql-reference/data-types/string.md). Query: ``` sql -SELECT h3ToString(617420388352917503) as h3_string; +SELECT h3ToString(617420388352917503) AS h3_string; ``` Result: @@ -549,7 +549,7 @@ stringToH3(index_str) Query: ``` sql -SELECT stringToH3('89184926cc3ffff') as index; +SELECT stringToH3('89184926cc3ffff') AS index; ``` Result: @@ -583,7 +583,7 @@ h3GetResolution(index) Query: ``` sql -SELECT h3GetResolution(617420388352917503) as res; +SELECT h3GetResolution(617420388352917503) AS res; ``` Result: @@ -620,7 +620,7 @@ Type: [UInt8](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT h3IsResClassIII(617420388352917503) as res; +SELECT h3IsResClassIII(617420388352917503) AS res; ``` Result: @@ -657,7 +657,7 @@ Type: [UInt8](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT SELECT h3IsPentagon(644721767722457330) as pentagon; +SELECT h3IsPentagon(644721767722457330) AS pentagon; ``` Result: @@ -693,7 +693,7 @@ Type: [Array](../../../sql-reference/data-types/array.md)([UInt64](../../../sql- Query: ``` sql -SELECT SELECT h3GetFaces(599686042433355775) as faces; +SELECT h3GetFaces(599686042433355775) AS faces; ``` Result: diff --git a/docs/ru/sql-reference/functions/geo/h3.md b/docs/ru/sql-reference/functions/geo/h3.md index bc47ca72a39..e8871d856c4 100644 --- a/docs/ru/sql-reference/functions/geo/h3.md +++ b/docs/ru/sql-reference/functions/geo/h3.md @@ -548,7 +548,7 @@ h3GetResolution(index) Запрос: ``` sql -SELECT h3GetResolution(617420388352917503) as res; +SELECT h3GetResolution(617420388352917503) AS res; ``` Результат: @@ -559,3 +559,113 @@ SELECT h3GetResolution(617420388352917503) as res; └─────┘ ``` +## h3IsResClassIII {#h3isresclassIII} + +Returns whether [H3](#h3index) index has a resolution with Class III orientation. + +**Синтаксис** + +``` sql +h3IsResClassIII(index) +``` + +**Параметр** + +- `index` — Hexagon index number. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). + +**Возвращаемые значения** + +- `1` — Index has a resolution with Class III orientation. +- `0` — Index doesn't have a resolution with Class III orientation. + +Тип: [UInt8](../../../sql-reference/data-types/int-uint.md). + +**Пример** + +Запрос: + +``` sql +SELECT h3IsResClassIII(617420388352917503) AS res; +``` + +Результат: + +``` text +┌─res─┐ +│ 1 │ +└─────┘ +``` + +## h3IsPentagon {#h3ispentagon } + +Returns whether this [H3](#h3index) index represents a pentagonal cell. + +**Синтаксис** + +``` sql +h3IsPentagon(index) +``` + +**Параметр** + +- `index` — Hexagon index number. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). + +**Возвращаемые значения** + +- `1` — Index represents a pentagonal cell. +- `0` — Index doesn't represent a pentagonal cell. + +Тип: [UInt8](../../../sql-reference/data-types/int-uint.md). + +**Пример** + +Запрос: + +``` sql +SELECT h3IsPentagon(644721767722457330) AS pentagon; +``` + +Результат: + +``` text +┌─pentagon─┐ +│ 0 │ +└──────────┘ +``` + +## h3GetFaces {#h3getfaces} + +Returns icosahedron faces intersected by a given [H3](#h3index) index. + +**Синтаксис** + +``` sql +h3GetFaces(index) +``` + +**Параметр** + +- `index` — Hexagon index number. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). + +**Возвращаемое значение** + +- Array containing icosahedron faces intersected by a given H3 index. + +Тип: [Array](../../../sql-reference/data-types/array.md)([UInt64](../../../sql-reference/data-types/int-uint.md)). + +**Пример** + +Запрос: + +``` sql +SELECT h3GetFaces(599686042433355775) AS faces; +``` + +Результат: + +``` text +┌─faces─┐ +│ [7] │ +└───────┘ + +[Оригинальная статья](https://clickhouse.com/docs/ru/sql-reference/functions/geo/h3) From bd4b0af2e14dfa22257d4778bf135f65dee1723c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 6 Oct 2021 02:34:48 +0300 Subject: [PATCH 046/264] Fix bad cast in ParserCreateQuery --- src/Parsers/ParserCreateQuery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Parsers/ParserCreateQuery.cpp b/src/Parsers/ParserCreateQuery.cpp index d4525883e36..2ea1663fc80 100644 --- a/src/Parsers/ParserCreateQuery.cpp +++ b/src/Parsers/ParserCreateQuery.cpp @@ -481,7 +481,7 @@ bool ParserCreateTableQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expe if (attach && s_from.ignore(pos, expected)) { - ParserLiteral from_path_p; + ParserStringLiteral from_path_p; if (!from_path_p.parse(pos, from_path, expected)) return false; } From 1550c167bb8b725376968d2b1f2779c669f59a3a Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 6 Oct 2021 18:14:51 +0300 Subject: [PATCH 047/264] Update ru translation. --- docs/en/sql-reference/functions/geo/h3.md | 2 +- docs/ru/sql-reference/functions/geo/h3.md | 26 +++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/en/sql-reference/functions/geo/h3.md b/docs/en/sql-reference/functions/geo/h3.md index 9cdd3bcf947..410cb9d3cc2 100644 --- a/docs/en/sql-reference/functions/geo/h3.md +++ b/docs/en/sql-reference/functions/geo/h3.md @@ -631,7 +631,7 @@ Result: └─────┘ ``` -## h3IsPentagon {#h3ispentagon } +## h3IsPentagon {#h3ispentagon} Returns whether this [H3](#h3index) index represents a pentagonal cell. diff --git a/docs/ru/sql-reference/functions/geo/h3.md b/docs/ru/sql-reference/functions/geo/h3.md index e8871d856c4..cd807ade04a 100644 --- a/docs/ru/sql-reference/functions/geo/h3.md +++ b/docs/ru/sql-reference/functions/geo/h3.md @@ -6,7 +6,7 @@ toc_title: "Функции для работы с индексами H3" [H3](https://eng.uber.com/h3/) — это система геокодирования, которая делит поверхность Земли на равные шестигранные ячейки. Система поддерживает иерархию (вложенность) ячеек, т.е. каждый "родительский" шестигранник может быть поделен на семь одинаковых вложенных "дочерних" шестигранников, и так далее. -Уровень вложенности назвается `разрешением` и может принимать значение от `0` до `15`, где `0` соответствует `базовым` ячейкам самого верхнего уровня (наиболее крупным). +Уровень вложенности называется `разрешением` и может принимать значение от `0` до `15`, где `0` соответствует `базовым` ячейкам самого верхнего уровня (наиболее крупным). Для каждой точки, имеющей широту и долготу, можно получить 64-битный индекс H3, соответствующий номеру шестигранной ячейки, где эта точка находится. @@ -561,7 +561,7 @@ SELECT h3GetResolution(617420388352917503) AS res; ## h3IsResClassIII {#h3isresclassIII} -Returns whether [H3](#h3index) index has a resolution with Class III orientation. +Проверяет, имеет ли индекс [H3](#h3index) разрешение с ориентацией Class III. **Синтаксис** @@ -571,12 +571,12 @@ h3IsResClassIII(index) **Параметр** -- `index` — Hexagon index number. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). +- `index` — порядковый номер шестигранника. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). **Возвращаемые значения** -- `1` — Index has a resolution with Class III orientation. -- `0` — Index doesn't have a resolution with Class III orientation. +- `1` — индекс имеет разрешение с ориентацией Class III. +- `0` — индекс не имеет разрешения с ориентацией Class III. Тип: [UInt8](../../../sql-reference/data-types/int-uint.md). @@ -596,9 +596,9 @@ SELECT h3IsResClassIII(617420388352917503) AS res; └─────┘ ``` -## h3IsPentagon {#h3ispentagon } +## h3IsPentagon {#h3ispentagon} -Returns whether this [H3](#h3index) index represents a pentagonal cell. +Проверяет, является ли указанный индекс [H3](#h3index) пятиугольной ячейкой. **Синтаксис** @@ -608,12 +608,12 @@ h3IsPentagon(index) **Параметр** -- `index` — Hexagon index number. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). +- `index` — порядковый номер шестигранника. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). **Возвращаемые значения** -- `1` — Index represents a pentagonal cell. -- `0` — Index doesn't represent a pentagonal cell. +- `1` — индекс представляет собой пятиугольную ячейку. +- `0` — индекс не является пятиугольной ячейкой. Тип: [UInt8](../../../sql-reference/data-types/int-uint.md). @@ -635,7 +635,7 @@ SELECT h3IsPentagon(644721767722457330) AS pentagon; ## h3GetFaces {#h3getfaces} -Returns icosahedron faces intersected by a given [H3](#h3index) index. +Возвращает все грани многоугольника (икосаэдра), пересекаемые заданным [H3](#h3index) индексом. **Синтаксис** @@ -645,11 +645,11 @@ h3GetFaces(index) **Параметр** -- `index` — Hexagon index number. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). +- `index` — индекс шестиугольной ячейки. Тип: [UInt64](../../../sql-reference/data-types/int-uint.md). **Возвращаемое значение** -- Array containing icosahedron faces intersected by a given H3 index. +- Массив, содержащий грани многоугольника (икосаэдра), пересекаемые заданным H3 индексом. Тип: [Array](../../../sql-reference/data-types/array.md)([UInt64](../../../sql-reference/data-types/int-uint.md)). From 259da1ccf07e8ed788ed7a418884c91801bff1fa Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Wed, 6 Oct 2021 18:32:55 +0300 Subject: [PATCH 048/264] Update h3.md --- docs/ru/sql-reference/functions/geo/h3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/geo/h3.md b/docs/ru/sql-reference/functions/geo/h3.md index cd807ade04a..6bc6943ec93 100644 --- a/docs/ru/sql-reference/functions/geo/h3.md +++ b/docs/ru/sql-reference/functions/geo/h3.md @@ -668,4 +668,4 @@ SELECT h3GetFaces(599686042433355775) AS faces; │ [7] │ └───────┘ -[Оригинальная статья](https://clickhouse.com/docs/ru/sql-reference/functions/geo/h3) +[Оригинальная статья](https://clickhouse.com/docs/ru/sql-reference/functions/geo/h3/) From 4894588f2751189a55b0dce9ca218e4b0040ec7b Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 6 Oct 2021 19:50:05 +0000 Subject: [PATCH 049/264] description improved new example --- .../functions/other-functions.md | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/docs/en/sql-reference/functions/other-functions.md b/docs/en/sql-reference/functions/other-functions.md index 44702f4097f..2bb38684eb3 100644 --- a/docs/en/sql-reference/functions/other-functions.md +++ b/docs/en/sql-reference/functions/other-functions.md @@ -2357,8 +2357,8 @@ Result: ## shardNum {#shard-num} -Returns the number of a shard which executes the query for a distributed query. -If query is not distributed then *constant value* is returned. +Returns the index of a shard which processes a part of data for a distributed query. Indices are started from `1`. +If a query is not distributed then constant value `0` is returned. **Syntax** @@ -2368,14 +2368,39 @@ shardNum() **Returned value** -- Shard number. +- Shard index or constant `0`. Type: [UInt32](../../sql-reference/data-types/int-uint.md). +**Example** + +In the following example a configuration with two shards is used. The query is executed on the [system.one](../../operations/system-tables/one.md) table on every shard. + +Query: + +``` sql +CREATE TABLE shard_num_example (dummy UInt8) + ENGINE=Distributed(test_cluster_two_shards_localhost, system, one, dummy); +SELECT dummy, shardNum(), shardCount() FROM shard_num_example; +``` + +Result: + +``` text +┌─dummy─┬─shardNum()─┬─shardCount()─┐ +│ 0 │ 2 │ 2 │ +│ 0 │ 1 │ 2 │ +└───────┴────────────┴──────────────┘ +``` + +**See Also** + +- [Distributed Table Engine](../../engines/table-engines/special/distributed.md) + ## shardCount {#shard-count} -Returns the total number of shards which execute a distributed query. -If query is not distributed then *constant value* is returned. +Returns the total number of shards for a distributed query. +If a query is not distributed then constant value `0` is returned. **Syntax** @@ -2385,8 +2410,10 @@ shardCount() **Returned value** -- Total number of shards. +- Total number of shards or `0`. Type: [UInt32](../../sql-reference/data-types/int-uint.md). +**See Also** +- [shardNum()](#shard-num) function example also contains `shardCount()` function call. From c2533b974394c2f1b4c356fa8408ad9dc0526d0f Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 6 Oct 2021 20:13:46 +0000 Subject: [PATCH 050/264] constant or column note added for other functions --- docs/en/sql-reference/functions/date-time-functions.md | 1 + docs/en/sql-reference/functions/other-functions.md | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/en/sql-reference/functions/date-time-functions.md b/docs/en/sql-reference/functions/date-time-functions.md index f54ef635e0c..b85f105758b 100644 --- a/docs/en/sql-reference/functions/date-time-functions.md +++ b/docs/en/sql-reference/functions/date-time-functions.md @@ -26,6 +26,7 @@ SELECT ## timeZone {#timezone} Returns the timezone of the server. +If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. **Syntax** diff --git a/docs/en/sql-reference/functions/other-functions.md b/docs/en/sql-reference/functions/other-functions.md index 2bb38684eb3..afcc9563b58 100644 --- a/docs/en/sql-reference/functions/other-functions.md +++ b/docs/en/sql-reference/functions/other-functions.md @@ -8,6 +8,7 @@ toc_title: Other ## hostName() {#hostname} Returns a string with the name of the host that this function was performed on. For distributed processing, this is the name of the remote server host, if the function is performed on a remote server. +If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. ## getMacro {#getmacro} @@ -691,10 +692,12 @@ Returns the largest value of a and b. ## uptime() {#uptime} Returns the server’s uptime in seconds. +If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. ## version() {#version} Returns the version of the server as a string. +If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. ## blockNumber {#blocknumber} @@ -2101,6 +2104,7 @@ UNSUPPORTED_METHOD ## tcpPort {#tcpPort} Returns [native interface](../../interfaces/tcp.md) TCP port number listened by this server. +If it is executed in the context of a distributed table, then it generates a normal column, otherwise it produces a constant value. **Syntax** From 95154305177f77d245d33493258e28e5df443fbc Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 7 Oct 2021 00:17:14 +0300 Subject: [PATCH 051/264] Fix compilation with glibc 2.34 (MINSIGSTKSZ defined as sysconf(_SC_SIGSTKSZ)) In glibc 2.34 MINSIGSTKSZ had been defined to sysconf(_SC_SIGSTKSZ) [1]. [1]: https://sourceware.org/git/?p=glibc.git;a=commit;h=6c57d320484988e87e446e2e60ce42816bf51d53 --- src/Common/ThreadStatus.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Common/ThreadStatus.cpp b/src/Common/ThreadStatus.cpp index b1d76c4660e..c0190cac58a 100644 --- a/src/Common/ThreadStatus.cpp +++ b/src/Common/ThreadStatus.cpp @@ -44,7 +44,7 @@ namespace struct ThreadStack { ThreadStack() - : data(aligned_alloc(getPageSize(), size)) + : data(aligned_alloc(getPageSize(), getSize())) { /// Add a guard page /// (and since the stack grows downward, we need to protect the first page). @@ -56,12 +56,11 @@ struct ThreadStack free(data); } - static size_t getSize() { return size; } + static size_t getSize() { return std::max(16 << 10, MINSIGSTKSZ); } void * getData() const { return data; } private: /// 16 KiB - not too big but enough to handle error. - static constexpr size_t size = std::max(16 << 10, MINSIGSTKSZ); void * data; }; From c41923c5958067f487b31a27f860cc1e775accdc Mon Sep 17 00:00:00 2001 From: Haavard Kvaalen Date: Thu, 7 Oct 2021 13:29:38 +0200 Subject: [PATCH 052/264] MaterializedMySQL: Update GTID set at end of transaction We would update the set of seen GTIDs as soon as we saw a GTID_EVENT, which arrives before a transaction. This would mostly work fine, but if we lost the connection to MySQL in the middle of a large transaction we would persist that the transaction had been processed as soon as the transaction had started. When the connection was reestablished, we would not process the transaction again, which meant that we only applied parts of it. Fix this by updating the seen GTIDs at the end of the transaction instead. --- src/Core/MySQL/MySQLReplication.cpp | 29 ++++++++++++++++-- src/Core/MySQL/MySQLReplication.h | 4 +++ .../materialize_with_ddl.py | 30 +++++++++++++++++++ .../test_materialized_mysql_database/test.py | 5 ++++ 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/Core/MySQL/MySQLReplication.cpp b/src/Core/MySQL/MySQLReplication.cpp index 9c90b2ff220..b5468d15edc 100644 --- a/src/Core/MySQL/MySQLReplication.cpp +++ b/src/Core/MySQL/MySQLReplication.cpp @@ -105,12 +105,16 @@ namespace MySQLReplication if (query.starts_with("BEGIN") || query.starts_with("COMMIT")) { typ = QUERY_EVENT_MULTI_TXN_FLAG; + if (!query.starts_with("COMMIT")) + transaction_complete = false; } else if (query.starts_with("XA")) { if (query.starts_with("XA ROLLBACK")) throw ReplicationError("ParseQueryEvent: Unsupported query event:" + query, ErrorCodes::LOGICAL_ERROR); typ = QUERY_EVENT_XA; + if (!query.starts_with("XA COMMIT")) + transaction_complete = false; } else if (query.starts_with("SAVEPOINT")) { @@ -711,9 +715,26 @@ namespace MySQLReplication { switch (event->header.type) { - case FORMAT_DESCRIPTION_EVENT: - case QUERY_EVENT: + case FORMAT_DESCRIPTION_EVENT: { + binlog_pos = event->header.log_pos; + break; + } + case QUERY_EVENT: { + auto query = std::static_pointer_cast(event); + if (query->transaction_complete && pending_gtid) + { + gtid_sets.update(*pending_gtid); + pending_gtid.reset(); + } + binlog_pos = event->header.log_pos; + break; + } case XID_EVENT: { + if (pending_gtid) + { + gtid_sets.update(*pending_gtid); + pending_gtid.reset(); + } binlog_pos = event->header.log_pos; break; } @@ -724,9 +745,11 @@ namespace MySQLReplication break; } case GTID_EVENT: { + if (pending_gtid) + gtid_sets.update(*pending_gtid); auto gtid_event = std::static_pointer_cast(event); binlog_pos = event->header.log_pos; - gtid_sets.update(gtid_event->gtid); + pending_gtid = gtid_event->gtid; break; } default: diff --git a/src/Core/MySQL/MySQLReplication.h b/src/Core/MySQL/MySQLReplication.h index a57cc246eaa..cb67ce73de9 100644 --- a/src/Core/MySQL/MySQLReplication.h +++ b/src/Core/MySQL/MySQLReplication.h @@ -383,6 +383,7 @@ namespace MySQLReplication String schema; String query; QueryType typ = QUERY_EVENT_DDL; + bool transaction_complete = true; QueryEvent(EventHeader && header_) : EventBase(std::move(header_)), thread_id(0), exec_time(0), schema_len(0), error_code(0), status_len(0) @@ -536,6 +537,9 @@ namespace MySQLReplication void update(BinlogEventPtr event); void update(UInt64 binlog_pos_, const String & binlog_name_, const String & gtid_sets_); void dump(WriteBuffer & out) const; + + private: + std::optional pending_gtid; }; class IFlavor : public MySQLProtocol::IMySQLReadPacket diff --git a/tests/integration/test_materialized_mysql_database/materialize_with_ddl.py b/tests/integration/test_materialized_mysql_database/materialize_with_ddl.py index 23fa9894a84..5f6daea24ac 100644 --- a/tests/integration/test_materialized_mysql_database/materialize_with_ddl.py +++ b/tests/integration/test_materialized_mysql_database/materialize_with_ddl.py @@ -980,3 +980,33 @@ def mysql_settings_test(clickhouse_node, mysql_node, service_name): clickhouse_node.query("DROP DATABASE test_database") mysql_node.query("DROP DATABASE test_database") +def materialized_mysql_large_transaction(clickhouse_node, mysql_node, service_name): + mysql_node.query("DROP DATABASE IF EXISTS largetransaction") + clickhouse_node.query("DROP DATABASE IF EXISTS largetransaction") + mysql_node.query("CREATE DATABASE largetransaction") + + mysql_node.query("CREATE TABLE largetransaction.test_table (" + "`key` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, " + "`value` INT NOT NULL) ENGINE = InnoDB;") + num_rows = 200000 + rows_per_insert = 5000 + values = ",".join(["(1)" for _ in range(rows_per_insert)]) + for i in range(num_rows//rows_per_insert): + mysql_node.query(f"INSERT INTO largetransaction.test_table (`value`) VALUES {values};") + + + clickhouse_node.query("CREATE DATABASE largetransaction ENGINE = MaterializedMySQL('{}:3306', 'largetransaction', 'root', 'clickhouse')".format(service_name)) + check_query(clickhouse_node, "SELECT COUNT() FROM largetransaction.test_table", f"{num_rows}\n") + + mysql_node.query("UPDATE largetransaction.test_table SET value = 2;") + + # Attempt to restart clickhouse after it has started processing + # the transaction, but before it has completed it. + while int(clickhouse_node.query("SELECT COUNT() FROM largetransaction.test_table WHERE value = 2")) == 0: + time.sleep(0.2) + clickhouse_node.restart_clickhouse() + + check_query(clickhouse_node, "SELECT COUNT() FROM largetransaction.test_table WHERE value = 2", f"{num_rows}\n") + + clickhouse_node.query("DROP DATABASE largetransaction") + mysql_node.query("DROP DATABASE largetransaction") diff --git a/tests/integration/test_materialized_mysql_database/test.py b/tests/integration/test_materialized_mysql_database/test.py index 18cb5b3b87c..feade1b60a0 100644 --- a/tests/integration/test_materialized_mysql_database/test.py +++ b/tests/integration/test_materialized_mysql_database/test.py @@ -237,3 +237,8 @@ def test_materialize_with_enum(started_cluster, started_mysql_8_0, started_mysql def test_mysql_settings(started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node): materialize_with_ddl.mysql_settings_test(clickhouse_node, started_mysql_5_7, "mysql57") materialize_with_ddl.mysql_settings_test(clickhouse_node, started_mysql_8_0, "mysql80") + +@pytest.mark.parametrize(('clickhouse_node'), [pytest.param(node_db_ordinary, id="ordinary"), pytest.param(node_db_atomic, id="atomic")]) +def test_large_transaction(started_cluster, started_mysql_8_0, started_mysql_5_7, clickhouse_node): + materialize_with_ddl.materialized_mysql_large_transaction(clickhouse_node, started_mysql_8_0, "mysql80") + materialize_with_ddl.materialized_mysql_large_transaction(clickhouse_node, started_mysql_5_7, "mysql57") From 7e2bc184ec29358cce749059bf776eccc784231e Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Thu, 7 Oct 2021 16:43:49 +0300 Subject: [PATCH 053/264] fix another suspicious places, add test --- src/Interpreters/MySQL/InterpretersMySQLDDLQuery.cpp | 2 +- src/Parsers/ParserCreateQuery.cpp | 2 +- src/Storages/MergeTree/MergeTreeIndexSet.cpp | 2 +- tests/queries/0_stateless/01188_attach_table_from_path.sql | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Interpreters/MySQL/InterpretersMySQLDDLQuery.cpp b/src/Interpreters/MySQL/InterpretersMySQLDDLQuery.cpp index f2860235117..a96713e3b5d 100644 --- a/src/Interpreters/MySQL/InterpretersMySQLDDLQuery.cpp +++ b/src/Interpreters/MySQL/InterpretersMySQLDDLQuery.cpp @@ -120,7 +120,7 @@ static NamesAndTypesList getColumnsList(const ASTExpressionList * columns_defini auto * literal = child->as(); new_child->arguments = std::make_shared(); - new_child->arguments->children.push_back(std::make_shared(literal->value.get())); + new_child->arguments->children.push_back(std::make_shared(literal->value.safeGet())); new_child->arguments->children.push_back(std::make_shared(Int16(++i))); child = new_child; } diff --git a/src/Parsers/ParserCreateQuery.cpp b/src/Parsers/ParserCreateQuery.cpp index 2ea1663fc80..1da1bfba491 100644 --- a/src/Parsers/ParserCreateQuery.cpp +++ b/src/Parsers/ParserCreateQuery.cpp @@ -896,7 +896,7 @@ bool ParserCreateViewQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec if (ParserKeyword{"TO INNER UUID"}.ignore(pos, expected)) { - ParserLiteral literal_p; + ParserStringLiteral literal_p; if (!literal_p.parse(pos, to_inner_uuid, expected)) return false; } diff --git a/src/Storages/MergeTree/MergeTreeIndexSet.cpp b/src/Storages/MergeTree/MergeTreeIndexSet.cpp index 024b87c9a3e..60b9ddae329 100644 --- a/src/Storages/MergeTree/MergeTreeIndexSet.cpp +++ b/src/Storages/MergeTree/MergeTreeIndexSet.cpp @@ -461,7 +461,7 @@ bool MergeTreeIndexConditionSet::checkASTUseless(const ASTPtr & node, bool atomi [this](const auto & arg) { return checkASTUseless(arg, true); }); } else if (const auto * literal = node->as()) - return !atomic && literal->value.get(); + return !atomic && literal->value.safeGet(); else if (const auto * identifier = node->as()) return key_columns.find(identifier->getColumnName()) == std::end(key_columns); else diff --git a/tests/queries/0_stateless/01188_attach_table_from_path.sql b/tests/queries/0_stateless/01188_attach_table_from_path.sql index 5b99c07e986..9bf401c8ea4 100644 --- a/tests/queries/0_stateless/01188_attach_table_from_path.sql +++ b/tests/queries/0_stateless/01188_attach_table_from_path.sql @@ -7,6 +7,7 @@ drop table if exists mt; attach table test from 'some/path' (n UInt8) engine=Memory; -- { serverError 48 } attach table test from '/etc/passwd' (s String) engine=File(TSVRaw); -- { serverError 481 } attach table test from '../../../../../../../../../etc/passwd' (s String) engine=File(TSVRaw); -- { serverError 481 } +attach table test from 42 (s String) engine=File(TSVRaw); -- { clientError 62 } insert into table function file('01188_attach/file/data.TSV', 'TSV', 's String, n UInt8') values ('file', 42); attach table file from '01188_attach/file' (s String, n UInt8) engine=File(TSV); From d24bfce93fda2d35360213adc3f90936d8cab010 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 7 Oct 2021 17:03:54 +0300 Subject: [PATCH 054/264] Add coroutines example. --- src/Core/examples/CMakeLists.txt | 3 + src/Core/examples/coro.cpp | 202 +++++++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 src/Core/examples/coro.cpp diff --git a/src/Core/examples/CMakeLists.txt b/src/Core/examples/CMakeLists.txt index 6b07dfbbfa6..c8846eb1743 100644 --- a/src/Core/examples/CMakeLists.txt +++ b/src/Core/examples/CMakeLists.txt @@ -13,3 +13,6 @@ target_link_libraries (mysql_protocol PRIVATE dbms) if(USE_SSL) target_include_directories (mysql_protocol SYSTEM PRIVATE ${OPENSSL_INCLUDE_DIR}) endif() + +add_executable (coro coro.cpp) +target_link_libraries (coro PRIVATE clickhouse_common_io) diff --git a/src/Core/examples/coro.cpp b/src/Core/examples/coro.cpp new file mode 100644 index 00000000000..c8e2f7418e4 --- /dev/null +++ b/src/Core/examples/coro.cpp @@ -0,0 +1,202 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(__clang__) + +#include + +template +using coroutine_handle = std::experimental::coroutine_handle; + +using default_coroutine_handle = std::experimental::coroutine_handle<>; + +using suspend_never = std::experimental::suspend_never; +using suspend_always = std::experimental::suspend_always; + +#else + +#include + +template +using coroutine_handle = std::coroutine_handle; + +using default_coroutine_handle = std::coroutine_handle<>; + +using suspend_never = std::suspend_never; +using suspend_always = std::suspend_always; + +#endif + + +template +struct suspend_never_val +{ + constexpr bool await_ready() const noexcept { return true; } + constexpr void await_suspend(default_coroutine_handle) const noexcept {} + constexpr T await_resume() const noexcept + { + std::cout << " ret " << val << std::endl; + return val; + } + + T val; +}; + +template +struct resumable +{ + struct promise_type + { + using coro_handle = coroutine_handle; + auto get_return_object() { return coro_handle::from_promise(*this); } + auto initial_suspend() { return suspend_never(); } + auto final_suspend() noexcept { return suspend_never_val{*r->value}; } + //void return_void() {} + void return_value(T value_) { r->value = value_; } + void unhandled_exception() + { + DB::tryLogCurrentException("Logger"); + r->exception = std::current_exception(); + } + + explicit promise_type(std::string tag_) : tag(tag_) {} + ~promise_type() { std::cout << "~promise_type " << tag << std::endl; } + std::string tag; + coro_handle next; + resumable * r = nullptr; + }; + + using coro_handle = coroutine_handle; + + bool await_ready() const noexcept { return false; } + void await_suspend(coro_handle g) noexcept + { + std::cout << " await_suspend " << my.promise().tag << std::endl; + std::cout << " g tag " << g.promise().tag << std::endl; + g.promise().next = my; + } + T await_resume() noexcept + { + std::cout << " await_res " << my.promise().tag << std::endl; + return *value; + } + + resumable(coro_handle handle) : my(handle), tag(handle.promise().tag) + { + assert(handle); + my.promise().r = this; + std::cout << " resumable " << tag << std::endl; + } + resumable(resumable &) = delete; + resumable(resumable &&rhs) : my(rhs.my), tag(rhs.tag) + { + rhs.my = {}; + std::cout << " resumable&& " << tag << std::endl; + } + static bool resume_impl(resumable *r) + { + if (r->value) + return false; + + auto & next = r->my.promise().next; + + if (next) + { + if (resume_impl(next.promise().r)) + return true; + next = {}; + } + + if (!r->value) + { + r->my.resume(); + if (r->exception) + std::rethrow_exception(r->exception); + } + return !r->value; + } + + bool resume() + { + return resume_impl(this); + } + + T res() + { + return *value; + } + + ~resumable() + { + std::cout << " ~resumable " << tag << std::endl; + } + +private: + coro_handle my; + std::string tag; + std::optional value; + std::exception_ptr exception; +}; + +resumable boo(std::string tag) +{ + std::cout << "x" << std::endl; + co_await suspend_always(); + std::cout << StackTrace().toString(); + std::cout << "y" << std::endl; + co_return 1; +} + +resumable bar(std::string tag) +{ + std::cout << "a" << std::endl; + int res1 = co_await boo("boo1"); + std::cout << "b " << res1 << std::endl; + int res2 = co_await boo("boo2"); + if (res2 == 1) + throw DB::Exception(1, "hello"); + std::cout << "c " << res2 << std::endl; + co_return res1 + res2; // 1 + 1 = 2 +} + +resumable foo(std::string tag) { + std::cout << "Hello" << std::endl; + auto res1 = co_await bar("bar1"); + std::cout << "Coro " << res1 << std::endl; + auto res2 = co_await bar("bar2"); + std::cout << "World " << res2 << std::endl; + co_return res1 * res2; // 2 * 2 = 4 +} + +int main() +{ + Poco::AutoPtr app_channel(new Poco::ConsoleChannel(std::cerr)); + Poco::Logger::root().setChannel(app_channel); + Poco::Logger::root().setLevel("trace"); + + LOG_INFO(&Poco::Logger::get(""), "Starting"); + + try + { + auto t = foo("foo"); + std::cout << ".. started" << std::endl; + while (t.resume()) + std::cout << ".. yielded" << std::endl; + std::cout << ".. done: " << t.res() << std::endl; + } + catch (DB::Exception & e) + { + std::cout << "Got exception " << e.what() << std::endl; + std::cout << e.getStackTraceString() << std::endl; + } +} From 00fbf48a683ec009b26f0c47f931c7441013dbbe Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Thu, 7 Oct 2021 19:09:40 +0300 Subject: [PATCH 055/264] Minor fixes. --- docs/en/sql-reference/functions/geo/h3.md | 14 +++++++------- docs/ru/sql-reference/functions/geo/h3.md | 23 ++++++++++++----------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/docs/en/sql-reference/functions/geo/h3.md b/docs/en/sql-reference/functions/geo/h3.md index 410cb9d3cc2..048834806d1 100644 --- a/docs/en/sql-reference/functions/geo/h3.md +++ b/docs/en/sql-reference/functions/geo/h3.md @@ -40,7 +40,7 @@ Type: [UInt8](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT h3IsValid(630814730351855103) as h3IsValid; +SELECT h3IsValid(630814730351855103) AS h3IsValid; ``` Result: @@ -77,7 +77,7 @@ Type: [UInt8](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT h3GetResolution(639821929606596015) as resolution; +SELECT h3GetResolution(639821929606596015) AS resolution; ``` Result: @@ -111,7 +111,7 @@ h3EdgeAngle(resolution) Query: ``` sql -SELECT h3EdgeAngle(10) as edgeAngle; +SELECT h3EdgeAngle(10) AS edgeAngle; ``` Result: @@ -145,7 +145,7 @@ h3EdgeLengthM(resolution) Query: ``` sql -SELECT h3EdgeLengthM(15) as edgeLengthM; +SELECT h3EdgeLengthM(15) AS edgeLengthM; ``` Result: @@ -184,7 +184,7 @@ Type: [UInt64](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT geoToH3(37.79506683, 55.71290588, 15) as h3Index; +SELECT geoToH3(37.79506683, 55.71290588, 15) AS h3Index; ``` Result: @@ -333,7 +333,7 @@ Type: [UInt8](../../../sql-reference/data-types/int-uint.md). Query: ``` sql -SELECT h3GetBaseCell(612916788725809151) as basecell; +SELECT h3GetBaseCell(612916788725809151) AS basecell; ``` Result: @@ -369,7 +369,7 @@ Type: [Float64](../../../sql-reference/data-types/float.md). Query: ``` sql -SELECT h3HexAreaM2(13) as area; +SELECT h3HexAreaM2(13) AS area; ``` Result: diff --git a/docs/ru/sql-reference/functions/geo/h3.md b/docs/ru/sql-reference/functions/geo/h3.md index 6bc6943ec93..e85236848f6 100644 --- a/docs/ru/sql-reference/functions/geo/h3.md +++ b/docs/ru/sql-reference/functions/geo/h3.md @@ -38,7 +38,7 @@ h3IsValid(h3index) Запрос: ``` sql -SELECT h3IsValid(630814730351855103) as h3IsValid; +SELECT h3IsValid(630814730351855103) AS h3IsValid; ``` Результат: @@ -75,7 +75,7 @@ h3GetResolution(h3index) Запрос: ``` sql -SELECT h3GetResolution(639821929606596015) as resolution; +SELECT h3GetResolution(639821929606596015) AS resolution; ``` Результат: @@ -109,7 +109,7 @@ h3EdgeAngle(resolution) Запрос: ``` sql -SELECT h3EdgeAngle(10) as edgeAngle; +SELECT h3EdgeAngle(10) AS edgeAngle; ``` Результат: @@ -143,7 +143,7 @@ h3EdgeLengthM(resolution) Запрос: ``` sql -SELECT h3EdgeLengthM(15) as edgeLengthM; +SELECT h3EdgeLengthM(15) AS edgeLengthM; ``` Результат: @@ -182,7 +182,7 @@ geoToH3(lon, lat, resolution) Запрос: ``` sql -SELECT geoToH3(37.79506683, 55.71290588, 15) as h3Index; +SELECT geoToH3(37.79506683, 55.71290588, 15) AS h3Index; ``` Результат: @@ -295,7 +295,7 @@ h3GetBaseCell(index) Запрос: ``` sql -SELECT h3GetBaseCell(612916788725809151) as basecell; +SELECT h3GetBaseCell(612916788725809151) AS basecell; ``` Результат: @@ -329,7 +329,7 @@ h3HexAreaM2(resolution) Запрос: ``` sql -SELECT h3HexAreaM2(13) as area; +SELECT h3HexAreaM2(13) AS area; ``` Результат: @@ -441,7 +441,7 @@ h3ToParent(index, resolution) Запрос: ``` sql -SELECT h3ToParent(599405990164561919, 3) as parent; +SELECT h3ToParent(599405990164561919, 3) AS parent; ``` Результат: @@ -475,7 +475,7 @@ h3ToString(index) Запрос: ``` sql -SELECT h3ToString(617420388352917503) as h3_string; +SELECT h3ToString(617420388352917503) AS h3_string; ``` Результат: @@ -512,7 +512,7 @@ stringToH3(index_str) Запрос: ``` sql -SELECT stringToH3('89184926cc3ffff') as index; +SELECT stringToH3('89184926cc3ffff') AS index; ``` Результат: @@ -667,5 +667,6 @@ SELECT h3GetFaces(599686042433355775) AS faces; ┌─faces─┐ │ [7] │ └───────┘ +``` -[Оригинальная статья](https://clickhouse.com/docs/ru/sql-reference/functions/geo/h3/) +[Оригинальная статья](https://clickhouse.com/docs/ru/sql-reference/functions/geo/h3) From 1df9afb47cf5204be24edbe0e8c8c631ea1e759f Mon Sep 17 00:00:00 2001 From: michon470 <71978106+michon470@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:27:22 +0300 Subject: [PATCH 056/264] Update docs/en/sql-reference/statements/alter/column.md Co-authored-by: Anna <42538400+adevyatova@users.noreply.github.com> --- docs/en/sql-reference/statements/alter/column.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/statements/alter/column.md b/docs/en/sql-reference/statements/alter/column.md index 31874ef208d..ef4b88af6ba 100644 --- a/docs/en/sql-reference/statements/alter/column.md +++ b/docs/en/sql-reference/statements/alter/column.md @@ -204,7 +204,7 @@ Syntax: ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; ``` -**Example with the creation of new column:** +**Example** ```sql DROP TABLE IF EXISTS tmp; From fc0bccb0c6f6fec55800235fde76ef6669c5b5f9 Mon Sep 17 00:00:00 2001 From: michon470 <71978106+michon470@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:27:39 +0300 Subject: [PATCH 057/264] Update docs/ru/sql-reference/statements/alter/column.md Co-authored-by: Anna <42538400+adevyatova@users.noreply.github.com> --- docs/ru/sql-reference/statements/alter/column.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/statements/alter/column.md b/docs/ru/sql-reference/statements/alter/column.md index 366caf6a2a0..5ab7207c580 100644 --- a/docs/ru/sql-reference/statements/alter/column.md +++ b/docs/ru/sql-reference/statements/alter/column.md @@ -196,7 +196,7 @@ ALTER TABLE table_with_ttl MODIFY COLUMN column_ttl REMOVE TTL; ## MATERIALIZE COLUMN {#materialize-column} -С помощью этого запроса можно сделать столбец таблицы материализованным (`MATERIALIZED`) в его частях, у которых отсутствуют значения. Это полезно, если необходимо создать новый столбец со сложным материализованным выражением или выражением для заполнения по умолчанию (`DEFAULT`). Если вычисление такого столбца прямо во время выполнения запроса `SELECT` оказывается ощутимо большим, для него может оказаться целесообразным использовать `MATERIALIZE COLUMN`. Чтобы совершить ту же операцию для существующего столбца, используйте модификатор `FINAL`, как показано ниже. +Материализует столбец таблицы в кусках, в которых отсутствуют значения. Используется, если необходимо создать новый столбец со сложным материализованным выражением или выражением для заполнения по умолчанию (`DEFAULT`), потому как вычисление такого столбца прямо во время выполнения запроса `SELECT` оказывается ощутимо затратным. Чтобы совершить ту же операцию для существующего столбца, используйте модификатор `FINAL`. Синтаксис: From 0eaf2f12a31e1ed0f9dff5bfcd2059123541603f Mon Sep 17 00:00:00 2001 From: michon470 <71978106+michon470@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:27:46 +0300 Subject: [PATCH 058/264] Update docs/ru/sql-reference/statements/alter/column.md Co-authored-by: Anna <42538400+adevyatova@users.noreply.github.com> --- docs/ru/sql-reference/statements/alter/column.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/statements/alter/column.md b/docs/ru/sql-reference/statements/alter/column.md index 5ab7207c580..c6269f0eb62 100644 --- a/docs/ru/sql-reference/statements/alter/column.md +++ b/docs/ru/sql-reference/statements/alter/column.md @@ -204,7 +204,7 @@ ALTER TABLE table_with_ttl MODIFY COLUMN column_ttl REMOVE TTL; ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; ``` -**Пример использования при создании нового столбца:** +**Пример** ```sql DROP TABLE IF EXISTS tmp; From c030756c38f75deaf0c3fd9e00c762e376d515c3 Mon Sep 17 00:00:00 2001 From: michon470 <71978106+michon470@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:28:02 +0300 Subject: [PATCH 059/264] Update docs/en/sql-reference/statements/alter/column.md Co-authored-by: Anna <42538400+adevyatova@users.noreply.github.com> --- docs/en/sql-reference/statements/alter/column.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/sql-reference/statements/alter/column.md b/docs/en/sql-reference/statements/alter/column.md index ef4b88af6ba..aee3823bc05 100644 --- a/docs/en/sql-reference/statements/alter/column.md +++ b/docs/en/sql-reference/statements/alter/column.md @@ -196,7 +196,7 @@ ALTER TABLE table_with_ttl MODIFY COLUMN column_ttl REMOVE TTL; ## MATERIALIZE COLUMN {#materialize-column} -Materializes the column in the parts where the column is missing. This is useful in case of creating a new column with complicated `DEFAULT` or `MATERIALIZED` expression. Calculation of the column directly on `SELECT` query can cause bigger request execution time, so it is reasonable to use `MATERIALIZE COLUMN` for such columns. To perform same manipulation for existing column, use `FINAL` modifier as shown below. +Materializes the column in the parts where the column is missing. This is useful in case of creating a new column with complicated `DEFAULT` or `MATERIALIZED` expression. Calculation of the column directly on `SELECT` query can cause bigger request execution time, so it is reasonable to use `MATERIALIZE COLUMN` for such columns. To perform same manipulation for existing column, use `FINAL` modifier. Syntax: From 76e3ef686a244d13cbc37249ae260873ed36fae2 Mon Sep 17 00:00:00 2001 From: michon470 <71978106+michon470@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:28:12 +0300 Subject: [PATCH 060/264] Update docs/ru/sql-reference/statements/alter/column.md Co-authored-by: Anna <42538400+adevyatova@users.noreply.github.com> --- docs/ru/sql-reference/statements/alter/column.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/statements/alter/column.md b/docs/ru/sql-reference/statements/alter/column.md index c6269f0eb62..ef3d98fc10e 100644 --- a/docs/ru/sql-reference/statements/alter/column.md +++ b/docs/ru/sql-reference/statements/alter/column.md @@ -25,7 +25,7 @@ ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|RENAME|CLEAR|COMMENT|MODIFY| - [COMMENT COLUMN](#alter_comment-column) — добавляет комментарий к столбцу; - [MODIFY COLUMN](#alter_modify-column) — изменяет тип столбца, выражение для значения по умолчанию и TTL; - [MODIFY COLUMN REMOVE](#modify-remove) — удаляет какое-либо из свойств столбца; -- [MATERIALIZE COLUMN](#materialize-column) — делает столбец материализованным (MATERIALIZED) в его частях, у которых отсутствуют значения. +- [MATERIALIZE COLUMN](#materialize-column) — делает столбец материализованным (`MATERIALIZED`) в кусках, в которых отсутствуют значения. Подробное описание для каждого действия приведено ниже. From 9389cb7c7702574dcf6224ef0e7c4d83e7a30896 Mon Sep 17 00:00:00 2001 From: Mikhail <71978106+michon470@users.noreply.github.com> Date: Thu, 7 Oct 2021 22:31:44 +0300 Subject: [PATCH 061/264] Example corrected --- docs/en/sql-reference/statements/alter/column.md | 8 ++++---- docs/ru/sql-reference/statements/alter/column.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/en/sql-reference/statements/alter/column.md b/docs/en/sql-reference/statements/alter/column.md index aee3823bc05..4eb251b88cd 100644 --- a/docs/en/sql-reference/statements/alter/column.md +++ b/docs/en/sql-reference/statements/alter/column.md @@ -210,7 +210,7 @@ ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; DROP TABLE IF EXISTS tmp; SET mutations_sync = 2; CREATE TABLE tmp (x Int64) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY tuple(); -INSERT INTO tmp SELECT * FROM system.numbers LIMIT 20; +INSERT INTO tmp SELECT * FROM system.numbers LIMIT 10; ALTER TABLE tmp ADD COLUMN s String MATERIALIZED toString(x); SELECT groupArray(x), groupArray(s) FROM tmp; ``` @@ -218,9 +218,9 @@ SELECT groupArray(x), groupArray(s) FROM tmp; **Result:** ```sql -┌─groupArray(x)───────────────────────────────────────┬─groupArray(s)───────────────────────────────────────────────────────────────────────────────┐ -│ [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] │ ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19'] │ -└─────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘ +┌─groupArray(x)─────────┬─groupArray(s)─────────────────────────────┐ +│ [0,1,2,3,4,5,6,7,8,9] │ ['0','1','2','3','4','5','6','7','8','9'] │ +└───────────────────────┴───────────────────────────────────────────┘ ``` **See Also** diff --git a/docs/ru/sql-reference/statements/alter/column.md b/docs/ru/sql-reference/statements/alter/column.md index ef3d98fc10e..bfd52801210 100644 --- a/docs/ru/sql-reference/statements/alter/column.md +++ b/docs/ru/sql-reference/statements/alter/column.md @@ -210,7 +210,7 @@ ALTER TABLE table MATERIALIZE COLUMN col [FINAL]; DROP TABLE IF EXISTS tmp; SET mutations_sync = 2; CREATE TABLE tmp (x Int64) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY tuple(); -INSERT INTO tmp SELECT * FROM system.numbers LIMIT 20; +INSERT INTO tmp SELECT * FROM system.numbers LIMIT 10; ALTER TABLE tmp ADD COLUMN s String MATERIALIZED toString(x); SELECT groupArray(x), groupArray(s) FROM tmp; ``` @@ -218,9 +218,9 @@ SELECT groupArray(x), groupArray(s) FROM tmp; **Результат:** ```sql -┌─groupArray(x)───────────────────────────────────────┬─groupArray(s)───────────────────────────────────────────────────────────────────────────────┐ -│ [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] │ ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19'] │ -└─────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────┘ +┌─groupArray(x)─────────┬─groupArray(s)─────────────────────────────┐ +│ [0,1,2,3,4,5,6,7,8,9] │ ['0','1','2','3','4','5','6','7','8','9'] │ +└───────────────────────┴───────────────────────────────────────────┘ ``` ## Ограничения запроса ALTER {#ogranicheniia-zaprosa-alter} From c734ada95ba7d5f13591acd32edb38f716784f64 Mon Sep 17 00:00:00 2001 From: kssenii Date: Thu, 7 Oct 2021 20:26:58 +0000 Subject: [PATCH 062/264] Fix --- src/Client/ClientBase.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index cde5a5f9977..b68df11fd60 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -426,10 +426,8 @@ void ClientBase::processTextAsSingleQuery(const String & full_query) catch (Exception & e) { if (!is_interactive) - { e.addMessage("(in query: {})", full_query); - throw; - } + throw; } if (have_error) From e07a6f3fc0ea0b496483287d85b50d29f5a8c330 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 7 Oct 2021 21:09:35 +0300 Subject: [PATCH 063/264] docker: add pandas/clickhouse_driver into test images --- docker/test/fasttest/Dockerfile | 2 +- docker/test/fuzzer/Dockerfile | 2 +- docker/test/stateless/Dockerfile | 2 +- docker/test/style/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/test/fasttest/Dockerfile b/docker/test/fasttest/Dockerfile index 798910fb952..f50c65bb9f2 100644 --- a/docker/test/fasttest/Dockerfile +++ b/docker/test/fasttest/Dockerfile @@ -67,7 +67,7 @@ RUN apt-get update \ unixodbc \ --yes --no-install-recommends -RUN pip3 install numpy scipy pandas Jinja2 +RUN pip3 install numpy scipy pandas Jinja2 pandas clickhouse_driver # This symlink required by gcc to find lld compiler RUN ln -s /usr/bin/lld-${LLVM_VERSION} /usr/bin/ld.lld diff --git a/docker/test/fuzzer/Dockerfile b/docker/test/fuzzer/Dockerfile index 6444e745c47..13353bc2960 100644 --- a/docker/test/fuzzer/Dockerfile +++ b/docker/test/fuzzer/Dockerfile @@ -27,7 +27,7 @@ RUN apt-get update \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* -RUN pip3 install Jinja2 +RUN pip3 install Jinja2 pandas clickhouse_driver COPY * / diff --git a/docker/test/stateless/Dockerfile b/docker/test/stateless/Dockerfile index 7de8c061673..a5733d11dd2 100644 --- a/docker/test/stateless/Dockerfile +++ b/docker/test/stateless/Dockerfile @@ -34,7 +34,7 @@ RUN apt-get update -y \ postgresql-client \ sqlite3 -RUN pip3 install numpy scipy pandas Jinja2 +RUN pip3 install numpy scipy pandas Jinja2 clickhouse_driver RUN mkdir -p /tmp/clickhouse-odbc-tmp \ && wget -nv -O - ${odbc_driver_url} | tar --strip-components=1 -xz -C /tmp/clickhouse-odbc-tmp \ diff --git a/docker/test/style/Dockerfile b/docker/test/style/Dockerfile index 33cdb9db57a..64cc0c9c7b7 100644 --- a/docker/test/style/Dockerfile +++ b/docker/test/style/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install --yes \ python3-pip \ pylint \ yamllint \ - && pip3 install codespell + && pip3 install codespell pandas clickhouse_driver COPY run.sh / COPY process_style_check_result.py / From 9dd0fca1edd383c00667ce4c1a953e4f6d2bca1a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 7 Oct 2021 23:45:18 +0300 Subject: [PATCH 064/264] Suppress some existed warnings in clickhouse-test (will be fixed separately) --- tests/clickhouse-test | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/clickhouse-test b/tests/clickhouse-test index 19080f3934f..2c8093190ea 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -1,6 +1,12 @@ #!/usr/bin/env python3 # pylint: disable=too-many-return-statements +# pylint: disable=consider-using-f-string +# pylint: disable=global-variable-not-assigned +# pylint: disable=consider-using-with +# pylint: disable=unspecified-encoding +# pylint: disable=consider-using-min-builtin + import enum import shutil import sys From df129d7efc70eb2abc394b72a0dd64c421de8549 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 7 Oct 2021 21:05:42 +0300 Subject: [PATCH 065/264] Rewrite clickhouse-test to use python clickhouse_driver Pros: - Using native protocol over executing binaries is always better - `clickhouse-client` in debug build takes almost a second to execute simple `SELECT 1` and `clickhouse-test` requires ~5 queries at start (determine some flags, zk, alive, create database) Notes: - `FORMAT Vertical` had been replaced with printing of `pandas.DataFrame` And after this patch tiny tests work with the speed of the test, and does not requires +-5 seconds of bootstrapping. --- tests/clickhouse-test | 424 +++++++++++++++++++----------------------- 1 file changed, 193 insertions(+), 231 deletions(-) diff --git a/tests/clickhouse-test b/tests/clickhouse-test index 2c8093190ea..e8c85a6ae79 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -19,13 +19,10 @@ import traceback import math from argparse import ArgumentParser -from typing import Tuple, Union, Optional, TextIO, Dict, Set, List -import shlex +from typing import Tuple, Union, Optional, Dict, Set, List import subprocess from subprocess import Popen from subprocess import PIPE -from subprocess import CalledProcessError -from subprocess import TimeoutExpired from datetime import datetime from time import time, sleep from errno import ESRCH @@ -41,6 +38,9 @@ import multiprocessing import socket from contextlib import closing +import clickhouse_driver +import pandas + USE_JINJA = True try: import jinja2 @@ -48,20 +48,45 @@ except ImportError: USE_JINJA = False print('WARNING: jinja2 not installed! Template tests will be skipped.') -DISTRIBUTED_DDL_TIMEOUT_MSG = "is executing longer than distributed_ddl_task_timeout" - MESSAGES_TO_RETRY = [ "ConnectionPoolWithFailover: Connection failed at try", "DB::Exception: New table appeared in database being dropped or detached. Try again", "is already started to be removing by another replica right now", "DB::Exception: Cannot enqueue query", - DISTRIBUTED_DDL_TIMEOUT_MSG # FIXME + "is executing longer than distributed_ddl_task_timeout" # FIXME +] +error_codes = clickhouse_driver.errors.ErrorCodes +error_codes.NOT_A_LEADER = 529 +ERROR_CODES_TO_RETRY = [ + error_codes.ALL_CONNECTION_TRIES_FAILED, + error_codes.DATABASE_NOT_EMPTY, + error_codes.NOT_A_LEADER, + error_codes.UNFINISHED, ] MAX_RETRIES = 3 TEST_FILE_EXTENSIONS = ['.sql', '.sql.j2', '.sh', '.py', '.expect'] +class Client(clickhouse_driver.Client): + # return first column of the first row + def execute_one(self, *args, **kwargs): + return super().execute(*args, **kwargs)[0][0] + + # return pandas.DataFrame + def execute_pandas(self, *args, **kwargs): + data = super().execute(*args, **kwargs, with_column_types=True) + return Client.__combine(data) + + @staticmethod + def __combine(data): + cols = data[1] + rows = data[0] + header = [ i[0] for i in cols ] + data = pandas.DataFrame(data=rows, columns=header) + return data + + class Terminated(KeyboardInterrupt): pass @@ -103,18 +128,16 @@ def get_db_engine(args, database_name): def get_zookeeper_session_uptime(args): + global clickhouse_client + try: - query = b"SELECT zookeeperSessionUptime()" - if args.replicated_database: - query = b"SELECT min(materialize(zookeeperSessionUptime())) " \ - b"FROM clusterAllReplicas('test_cluster_database_replicated', system.one) " - - clickhouse_proc = open_client_process(args.client) - - (stdout, _) = clickhouse_proc.communicate((query), timeout=20) - - return int(stdout.decode('utf-8').strip()) + return int(clickhouse_client.execute_one(""" + SELECT min(materialize(zookeeperSessionUptime())) + FROM clusterAllReplicas('test_cluster_database_replicated', system.one) + """)) + else: + return int(clickhouse_client.execute_one('SELECT zookeeperSessionUptime()')) except: return None @@ -128,24 +151,31 @@ def need_retry(args, stdout, stderr, total_time): return True return any(msg in stdout for msg in MESSAGES_TO_RETRY) or any(msg in stderr for msg in MESSAGES_TO_RETRY) +def need_retry_error(args, error, total_time): + # Sometimes we may get unexpected exception like "Replica is readonly" or "Shutdown is called for table" + # instead of "Session expired" or "Connection loss" + # Retry if session was expired during test execution + session_uptime = get_zookeeper_session_uptime(args) + if session_uptime is not None and session_uptime < math.ceil(total_time): + return True + if isinstance(error, clickhouse_driver.errors.Error): + if error.code in ERROR_CODES_TO_RETRY: + return True + if any(msg in error.message for msg in MESSAGES_TO_RETRY): + return True + return False + def get_processlist(args): - try: - query = b"SHOW PROCESSLIST FORMAT Vertical" - - if args.replicated_database: - query = b"SELECT materialize((hostName(), tcpPort())) as host, * " \ - b"FROM clusterAllReplicas('test_cluster_database_replicated', system.processes) " \ - b"WHERE query NOT LIKE '%system.processes%' FORMAT Vertical" - - clickhouse_proc = open_client_process(args.client) - - (stdout, _) = clickhouse_proc.communicate((query), timeout=20) - - return False, stdout.decode('utf-8') - except Exception as ex: - print("Exception", ex) - return True, "" + global clickhouse_client + if args.replicated_database: + return clickhouse_client.execute_pandas(""" + SELECT materialize((hostName(), tcpPort())) as host, * + FROM clusterAllReplicas('test_cluster_database_replicated', system.processes) + WHERE query NOT LIKE '%system.processes%' + """) + else: + return clickhouse_client.execute_pandas('SHOW PROCESSLIST') # collect server stacktraces using gdb @@ -311,7 +341,8 @@ class TestCase: return None @staticmethod - def configure_testcase_args(args, case_file, suite_tmp_dir, stderr_file): + def configure_testcase_args(args, case_file, suite_tmp_dir): + global clickhouse_client testcase_args = copy.deepcopy(args) testcase_args.testcase_start_time = datetime.now() @@ -331,23 +362,11 @@ class TestCase: database = 'test_{suffix}'.format(suffix=random_str()) - with open(stderr_file, 'w') as stderr: - client_cmd = testcase_args.testcase_client + " " \ - + get_additional_client_options(args) - - clickhouse_proc_create = open_client_process( - universal_newlines=True, - client_args=client_cmd, - stderr_file=stderr) - - try: - clickhouse_proc_create.communicate( - ("CREATE DATABASE " + database + get_db_engine(testcase_args, database)), - timeout=testcase_args.timeout) - except TimeoutExpired: - total_time = (datetime.now() - testcase_args.testcase_start_time).total_seconds() - return clickhouse_proc_create, "", "Timeout creating database {} before test".format( - database), total_time + try: + clickhouse_client.execute("CREATE DATABASE " + database + get_db_engine(testcase_args, database), settings={'log_comment': testcase_basename}) + except (TimeoutError, clickhouse_driver.errors.SocketTimeoutError): + total_time = (datetime.now() - testcase_args.testcase_start_time).total_seconds() + return None, "", f"Timeout creating database {database} before test", total_time os.environ["CLICKHOUSE_DATABASE"] = database # Set temporary directory to match the randomly generated database, @@ -418,41 +437,42 @@ class TestCase: def process_result_impl(self, proc, stdout: str, stderr: str, total_time: float): description = "" - if proc.returncode is None: - try: - proc.kill() - except OSError as e: - if e.errno != ESRCH: - raise + if proc: + if proc.returncode is None: + try: + proc.kill() + except OSError as e: + if e.errno != ESRCH: + raise - if stderr: - description += stderr - return TestResult(self.name, TestStatus.FAIL, FailureReason.TIMEOUT, total_time, description) + if stderr: + description += stderr + return TestResult(self.name, TestStatus.FAIL, FailureReason.TIMEOUT, total_time, description) - if proc.returncode != 0: - reason = FailureReason.EXIT_CODE - description += str(proc.returncode) + if proc.returncode != 0: + reason = FailureReason.EXIT_CODE + description += str(proc.returncode) - if stderr: - description += "\n" - description += stderr + if stderr: + description += "\n" + description += stderr - # Stop on fatal errors like segmentation fault. They are sent to client via logs. - if ' ' in stderr: - reason = FailureReason.SERVER_DIED + # Stop on fatal errors like segmentation fault. They are sent to client via logs. + if ' ' in stderr: + reason = FailureReason.SERVER_DIED - if self.testcase_args.stop \ - and ('Connection refused' in stderr or 'Attempt to read after eof' in stderr) \ - and 'Received exception from server' not in stderr: - reason = FailureReason.SERVER_DIED + if self.testcase_args.stop \ + and ('Connection refused' in stderr or 'Attempt to read after eof' in stderr) \ + and 'Received exception from server' not in stderr: + reason = FailureReason.SERVER_DIED - if os.path.isfile(self.stdout_file): - description += ", result:\n\n" - description += '\n'.join(open(self.stdout_file).read().split('\n')[:100]) - description += '\n' + if os.path.isfile(self.stdout_file): + description += ", result:\n\n" + description += '\n'.join(open(self.stdout_file).read().split('\n')[:100]) + description += '\n' - description += "\nstdout:\n{}\n".format(stdout) - return TestResult(self.name, TestStatus.FAIL, reason, total_time, description) + description += "\nstdout:\n{}\n".format(stdout) + return TestResult(self.name, TestStatus.FAIL, reason, total_time, description) if stderr: description += "\n{}\n".format('\n'.join(stderr.split('\n')[:100])) @@ -516,21 +536,12 @@ class TestCase: @staticmethod def send_test_name_failed(suite: str, case: str) -> bool: - clickhouse_proc = open_client_process(args.client, universal_newlines=True) - - failed_to_check = False - + global clickhouse_client pid = os.getpid() - query = f"SELECT 'Running test {suite}/{case} from pid={pid}';" - - try: - clickhouse_proc.communicate((query), timeout=20) - except: - failed_to_check = True - - return failed_to_check or clickhouse_proc.returncode != 0 + clickhouse_client.execute(f"SELECT 'Running test {suite}/{case} from pid={pid}'") def run_single_test(self, server_logs_level, client_options): + global clickhouse_client args = self.testcase_args client = args.testcase_client start_time = args.testcase_start_time @@ -572,28 +583,13 @@ class TestCase: need_drop_database = not maybe_passed if need_drop_database: - with open(self.stderr_file, 'a') as stderr: - clickhouse_proc_create = open_client_process(client, universal_newlines=True, stderr_file=stderr) - seconds_left = max(args.timeout - (datetime.now() - start_time).total_seconds(), 20) - try: - drop_database_query = "DROP DATABASE " + database - if args.replicated_database: - drop_database_query += " ON CLUSTER test_cluster_database_replicated" - clickhouse_proc_create.communicate((drop_database_query), timeout=seconds_left) - except TimeoutExpired: - # kill test process because it can also hung - if proc.returncode is None: - try: - proc.kill() - except OSError as e: - if e.errno != ESRCH: - raise - + with clickhouse_client.connection.timeout_setter(seconds_left): + clickhouse_client.execute("DROP DATABASE " + database) + except (TimeoutError, clickhouse_driver.errors.SocketTimeoutError): total_time = (datetime.now() - start_time).total_seconds() - return clickhouse_proc_create, "", f"Timeout dropping database {database} after test", total_time - + return None, "", f"Timeout dropping database {database} after test", total_time shutil.rmtree(args.test_tmp_dir) total_time = (datetime.now() - start_time).total_seconds() @@ -624,12 +620,15 @@ class TestCase: if skip_reason is not None: return TestResult(self.name, TestStatus.SKIPPED, skip_reason, 0., "") - if args.testname and self.send_test_name_failed(suite.suite, self.case): - description = "\nServer does not respond to health check\n" - return TestResult(self.name, TestStatus.FAIL, FailureReason.SERVER_DIED, 0., description) + if args.testname: + try: + self.send_test_name_failed(suite.suite, self.case) + except: + return TestResult(self.name, TestStatus.FAIL, FailureReason.SERVER_DIED, 0., + "\nServer does not respond to health check\n") self.runs_count += 1 - self.testcase_args = self.configure_testcase_args(args, self.case_file, suite.suite_tmp_path, self.stderr_file) + self.testcase_args = self.configure_testcase_args(args, self.case_file, suite.suite_tmp_path) proc, stdout, stderr, total_time = self.run_single_test(server_logs_level, client_options) result = self.process_result_impl(proc, stdout, stderr, total_time) @@ -794,12 +793,8 @@ class TestSuite: @staticmethod def readTestSuite(args, suite_dir_name: str): def is_data_present(): - clickhouse_proc = open_client_process(args.client) - (stdout, stderr) = clickhouse_proc.communicate(b"EXISTS TABLE test.hits") - if clickhouse_proc.returncode != 0: - raise CalledProcessError(clickhouse_proc.returncode, args.client, stderr) - - return stdout.startswith(b'1') + global clickhouse_client + return int(clickhouse_client.execute_one('EXISTS TABLE test.hits')) base_dir = os.path.abspath(args.queries) tmp_dir = os.path.abspath(args.tmp) @@ -832,6 +827,7 @@ class TestSuite: stop_time = None +clickhouse_client = None exit_code = None server_died = None stop_tests_triggered_lock = None @@ -961,42 +957,26 @@ def run_tests_array(all_tests_with_params): server_logs_level = "warning" -def check_server_started(client, retry_count): +def check_server_started(retry_count): + global clickhouse_client print("Connecting to ClickHouse server...", end='') sys.stdout.flush() - while retry_count > 0: - clickhouse_proc = open_client_process(client) - (stdout, stderr) = clickhouse_proc.communicate(b"SELECT 1") - - if clickhouse_proc.returncode == 0 and stdout.startswith(b"1"): + try: + clickhouse_client.execute('SELECT 1') print(" OK") sys.stdout.flush() return True - - if clickhouse_proc.returncode == 210: - # Connection refused, retry + except (ConnectionRefusedError, ConnectionResetError, clickhouse_driver.errors.NetworkError): print('.', end='') sys.stdout.flush() retry_count -= 1 sleep(0.5) continue - code: int = clickhouse_proc.returncode - - print(f"\nClient invocation failed with code {code}:\n\ - stdout: {stdout}\n\ - stderr: {stderr}\n\ - args: {''.join(clickhouse_proc.args)}\n") - - sys.stdout.flush() - - return False - print('\nAll connection tries failed') sys.stdout.flush() - return False @@ -1012,60 +992,38 @@ class BuildFlags(): POLYMORPHIC_PARTS = 'polymorphic-parts' -def collect_build_flags(client): - clickhouse_proc = open_client_process(client) - (stdout, stderr) = clickhouse_proc.communicate(b"SELECT value FROM system.build_options WHERE name = 'CXX_FLAGS'") +def collect_build_flags(): + global clickhouse_client + result = [] - if clickhouse_proc.returncode == 0: - if b'-fsanitize=thread' in stdout: - result.append(BuildFlags.THREAD) - elif b'-fsanitize=address' in stdout: - result.append(BuildFlags.ADDRESS) - elif b'-fsanitize=undefined' in stdout: - result.append(BuildFlags.UNDEFINED) - elif b'-fsanitize=memory' in stdout: - result.append(BuildFlags.MEMORY) - else: - raise Exception("Cannot get information about build from server errorcode {}, stderr {}".format(clickhouse_proc.returncode, stderr)) + value = clickhouse_client.execute_one("SELECT value FROM system.build_options WHERE name = 'CXX_FLAGS'") + if '-fsanitize=thread' in value: + result.append(BuildFlags.THREAD) + elif '-fsanitize=address' in value: + result.append(BuildFlags.ADDRESS) + elif '-fsanitize=undefined' in value: + result.append(BuildFlags.UNDEFINED) + elif '-fsanitize=memory' in value: + result.append(BuildFlags.MEMORY) - clickhouse_proc = open_client_process(client) - (stdout, stderr) = clickhouse_proc.communicate(b"SELECT value FROM system.build_options WHERE name = 'BUILD_TYPE'") + value = clickhouse_client.execute_one("SELECT value FROM system.build_options WHERE name = 'BUILD_TYPE'") + if 'Debug' in value: + result.append(BuildFlags.DEBUG) + elif 'RelWithDebInfo' in value or 'Release' in value: + result.append(BuildFlags.RELEASE) - if clickhouse_proc.returncode == 0: - if b'Debug' in stdout: - result.append(BuildFlags.DEBUG) - elif b'RelWithDebInfo' in stdout or b'Release' in stdout: - result.append(BuildFlags.RELEASE) - else: - raise Exception("Cannot get information about build from server errorcode {}, stderr {}".format(clickhouse_proc.returncode, stderr)) + value = clickhouse_client.execute_one("SELECT value FROM system.build_options WHERE name = 'UNBUNDLED'") + if value in ('ON', '1'): + result.append(BuildFlags.UNBUNDLED) - clickhouse_proc = open_client_process(client) - (stdout, stderr) = clickhouse_proc.communicate(b"SELECT value FROM system.build_options WHERE name = 'UNBUNDLED'") + value = clickhouse_client.execute_one("SELECT value FROM system.settings WHERE name = 'default_database_engine'") + if value == 'Ordinary': + result.append(BuildFlags.ORDINARY_DATABASE) - if clickhouse_proc.returncode == 0: - if b'ON' in stdout or b'1' in stdout: - result.append(BuildFlags.UNBUNDLED) - else: - raise Exception("Cannot get information about build from server errorcode {}, stderr {}".format(clickhouse_proc.returncode, stderr)) - - clickhouse_proc = open_client_process(client) - (stdout, stderr) = clickhouse_proc.communicate(b"SELECT value FROM system.settings WHERE name = 'default_database_engine'") - - if clickhouse_proc.returncode == 0: - if b'Ordinary' in stdout: - result.append(BuildFlags.ORDINARY_DATABASE) - else: - raise Exception("Cannot get information about build from server errorcode {}, stderr {}".format(clickhouse_proc.returncode, stderr)) - - clickhouse_proc = open_client_process(client) - (stdout, stderr) = clickhouse_proc.communicate(b"SELECT value FROM system.merge_tree_settings WHERE name = 'min_bytes_for_wide_part'") - - if clickhouse_proc.returncode == 0: - if stdout == b'0\n': - result.append(BuildFlags.POLYMORPHIC_PARTS) - else: - raise Exception("Cannot get inforamtion about build from server errorcode {}, stderr {}".format(clickhouse_proc.returncode, stderr)) + value = int(clickhouse_client.execute_one("SELECT value FROM system.merge_tree_settings WHERE name = 'min_bytes_for_wide_part'")) + if value == 0: + result.append(BuildFlags.POLYMORPHIC_PARTS) return result @@ -1092,16 +1050,6 @@ def extract_key(key: str) -> str: args.configserver + key)[1] -def open_client_process( - client_args: str, - universal_newlines: bool = False, - stderr_file: Optional[TextIO] = None): - return Popen( - shlex.split(client_args), stdin=PIPE, stdout=PIPE, - stderr=stderr_file if stderr_file is not None else PIPE, - universal_newlines=True if universal_newlines else None) - - def do_run_tests(jobs, test_suite: TestSuite, parallel): if jobs > 1 and len(test_suite.parallel_tests) > 0: print("Found", len(test_suite.parallel_tests), "parallel tests and", len(test_suite.sequential_tests), "sequential tests") @@ -1170,8 +1118,9 @@ def main(args): global exit_code global server_logs_level global restarted_tests + global clickhouse_client - if not check_server_started(args.client, args.server_check_retries): + if not check_server_started(args.server_check_retries): msg = "Server is not responding. Cannot execute 'SELECT 1' query. \ If you are using split build, you have to specify -c option." if args.hung_check: @@ -1181,13 +1130,12 @@ def main(args): print_stacktraces() raise Exception(msg) - args.build_flags = collect_build_flags(args.client) + args.build_flags = collect_build_flags() if args.skip: args.skip = set(args.skip) base_dir = os.path.abspath(args.queries) - tmp_dir = os.path.abspath(args.tmp) # Keep same default values as in queries/shell_config.sh os.environ.setdefault("CLICKHOUSE_BINARY", args.binary) @@ -1218,17 +1166,12 @@ def main(args): create_database_retries = 0 while create_database_retries < MAX_RETRIES: start_time = datetime.now() - - client_cmd = args.client + " " + get_additional_client_options(args) - - clickhouse_proc_create = open_client_process(client_cmd, universal_newlines=True) - - (stdout, stderr) = clickhouse_proc_create.communicate(("CREATE DATABASE IF NOT EXISTS " + db_name + get_db_engine(args, db_name))) - - total_time = (datetime.now() - start_time).total_seconds() - - if not need_retry(args, stdout, stderr, total_time): - break + try: + clickhouse_client.execute("CREATE DATABASE IF NOT EXISTS " + db_name + get_db_engine(args, db_name)) + except Exception as e: + total_time = (datetime.now() - start_time).total_seconds() + if not need_retry_error(args, e, total_time): + break create_database_retries += 1 if args.database and args.database != "test": @@ -1255,18 +1198,14 @@ def main(args): # Some queries may execute in background for some time after test was finished. This is normal. for _ in range(1, 60): - timeout, processlist = get_processlist(args) - if timeout or not processlist: + processlist = get_processlist(args) + if processlist.empty: break sleep(1) - if timeout or processlist: - if processlist: - print(colored("\nFound hung queries in processlist:", args, "red", attrs=["bold"])) - print(processlist) - else: - print(colored("Seems like server hung and cannot respond to queries", args, "red", attrs=["bold"])) - + if not processlist.empty: + print(colored("\nFound hung queries in processlist:", args, "red", attrs=["bold"])) + print(processlist) print_stacktraces() exit_code.value = 1 @@ -1311,16 +1250,20 @@ def find_binary(name): def get_additional_client_options(args): if args.client_option: return ' '.join('--' + option for option in args.client_option) - return '' - def get_additional_client_options_url(args): if args.client_option: return '&'.join(args.client_option) - return '' +def get_additional_client_options_dict(args): + settings = {} + if args.client_option: + for key, value in map(lambda x: x.split('='), args.client_option): + settings[key] = value + return settings + if __name__ == '__main__': stop_time = None @@ -1439,14 +1382,24 @@ if __name__ == '__main__': if args.configclient: args.client += ' --config-file=' + args.configclient - if os.getenv("CLICKHOUSE_HOST"): - args.client += ' --host=' + os.getenv("CLICKHOUSE_HOST") + tcp_host = os.getenv("CLICKHOUSE_HOST") + if tcp_host is not None: + args.client += f' --host={tcp_host}' + else: + tcp_host = 'localhost' - args.tcp_port = int(os.getenv("CLICKHOUSE_PORT_TCP", "9000")) - args.client += f" --port={args.tcp_port}" + tcp_port = os.getenv("CLICKHOUSE_PORT_TCP") + if tcp_port is not None: + args.tcp_port = int(tcp_port) + args.client += f" --port={tcp_port}" + else: + args.tcp_port = 9000 - if os.getenv("CLICKHOUSE_DATABASE"): - args.client += ' --database=' + os.getenv("CLICKHOUSE_DATABASE") + client_database = os.getenv("CLICKHOUSE_DATABASE") + if client_database is not None: + args.client += f' --database={client_database}' + else: + client_database = 'default' if args.client_option: # Set options for client @@ -1474,4 +1427,13 @@ if __name__ == '__main__': if args.jobs is None: args.jobs = multiprocessing.cpu_count() + # configure pandas to make it more like Vertical format + pandas.options.display.max_columns = None + pandas.options.display.width = None + + clickhouse_client = Client(host=tcp_host, + port=args.tcp_port, + database=client_database, + settings=get_additional_client_options_dict(args)) + main(args) From e2d6698244d43979b3fe2478dfdcd8dc3a91a0fd Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 8 Oct 2021 00:07:05 +0300 Subject: [PATCH 066/264] clickhouse-test: do not use persistent connection for simplicity (due to threads) --- tests/clickhouse-test | 77 +++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/tests/clickhouse-test b/tests/clickhouse-test index e8c85a6ae79..6bbfa97ab66 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -86,6 +86,17 @@ class Client(clickhouse_driver.Client): data = pandas.DataFrame(data=rows, columns=header) return data +# Helpers +def make_clickhouse_client(base_args, *args, **kwargs): + return Client(host=base_args.tcp_host, port=base_args.tcp_port, + settings=get_additional_client_options_dict(base_args)) +def clickhouse_execute_one(base_args, *args, **kwargs): + return make_clickhouse_client(base_args).execute_one(*args, **kwargs) +def clickhouse_execute(base_args, *args, **kwargs): + return make_clickhouse_client(base_args).execute(*args, **kwargs) +def clickhouse_execute_pandas(base_args, *args, **kwargs): + return make_clickhouse_client(base_args).execute_pandas(*args, **kwargs) + class Terminated(KeyboardInterrupt): pass @@ -128,16 +139,14 @@ def get_db_engine(args, database_name): def get_zookeeper_session_uptime(args): - global clickhouse_client - try: if args.replicated_database: - return int(clickhouse_client.execute_one(""" + return int(clickhouse_execute_one(args, """ SELECT min(materialize(zookeeperSessionUptime())) FROM clusterAllReplicas('test_cluster_database_replicated', system.one) """)) else: - return int(clickhouse_client.execute_one('SELECT zookeeperSessionUptime()')) + return int(clickhouse_execute_one(args, 'SELECT zookeeperSessionUptime()')) except: return None @@ -167,15 +176,14 @@ def need_retry_error(args, error, total_time): def get_processlist(args): - global clickhouse_client if args.replicated_database: - return clickhouse_client.execute_pandas(""" + return clickhouse_execute_pandas(args, """ SELECT materialize((hostName(), tcpPort())) as host, * FROM clusterAllReplicas('test_cluster_database_replicated', system.processes) WHERE query NOT LIKE '%system.processes%' """) else: - return clickhouse_client.execute_pandas('SHOW PROCESSLIST') + return clickhouse_execute_pandas(args, 'SHOW PROCESSLIST') # collect server stacktraces using gdb @@ -342,7 +350,6 @@ class TestCase: @staticmethod def configure_testcase_args(args, case_file, suite_tmp_dir): - global clickhouse_client testcase_args = copy.deepcopy(args) testcase_args.testcase_start_time = datetime.now() @@ -363,7 +370,7 @@ class TestCase: database = 'test_{suffix}'.format(suffix=random_str()) try: - clickhouse_client.execute("CREATE DATABASE " + database + get_db_engine(testcase_args, database), settings={'log_comment': testcase_basename}) + clickhouse_execute(args, "CREATE DATABASE " + database + get_db_engine(testcase_args, database), settings={'log_comment': testcase_basename}) except (TimeoutError, clickhouse_driver.errors.SocketTimeoutError): total_time = (datetime.now() - testcase_args.testcase_start_time).total_seconds() return None, "", f"Timeout creating database {database} before test", total_time @@ -536,12 +543,10 @@ class TestCase: @staticmethod def send_test_name_failed(suite: str, case: str) -> bool: - global clickhouse_client pid = os.getpid() - clickhouse_client.execute(f"SELECT 'Running test {suite}/{case} from pid={pid}'") + clickhouse_execute(args, f"SELECT 'Running test {suite}/{case} from pid={pid}'") def run_single_test(self, server_logs_level, client_options): - global clickhouse_client args = self.testcase_args client = args.testcase_client start_time = args.testcase_start_time @@ -585,8 +590,10 @@ class TestCase: if need_drop_database: seconds_left = max(args.timeout - (datetime.now() - start_time).total_seconds(), 20) try: - with clickhouse_client.connection.timeout_setter(seconds_left): - clickhouse_client.execute("DROP DATABASE " + database) + client = make_clickhouse_client(args) + client.connection.force_connect() + with client.connection.timeout_setter(seconds_left): + client.execute("DROP DATABASE " + database) except (TimeoutError, clickhouse_driver.errors.SocketTimeoutError): total_time = (datetime.now() - start_time).total_seconds() return None, "", f"Timeout dropping database {database} after test", total_time @@ -793,8 +800,7 @@ class TestSuite: @staticmethod def readTestSuite(args, suite_dir_name: str): def is_data_present(): - global clickhouse_client - return int(clickhouse_client.execute_one('EXISTS TABLE test.hits')) + return int(clickhouse_execute_one(args, 'EXISTS TABLE test.hits')) base_dir = os.path.abspath(args.queries) tmp_dir = os.path.abspath(args.tmp) @@ -827,7 +833,6 @@ class TestSuite: stop_time = None -clickhouse_client = None exit_code = None server_died = None stop_tests_triggered_lock = None @@ -957,14 +962,14 @@ def run_tests_array(all_tests_with_params): server_logs_level = "warning" -def check_server_started(retry_count): - global clickhouse_client +def check_server_started(args): print("Connecting to ClickHouse server...", end='') sys.stdout.flush() + retry_count = args.server_check_retries while retry_count > 0: try: - clickhouse_client.execute('SELECT 1') + clickhouse_execute(args, 'SELECT 1') print(" OK") sys.stdout.flush() return True @@ -992,12 +997,10 @@ class BuildFlags(): POLYMORPHIC_PARTS = 'polymorphic-parts' -def collect_build_flags(): - global clickhouse_client - +def collect_build_flags(args): result = [] - value = clickhouse_client.execute_one("SELECT value FROM system.build_options WHERE name = 'CXX_FLAGS'") + value = clickhouse_execute_one(args, "SELECT value FROM system.build_options WHERE name = 'CXX_FLAGS'") if '-fsanitize=thread' in value: result.append(BuildFlags.THREAD) elif '-fsanitize=address' in value: @@ -1007,21 +1010,21 @@ def collect_build_flags(): elif '-fsanitize=memory' in value: result.append(BuildFlags.MEMORY) - value = clickhouse_client.execute_one("SELECT value FROM system.build_options WHERE name = 'BUILD_TYPE'") + value = clickhouse_execute_one(args, "SELECT value FROM system.build_options WHERE name = 'BUILD_TYPE'") if 'Debug' in value: result.append(BuildFlags.DEBUG) elif 'RelWithDebInfo' in value or 'Release' in value: result.append(BuildFlags.RELEASE) - value = clickhouse_client.execute_one("SELECT value FROM system.build_options WHERE name = 'UNBUNDLED'") + value = clickhouse_execute_one(args, "SELECT value FROM system.build_options WHERE name = 'UNBUNDLED'") if value in ('ON', '1'): result.append(BuildFlags.UNBUNDLED) - value = clickhouse_client.execute_one("SELECT value FROM system.settings WHERE name = 'default_database_engine'") + value = clickhouse_execute_one(args, "SELECT value FROM system.settings WHERE name = 'default_database_engine'") if value == 'Ordinary': result.append(BuildFlags.ORDINARY_DATABASE) - value = int(clickhouse_client.execute_one("SELECT value FROM system.merge_tree_settings WHERE name = 'min_bytes_for_wide_part'")) + value = int(clickhouse_execute_one(args, "SELECT value FROM system.merge_tree_settings WHERE name = 'min_bytes_for_wide_part'")) if value == 0: result.append(BuildFlags.POLYMORPHIC_PARTS) @@ -1118,9 +1121,8 @@ def main(args): global exit_code global server_logs_level global restarted_tests - global clickhouse_client - if not check_server_started(args.server_check_retries): + if not check_server_started(args): msg = "Server is not responding. Cannot execute 'SELECT 1' query. \ If you are using split build, you have to specify -c option." if args.hung_check: @@ -1130,7 +1132,7 @@ def main(args): print_stacktraces() raise Exception(msg) - args.build_flags = collect_build_flags() + args.build_flags = collect_build_flags(args) if args.skip: args.skip = set(args.skip) @@ -1167,7 +1169,7 @@ def main(args): while create_database_retries < MAX_RETRIES: start_time = datetime.now() try: - clickhouse_client.execute("CREATE DATABASE IF NOT EXISTS " + db_name + get_db_engine(args, db_name)) + clickhouse_execute(args, "CREATE DATABASE IF NOT EXISTS " + db_name + get_db_engine(args, db_name)) except Exception as e: total_time = (datetime.now() - start_time).total_seconds() if not need_retry_error(args, e, total_time): @@ -1384,9 +1386,10 @@ if __name__ == '__main__': tcp_host = os.getenv("CLICKHOUSE_HOST") if tcp_host is not None: + args.tcp_host = tcp_host args.client += f' --host={tcp_host}' else: - tcp_host = 'localhost' + args.tcp_host = 'localhost' tcp_port = os.getenv("CLICKHOUSE_PORT_TCP") if tcp_port is not None: @@ -1398,8 +1401,9 @@ if __name__ == '__main__': client_database = os.getenv("CLICKHOUSE_DATABASE") if client_database is not None: args.client += f' --database={client_database}' + args.client_database = client_database else: - client_database = 'default' + args.client_database = 'default' if args.client_option: # Set options for client @@ -1431,9 +1435,4 @@ if __name__ == '__main__': pandas.options.display.max_columns = None pandas.options.display.width = None - clickhouse_client = Client(host=tcp_host, - port=args.tcp_port, - database=client_database, - settings=get_additional_client_options_dict(args)) - main(args) From f854065744f57607e23a0de3edcca1b06f06c11a Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 8 Oct 2021 05:05:12 +0000 Subject: [PATCH 067/264] buildID() description --- docs/en/sql-reference/functions/other-functions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/en/sql-reference/functions/other-functions.md b/docs/en/sql-reference/functions/other-functions.md index afcc9563b58..9828c91909b 100644 --- a/docs/en/sql-reference/functions/other-functions.md +++ b/docs/en/sql-reference/functions/other-functions.md @@ -699,6 +699,12 @@ If it is executed in the context of a distributed table, then it generates a nor Returns the version of the server as a string. If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. +## buildId() {#buildid} + +Returns the compiler build id of the running binary. +If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. + + ## blockNumber {#blocknumber} Returns the sequence number of the data block where the row is located. From d454a9affe73ee5844f19f8e85a4143c89c1d016 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 8 Oct 2021 10:07:55 +0300 Subject: [PATCH 068/264] Update docs/ru/getting-started/example-datasets/metrica.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/getting-started/example-datasets/metrica.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index 27105ca8488..4d862bae423 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -35,7 +35,7 @@ $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" ``` bash $ curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv -$ # теперь создадим таблицу +# создадим таблицу hits_v1 $ clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" $ clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" # for hits_100m_obfuscated From 9d97a1263f4bd31c8520d9a54a35c8aa8877b982 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 8 Oct 2021 10:08:02 +0300 Subject: [PATCH 069/264] Update docs/ru/getting-started/example-datasets/metrica.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/getting-started/example-datasets/metrica.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index 4d862bae423..765642ce3ae 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -38,7 +38,7 @@ $ curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads= # создадим таблицу hits_v1 $ clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" $ clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" -# for hits_100m_obfuscated +# создадим таблицу hits_100m_obfuscated clickhouse-client --query="CREATE TABLE hits_100m_obfuscated (WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, Refresh UInt8, RefererCategoryID UInt16, RefererRegionID UInt32, URLCategoryID UInt16, URLRegionID UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, OriginalURL String, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), LocalEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, RemoteIP UInt32, WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming UInt32, DNSTiming UInt32, ConnectTiming UInt32, ResponseStartTiming UInt32, ResponseEndTiming UInt32, FetchTiming UInt32, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" $ # импортируем данные From 2c5341df33a3410db2aed4f57d4429d681064186 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 8 Oct 2021 10:08:25 +0300 Subject: [PATCH 070/264] Update docs/ru/sql-reference/functions/geo/h3.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/geo/h3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/geo/h3.md b/docs/ru/sql-reference/functions/geo/h3.md index e85236848f6..db96f0caa1d 100644 --- a/docs/ru/sql-reference/functions/geo/h3.md +++ b/docs/ru/sql-reference/functions/geo/h3.md @@ -6,7 +6,7 @@ toc_title: "Функции для работы с индексами H3" [H3](https://eng.uber.com/h3/) — это система геокодирования, которая делит поверхность Земли на равные шестигранные ячейки. Система поддерживает иерархию (вложенность) ячеек, т.е. каждый "родительский" шестигранник может быть поделен на семь одинаковых вложенных "дочерних" шестигранников, и так далее. -Уровень вложенности называется `разрешением` и может принимать значение от `0` до `15`, где `0` соответствует `базовым` ячейкам самого верхнего уровня (наиболее крупным). +Уровень вложенности называется "разрешением" и может принимать значение от `0` до `15`, где `0` соответствует "базовым" ячейкам самого верхнего уровня (наиболее крупным). Для каждой точки, имеющей широту и долготу, можно получить 64-битный индекс H3, соответствующий номеру шестигранной ячейки, где эта точка находится. From 0fdbf867a45689308f0072a005a70b83757d8cc0 Mon Sep 17 00:00:00 2001 From: Roman Bug Date: Fri, 8 Oct 2021 10:08:31 +0300 Subject: [PATCH 071/264] Update docs/ru/getting-started/example-datasets/metrica.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/getting-started/example-datasets/metrica.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index 765642ce3ae..761e298fc54 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -41,9 +41,9 @@ $ clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, Ja # создадим таблицу hits_100m_obfuscated clickhouse-client --query="CREATE TABLE hits_100m_obfuscated (WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, Refresh UInt8, RefererCategoryID UInt16, RefererRegionID UInt32, URLCategoryID UInt16, URLRegionID UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, OriginalURL String, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), LocalEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, RemoteIP UInt32, WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming UInt32, DNSTiming UInt32, ConnectTiming UInt32, ResponseStartTiming UInt32, ResponseEndTiming UInt32, FetchTiming UInt32, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" -$ # импортируем данные +# импортируем данные $ cat hits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.hits_v1 FORMAT TSV" --max_insert_block_size=100000 -$ # опционально можно оптимизировать таблицу +# опционально можно оптимизировать таблицу $ clickhouse-client --query "OPTIMIZE TABLE datasets.hits_v1 FINAL" $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" ``` From d11cae26178fd114f69c763de4dbd18190175486 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Fri, 8 Oct 2021 10:26:02 +0300 Subject: [PATCH 072/264] Remove `$ #` from metrica.md --- docs/ru/getting-started/example-datasets/metrica.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index 761e298fc54..0f5e7197fe5 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -14,7 +14,7 @@ toc_title: "Анонимизированные данные Яндекс.Мет ``` bash $ curl -O https://datasets.clickhouse.com/hits/partitions/hits_v1.tar $ tar xvf hits_v1.tar -C /var/lib/clickhouse # путь к папке с данными ClickHouse -$ # убедитесь, что установлены корректные права доступа на файлы +# убедитесь, что установлены корректные права доступа на файлы $ sudo service clickhouse-server restart $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" ``` @@ -24,7 +24,7 @@ $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" ``` bash $ curl -O https://datasets.clickhouse.com/visits/partitions/visits_v1.tar $ tar xvf visits_v1.tar -C /var/lib/clickhouse # путь к папке с данными ClickHouse -$ # убедитесь, что установлены корректные права доступа на файлы +# убедитесь, что установлены корректные права доступа на файлы $ sudo service clickhouse-server restart $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" ``` @@ -52,12 +52,12 @@ $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" ``` bash $ curl https://datasets.clickhouse.com/visits/tsv/visits_v1.tsv.xz | unxz --threads=`nproc` > visits_v1.tsv -$ # теперь создадим таблицу +# теперь создадим таблицу $ clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" $ clickhouse-client --query "CREATE TABLE datasets.visits_v1 ( CounterID UInt32, StartDate Date, Sign Int8, IsNew UInt8, VisitID UInt64, UserID UInt64, StartTime DateTime, Duration UInt32, UTCStartTime DateTime, PageViews Int32, Hits Int32, IsBounce UInt8, Referer String, StartURL String, RefererDomain String, StartURLDomain String, EndURL String, LinkURL String, IsDownload UInt8, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, PlaceID Int32, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), IsYandex UInt8, GoalReachesDepth Int32, GoalReachesURL Int32, GoalReachesAny Int32, SocialSourceNetworkID UInt8, SocialSourcePage String, MobilePhoneModel String, ClientEventTime DateTime, RegionID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RemoteIP UInt32, RemoteIP6 FixedString(16), IPNetworkID UInt32, SilverlightVersion3 UInt32, CodeVersion UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, UserAgentMajor UInt16, UserAgentMinor UInt16, WindowClientWidth UInt16, WindowClientHeight UInt16, SilverlightVersion2 UInt8, SilverlightVersion4 UInt16, FlashVersion3 UInt16, FlashVersion4 UInt16, ClientTimeZone Int16, OS UInt8, UserAgent UInt8, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, NetMajor UInt8, NetMinor UInt8, MobilePhone UInt8, SilverlightVersion1 UInt8, Age UInt8, Sex UInt8, Income UInt8, JavaEnable UInt8, CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, BrowserLanguage UInt16, BrowserCountry UInt16, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), Params Array(String), Goals Nested(ID UInt32, Serial UInt32, EventTime DateTime, Price Int64, OrderID String, CurrencyID UInt32), WatchIDs Array(UInt64), ParamSumPrice Int64, ParamCurrency FixedString(3), ParamCurrencyID UInt16, ClickLogID UInt64, ClickEventID Int32, ClickGoodEvent Int32, ClickEventTime DateTime, ClickPriorityID Int32, ClickPhraseID Int32, ClickPageID Int32, ClickPlaceID Int32, ClickTypeID Int32, ClickResourceID Int32, ClickCost UInt32, ClickClientIP UInt32, ClickDomainID UInt32, ClickURL String, ClickAttempt UInt8, ClickOrderID UInt32, ClickBannerID UInt32, ClickMarketCategoryID UInt32, ClickMarketPP UInt32, ClickMarketCategoryName String, ClickMarketPPName String, ClickAWAPSCampaignName String, ClickPageName String, ClickTargetType UInt16, ClickTargetPhraseID UInt64, ClickContextType UInt8, ClickSelectType Int8, ClickOptions String, ClickGroupBannerID Int32, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, FirstVisit DateTime, PredLastVisit Date, LastVisit Date, TotalVisits UInt32, TraficSource Nested(ID Int8, SearchEngineID UInt16, AdvEngineID UInt8, PlaceID UInt16, SocialSourceNetworkID UInt8, Domain String, SearchPhrase String, SocialSourcePage String), Attendance FixedString(16), CLID UInt32, YCLID UInt64, NormalizedRefererHash UInt64, SearchPhraseHash UInt64, RefererDomainHash UInt64, NormalizedStartURLHash UInt64, StartURLDomainHash UInt64, NormalizedEndURLHash UInt64, TopLevelDomain UInt64, URLScheme UInt64, OpenstatServiceNameHash UInt64, OpenstatCampaignIDHash UInt64, OpenstatAdIDHash UInt64, OpenstatSourceIDHash UInt64, UTMSourceHash UInt64, UTMMediumHash UInt64, UTMCampaignHash UInt64, UTMContentHash UInt64, UTMTermHash UInt64, FromHash UInt64, WebVisorEnabled UInt8, WebVisorActivity UInt32, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), Market Nested(Type UInt8, GoalID UInt32, OrderID String, OrderPrice Int64, PP UInt32, DirectPlaceID UInt32, DirectOrderID UInt32, DirectBannerID UInt32, GoodID String, GoodName String, GoodQuantity Int32, GoodPrice Int64), IslandID FixedString(16)) ENGINE = CollapsingMergeTree(Sign) PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" -$ # импортируем данные +# импортируем данные $ cat visits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.visits_v1 FORMAT TSV" --max_insert_block_size=100000 -$ # опционально можно оптимизировать таблицу +# опционально можно оптимизировать таблицу $ clickhouse-client --query "OPTIMIZE TABLE datasets.visits_v1 FINAL" $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" ``` From bb55fb41c62b8412d2b245b58152d8a014c831b1 Mon Sep 17 00:00:00 2001 From: kssenii Date: Fri, 8 Oct 2021 07:48:05 +0000 Subject: [PATCH 073/264] Add test --- .../0_stateless/02047_client_exception.expect | 32 +++++++++++++++++++ .../02047_client_exception.reference | 0 2 files changed, 32 insertions(+) create mode 100755 tests/queries/0_stateless/02047_client_exception.expect create mode 100644 tests/queries/0_stateless/02047_client_exception.reference diff --git a/tests/queries/0_stateless/02047_client_exception.expect b/tests/queries/0_stateless/02047_client_exception.expect new file mode 100755 index 00000000000..120f8ef11e3 --- /dev/null +++ b/tests/queries/0_stateless/02047_client_exception.expect @@ -0,0 +1,32 @@ +#!/usr/bin/expect -f +# Tags: no-unbundled, no-fasttest + +log_user 0 +set timeout 20 +match_max 100000 + +# A default timeout action is to fail +expect_after { + timeout { + exit 1 + } +} + +set basedir [file dirname $argv0] +spawn bash -c "source $basedir/../shell_config.sh ; \$CLICKHOUSE_CLIENT_BINARY \$CLICKHOUSE_CLIENT_OPT --disable_suggestion" +expect ":) " + +send -- "DROP TABLE IF EXISTS test_02047\r" +expect "Ok." + +send -- "CREATE TABLE test_02047 (s Int32) ENGINE=Memory()\r" +expect "Ok." + +send -- "INSERT INTO test_02047 SELECT 'f' \r" +expect "Received exception from server" + +send -- "DROP TABLE test_02047\r" +expect "Ok." + +send -- "\4" +expect eof diff --git a/tests/queries/0_stateless/02047_client_exception.reference b/tests/queries/0_stateless/02047_client_exception.reference new file mode 100644 index 00000000000..e69de29bb2d From b081f58db51a10a1d0fc6977cd4d9f108f12a265 Mon Sep 17 00:00:00 2001 From: MaxWk <610379995@qq.com> Date: Fri, 8 Oct 2021 16:49:02 +0800 Subject: [PATCH 074/264] add alias --- src/Storages/System/StorageSystemTables.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Storages/System/StorageSystemTables.cpp b/src/Storages/System/StorageSystemTables.cpp index f1f7fa4fa08..254e6f77e0c 100644 --- a/src/Storages/System/StorageSystemTables.cpp +++ b/src/Storages/System/StorageSystemTables.cpp @@ -59,6 +59,8 @@ StorageSystemTables::StorageSystemTables(const StorageID & table_id_) {"lifetime_bytes", std::make_shared(std::make_shared())}, {"comment", std::make_shared()}, {"has_own_data", std::make_shared()}, + }, { + {"table", std::make_shared(), "name"} })); setInMemoryMetadata(storage_metadata); } From 383f3a3a20ff7268b4c2fad14d0e20f266682b77 Mon Sep 17 00:00:00 2001 From: vesslanjin Date: Fri, 8 Oct 2021 09:19:58 -0400 Subject: [PATCH 075/264] =?UTF-8?q?Remove=C2=A0branchy=C2=A0code=C2=A0in?= =?UTF-8?q?=C2=A0filter=C2=A0operation=C2=A0with=C2=A0a=C2=A0better=C2=A0i?= =?UTF-8?q?mplementation=C2=A0with=C2=A0popcnt/ctz=C2=A0which=C2=A0have?= =?UTF-8?q?=C2=A0better=C2=A0performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Zhu Jasper --- src/Columns/ColumnFixedString.cpp | 22 +++++++++------------- src/Columns/ColumnVector.cpp | 11 +++++++---- src/Columns/ColumnsCommon.cpp | 11 +++++++---- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/Columns/ColumnFixedString.cpp b/src/Columns/ColumnFixedString.cpp index ce39ab0994c..4bfc6513263 100644 --- a/src/Columns/ColumnFixedString.cpp +++ b/src/Columns/ColumnFixedString.cpp @@ -231,7 +231,7 @@ ColumnPtr ColumnFixedString::filter(const IColumn::Filter & filt, ssize_t result const UInt8 * filt_end = filt_pos + col_size; const UInt8 * data_pos = chars.data(); -#ifdef __SSE2__ +#if defined(__SSE2__) && defined(__POPCNT__) /** A slightly more optimized version. * Based on the assumption that often pieces of consecutive values * completely pass or do not pass the filter. @@ -251,28 +251,24 @@ ColumnPtr ColumnFixedString::filter(const IColumn::Filter & filt, ssize_t result if (0 == mask) { /// Nothing is inserted. - data_pos += chars_per_simd_elements; } else if (0xFFFF == mask) { res->chars.insert(data_pos, data_pos + chars_per_simd_elements); - data_pos += chars_per_simd_elements; } else { size_t res_chars_size = res->chars.size(); - for (size_t i = 0; i < SIMD_BYTES; ++i) - { - if (filt_pos[i]) - { - res->chars.resize(res_chars_size + n); - memcpySmallAllowReadWriteOverflow15(&res->chars[res_chars_size], data_pos, n); - res_chars_size += n; - } - data_pos += n; + size_t pcnt = __builtin_popcount(mask); + for(size_t j = 0; j < pcnt; j++) { + size_t index = __builtin_ctz(mask); + res->chars.resize(res_chars_size + n); + memcpySmallAllowReadWriteOverflow15(&res->chars[res_chars_size], data_pos+index*n, n); + res_chars_size += n; + mask = mask & (mask-1); } } - + data_pos += chars_per_simd_elements; filt_pos += SIMD_BYTES; } #endif diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index 7f3cdaeec7f..ff84204a7cb 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -311,7 +311,7 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s const UInt8 * filt_end = filt_pos + size; const T * data_pos = data.data(); -#ifdef __SSE2__ +#if defined(__SSE2__) && defined(__POPCNT__) /** A slightly more optimized version. * Based on the assumption that often pieces of consecutive values * completely pass or do not pass the filter. @@ -337,9 +337,12 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s } else { - for (size_t i = 0; i < SIMD_BYTES; ++i) - if (filt_pos[i]) - res_data.push_back(data_pos[i]); + size_t pcnt = __builtin_popcount(mask); + for(size_t j = 0; j < pcnt; j++) { + size_t index = __builtin_ctz(mask); + res_data.push_back(data_pos[index]); + mask = mask & (mask-1); + } } filt_pos += SIMD_BYTES; diff --git a/src/Columns/ColumnsCommon.cpp b/src/Columns/ColumnsCommon.cpp index 41933ed08ed..5c0214054b2 100644 --- a/src/Columns/ColumnsCommon.cpp +++ b/src/Columns/ColumnsCommon.cpp @@ -229,7 +229,7 @@ namespace memcpy(&res_elems[elems_size_old], &src_elems[arr_offset], arr_size * sizeof(T)); }; - #ifdef __SSE2__ + #if defined(__SSE2__) && defined(__POPCNT__) const __m128i zero_vec = _mm_setzero_si128(); static constexpr size_t SIMD_BYTES = 16; const auto * filt_end_aligned = filt_pos + size / SIMD_BYTES * SIMD_BYTES; @@ -262,9 +262,12 @@ namespace } else { - for (size_t i = 0; i < SIMD_BYTES; ++i) - if (filt_pos[i]) - copy_array(offsets_pos + i); + size_t pcnt = __builtin_popcount(mask); + for(size_t j = 0; j < pcnt; j++) { + size_t index = __builtin_ctz(mask); + copy_array(offsets_pos + index); + mask = mask & (mask-1); + } } filt_pos += SIMD_BYTES; From 35feb082365eb0517f2c58659507de34ed47d3af Mon Sep 17 00:00:00 2001 From: Vladimir C Date: Fri, 8 Oct 2021 12:03:55 +0300 Subject: [PATCH 076/264] Whitespace changes --- src/Columns/ColumnFixedString.cpp | 7 ++++--- src/Columns/ColumnVector.cpp | 5 +++-- src/Columns/ColumnsCommon.cpp | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Columns/ColumnFixedString.cpp b/src/Columns/ColumnFixedString.cpp index 4bfc6513263..1080f29b5aa 100644 --- a/src/Columns/ColumnFixedString.cpp +++ b/src/Columns/ColumnFixedString.cpp @@ -260,12 +260,13 @@ ColumnPtr ColumnFixedString::filter(const IColumn::Filter & filt, ssize_t result { size_t res_chars_size = res->chars.size(); size_t pcnt = __builtin_popcount(mask); - for(size_t j = 0; j < pcnt; j++) { + for (size_t j = 0; j < pcnt; ++j) + { size_t index = __builtin_ctz(mask); res->chars.resize(res_chars_size + n); - memcpySmallAllowReadWriteOverflow15(&res->chars[res_chars_size], data_pos+index*n, n); + memcpySmallAllowReadWriteOverflow15(&res->chars[res_chars_size], data_pos + index * n, n); res_chars_size += n; - mask = mask & (mask-1); + mask = mask & (mask - 1); } } data_pos += chars_per_simd_elements; diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index ff84204a7cb..e7c56a57d51 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -338,10 +338,11 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s else { size_t pcnt = __builtin_popcount(mask); - for(size_t j = 0; j < pcnt; j++) { + for (size_t j = 0; j < pcnt; ++j) + { size_t index = __builtin_ctz(mask); res_data.push_back(data_pos[index]); - mask = mask & (mask-1); + mask = mask & (mask - 1); } } diff --git a/src/Columns/ColumnsCommon.cpp b/src/Columns/ColumnsCommon.cpp index 5c0214054b2..b4614abe490 100644 --- a/src/Columns/ColumnsCommon.cpp +++ b/src/Columns/ColumnsCommon.cpp @@ -263,10 +263,11 @@ namespace else { size_t pcnt = __builtin_popcount(mask); - for(size_t j = 0; j < pcnt; j++) { + for (size_t j = 0; j < pcnt; ++j) + { size_t index = __builtin_ctz(mask); copy_array(offsets_pos + index); - mask = mask & (mask-1); + mask = mask & (mask - 1); } } From a4d1ad61d0e220b6c215eaffd4cf3531e4c01423 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Fri, 8 Oct 2021 12:09:12 +0300 Subject: [PATCH 077/264] Remove $ symbols in bash commands. --- .../example-datasets/metrica.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index 0f5e7197fe5..15c0cc14517 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -12,21 +12,21 @@ toc_title: "Анонимизированные данные Яндекс.Мет **Скачивание и импортирование партиций hits:** ``` bash -$ curl -O https://datasets.clickhouse.com/hits/partitions/hits_v1.tar -$ tar xvf hits_v1.tar -C /var/lib/clickhouse # путь к папке с данными ClickHouse +curl -O https://datasets.clickhouse.com/hits/partitions/hits_v1.tar +tar xvf hits_v1.tar -C /var/lib/clickhouse # путь к папке с данными ClickHouse # убедитесь, что установлены корректные права доступа на файлы -$ sudo service clickhouse-server restart -$ clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" +sudo service clickhouse-server restart +clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" ``` **Скачивание и импортирование партиций visits:** ``` bash -$ curl -O https://datasets.clickhouse.com/visits/partitions/visits_v1.tar -$ tar xvf visits_v1.tar -C /var/lib/clickhouse # путь к папке с данными ClickHouse +curl -O https://datasets.clickhouse.com/visits/partitions/visits_v1.tar +tar xvf visits_v1.tar -C /var/lib/clickhouse # путь к папке с данными ClickHouse # убедитесь, что установлены корректные права доступа на файлы -$ sudo service clickhouse-server restart -$ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" +sudo service clickhouse-server restart +clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" ``` ## Получение таблиц из сжатых tsv-файлов {#poluchenie-tablits-iz-szhatykh-tsv-failov} @@ -34,32 +34,32 @@ $ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" **Скачивание и импортирование hits из сжатого tsv-файла** ``` bash -$ curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv +curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv # создадим таблицу hits_v1 -$ clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" -$ clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" +clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" +clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" # создадим таблицу hits_100m_obfuscated clickhouse-client --query="CREATE TABLE hits_100m_obfuscated (WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, Refresh UInt8, RefererCategoryID UInt16, RefererRegionID UInt32, URLCategoryID UInt16, URLRegionID UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, OriginalURL String, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), LocalEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, RemoteIP UInt32, WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming UInt32, DNSTiming UInt32, ConnectTiming UInt32, ResponseStartTiming UInt32, ResponseEndTiming UInt32, FetchTiming UInt32, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" # импортируем данные -$ cat hits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.hits_v1 FORMAT TSV" --max_insert_block_size=100000 +cat hits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.hits_v1 FORMAT TSV" --max_insert_block_size=100000 # опционально можно оптимизировать таблицу -$ clickhouse-client --query "OPTIMIZE TABLE datasets.hits_v1 FINAL" -$ clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" +clickhouse-client --query "OPTIMIZE TABLE datasets.hits_v1 FINAL" +clickhouse-client --query "SELECT COUNT(*) FROM datasets.hits_v1" ``` **Скачивание и импортирование visits из сжатого tsv-файла** ``` bash -$ curl https://datasets.clickhouse.com/visits/tsv/visits_v1.tsv.xz | unxz --threads=`nproc` > visits_v1.tsv +curl https://datasets.clickhouse.com/visits/tsv/visits_v1.tsv.xz | unxz --threads=`nproc` > visits_v1.tsv # теперь создадим таблицу -$ clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" -$ clickhouse-client --query "CREATE TABLE datasets.visits_v1 ( CounterID UInt32, StartDate Date, Sign Int8, IsNew UInt8, VisitID UInt64, UserID UInt64, StartTime DateTime, Duration UInt32, UTCStartTime DateTime, PageViews Int32, Hits Int32, IsBounce UInt8, Referer String, StartURL String, RefererDomain String, StartURLDomain String, EndURL String, LinkURL String, IsDownload UInt8, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, PlaceID Int32, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), IsYandex UInt8, GoalReachesDepth Int32, GoalReachesURL Int32, GoalReachesAny Int32, SocialSourceNetworkID UInt8, SocialSourcePage String, MobilePhoneModel String, ClientEventTime DateTime, RegionID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RemoteIP UInt32, RemoteIP6 FixedString(16), IPNetworkID UInt32, SilverlightVersion3 UInt32, CodeVersion UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, UserAgentMajor UInt16, UserAgentMinor UInt16, WindowClientWidth UInt16, WindowClientHeight UInt16, SilverlightVersion2 UInt8, SilverlightVersion4 UInt16, FlashVersion3 UInt16, FlashVersion4 UInt16, ClientTimeZone Int16, OS UInt8, UserAgent UInt8, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, NetMajor UInt8, NetMinor UInt8, MobilePhone UInt8, SilverlightVersion1 UInt8, Age UInt8, Sex UInt8, Income UInt8, JavaEnable UInt8, CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, BrowserLanguage UInt16, BrowserCountry UInt16, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), Params Array(String), Goals Nested(ID UInt32, Serial UInt32, EventTime DateTime, Price Int64, OrderID String, CurrencyID UInt32), WatchIDs Array(UInt64), ParamSumPrice Int64, ParamCurrency FixedString(3), ParamCurrencyID UInt16, ClickLogID UInt64, ClickEventID Int32, ClickGoodEvent Int32, ClickEventTime DateTime, ClickPriorityID Int32, ClickPhraseID Int32, ClickPageID Int32, ClickPlaceID Int32, ClickTypeID Int32, ClickResourceID Int32, ClickCost UInt32, ClickClientIP UInt32, ClickDomainID UInt32, ClickURL String, ClickAttempt UInt8, ClickOrderID UInt32, ClickBannerID UInt32, ClickMarketCategoryID UInt32, ClickMarketPP UInt32, ClickMarketCategoryName String, ClickMarketPPName String, ClickAWAPSCampaignName String, ClickPageName String, ClickTargetType UInt16, ClickTargetPhraseID UInt64, ClickContextType UInt8, ClickSelectType Int8, ClickOptions String, ClickGroupBannerID Int32, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, FirstVisit DateTime, PredLastVisit Date, LastVisit Date, TotalVisits UInt32, TraficSource Nested(ID Int8, SearchEngineID UInt16, AdvEngineID UInt8, PlaceID UInt16, SocialSourceNetworkID UInt8, Domain String, SearchPhrase String, SocialSourcePage String), Attendance FixedString(16), CLID UInt32, YCLID UInt64, NormalizedRefererHash UInt64, SearchPhraseHash UInt64, RefererDomainHash UInt64, NormalizedStartURLHash UInt64, StartURLDomainHash UInt64, NormalizedEndURLHash UInt64, TopLevelDomain UInt64, URLScheme UInt64, OpenstatServiceNameHash UInt64, OpenstatCampaignIDHash UInt64, OpenstatAdIDHash UInt64, OpenstatSourceIDHash UInt64, UTMSourceHash UInt64, UTMMediumHash UInt64, UTMCampaignHash UInt64, UTMContentHash UInt64, UTMTermHash UInt64, FromHash UInt64, WebVisorEnabled UInt8, WebVisorActivity UInt32, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), Market Nested(Type UInt8, GoalID UInt32, OrderID String, OrderPrice Int64, PP UInt32, DirectPlaceID UInt32, DirectOrderID UInt32, DirectBannerID UInt32, GoodID String, GoodName String, GoodQuantity Int32, GoodPrice Int64), IslandID FixedString(16)) ENGINE = CollapsingMergeTree(Sign) PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" +clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" +clickhouse-client --query "CREATE TABLE datasets.visits_v1 ( CounterID UInt32, StartDate Date, Sign Int8, IsNew UInt8, VisitID UInt64, UserID UInt64, StartTime DateTime, Duration UInt32, UTCStartTime DateTime, PageViews Int32, Hits Int32, IsBounce UInt8, Referer String, StartURL String, RefererDomain String, StartURLDomain String, EndURL String, LinkURL String, IsDownload UInt8, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, PlaceID Int32, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), IsYandex UInt8, GoalReachesDepth Int32, GoalReachesURL Int32, GoalReachesAny Int32, SocialSourceNetworkID UInt8, SocialSourcePage String, MobilePhoneModel String, ClientEventTime DateTime, RegionID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RemoteIP UInt32, RemoteIP6 FixedString(16), IPNetworkID UInt32, SilverlightVersion3 UInt32, CodeVersion UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, UserAgentMajor UInt16, UserAgentMinor UInt16, WindowClientWidth UInt16, WindowClientHeight UInt16, SilverlightVersion2 UInt8, SilverlightVersion4 UInt16, FlashVersion3 UInt16, FlashVersion4 UInt16, ClientTimeZone Int16, OS UInt8, UserAgent UInt8, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, NetMajor UInt8, NetMinor UInt8, MobilePhone UInt8, SilverlightVersion1 UInt8, Age UInt8, Sex UInt8, Income UInt8, JavaEnable UInt8, CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, BrowserLanguage UInt16, BrowserCountry UInt16, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), Params Array(String), Goals Nested(ID UInt32, Serial UInt32, EventTime DateTime, Price Int64, OrderID String, CurrencyID UInt32), WatchIDs Array(UInt64), ParamSumPrice Int64, ParamCurrency FixedString(3), ParamCurrencyID UInt16, ClickLogID UInt64, ClickEventID Int32, ClickGoodEvent Int32, ClickEventTime DateTime, ClickPriorityID Int32, ClickPhraseID Int32, ClickPageID Int32, ClickPlaceID Int32, ClickTypeID Int32, ClickResourceID Int32, ClickCost UInt32, ClickClientIP UInt32, ClickDomainID UInt32, ClickURL String, ClickAttempt UInt8, ClickOrderID UInt32, ClickBannerID UInt32, ClickMarketCategoryID UInt32, ClickMarketPP UInt32, ClickMarketCategoryName String, ClickMarketPPName String, ClickAWAPSCampaignName String, ClickPageName String, ClickTargetType UInt16, ClickTargetPhraseID UInt64, ClickContextType UInt8, ClickSelectType Int8, ClickOptions String, ClickGroupBannerID Int32, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, FirstVisit DateTime, PredLastVisit Date, LastVisit Date, TotalVisits UInt32, TraficSource Nested(ID Int8, SearchEngineID UInt16, AdvEngineID UInt8, PlaceID UInt16, SocialSourceNetworkID UInt8, Domain String, SearchPhrase String, SocialSourcePage String), Attendance FixedString(16), CLID UInt32, YCLID UInt64, NormalizedRefererHash UInt64, SearchPhraseHash UInt64, RefererDomainHash UInt64, NormalizedStartURLHash UInt64, StartURLDomainHash UInt64, NormalizedEndURLHash UInt64, TopLevelDomain UInt64, URLScheme UInt64, OpenstatServiceNameHash UInt64, OpenstatCampaignIDHash UInt64, OpenstatAdIDHash UInt64, OpenstatSourceIDHash UInt64, UTMSourceHash UInt64, UTMMediumHash UInt64, UTMCampaignHash UInt64, UTMContentHash UInt64, UTMTermHash UInt64, FromHash UInt64, WebVisorEnabled UInt8, WebVisorActivity UInt32, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), Market Nested(Type UInt8, GoalID UInt32, OrderID String, OrderPrice Int64, PP UInt32, DirectPlaceID UInt32, DirectOrderID UInt32, DirectBannerID UInt32, GoodID String, GoodName String, GoodQuantity Int32, GoodPrice Int64), IslandID FixedString(16)) ENGINE = CollapsingMergeTree(Sign) PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" # импортируем данные -$ cat visits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.visits_v1 FORMAT TSV" --max_insert_block_size=100000 +cat visits_v1.tsv | clickhouse-client --query "INSERT INTO datasets.visits_v1 FORMAT TSV" --max_insert_block_size=100000 # опционально можно оптимизировать таблицу -$ clickhouse-client --query "OPTIMIZE TABLE datasets.visits_v1 FINAL" -$ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" +clickhouse-client --query "OPTIMIZE TABLE datasets.visits_v1 FINAL" +clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" ``` ## Запросы {#zaprosy} From 525df998934368aedb3baac72645453b080cf01d Mon Sep 17 00:00:00 2001 From: Vladimir C Date: Fri, 8 Oct 2021 12:10:19 +0300 Subject: [PATCH 078/264] Whitespace fix --- src/Columns/ColumnVector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index e7c56a57d51..61ba2074bd7 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -343,7 +343,7 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s size_t index = __builtin_ctz(mask); res_data.push_back(data_pos[index]); mask = mask & (mask - 1); - } + } } filt_pos += SIMD_BYTES; From 3acdcc6ec5b31d3b5e7c33e0e49df99b39dbdda4 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 15:03:31 +0300 Subject: [PATCH 079/264] Update example --- src/Core/examples/coro.cpp | 44 ++++++++++++++------------------------ 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/src/Core/examples/coro.cpp b/src/Core/examples/coro.cpp index c8e2f7418e4..a9728314495 100644 --- a/src/Core/examples/coro.cpp +++ b/src/Core/examples/coro.cpp @@ -12,37 +12,25 @@ #include #if defined(__clang__) - #include -template -using coroutine_handle = std::experimental::coroutine_handle; - -using default_coroutine_handle = std::experimental::coroutine_handle<>; - -using suspend_never = std::experimental::suspend_never; -using suspend_always = std::experimental::suspend_always; +namespace std +{ + using namespace experimental::coroutines_v1; +} #else - #include - -template -using coroutine_handle = std::coroutine_handle; - -using default_coroutine_handle = std::coroutine_handle<>; - -using suspend_never = std::suspend_never; -using suspend_always = std::suspend_always; - +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #endif template -struct suspend_never_val +struct suspend_value { constexpr bool await_ready() const noexcept { return true; } - constexpr void await_suspend(default_coroutine_handle) const noexcept {} + constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} constexpr T await_resume() const noexcept { std::cout << " ret " << val << std::endl; @@ -57,10 +45,10 @@ struct resumable { struct promise_type { - using coro_handle = coroutine_handle; + using coro_handle = std::coroutine_handle; auto get_return_object() { return coro_handle::from_promise(*this); } - auto initial_suspend() { return suspend_never(); } - auto final_suspend() noexcept { return suspend_never_val{*r->value}; } + auto initial_suspend() { return std::suspend_never(); } + auto final_suspend() noexcept { return suspend_value{*r->value}; } //void return_void() {} void return_value(T value_) { r->value = value_; } void unhandled_exception() @@ -76,7 +64,7 @@ struct resumable resumable * r = nullptr; }; - using coro_handle = coroutine_handle; + using coro_handle = std::coroutine_handle; bool await_ready() const noexcept { return false; } void await_suspend(coro_handle g) noexcept @@ -148,16 +136,16 @@ private: std::exception_ptr exception; }; -resumable boo(std::string tag) +resumable boo([[maybe_unused]] std::string tag) { std::cout << "x" << std::endl; - co_await suspend_always(); + co_await std::suspend_always(); std::cout << StackTrace().toString(); std::cout << "y" << std::endl; co_return 1; } -resumable bar(std::string tag) +resumable bar([[maybe_unused]] std::string tag) { std::cout << "a" << std::endl; int res1 = co_await boo("boo1"); @@ -169,7 +157,7 @@ resumable bar(std::string tag) co_return res1 + res2; // 1 + 1 = 2 } -resumable foo(std::string tag) { +resumable foo([[maybe_unused]] std::string tag) { std::cout << "Hello" << std::endl; auto res1 = co_await bar("bar1"); std::cout << "Coro " << res1 << std::endl; From b8e77a0c62ca664e65f545a39c1132edb14995e1 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 15:06:09 +0300 Subject: [PATCH 080/264] Add -fcoroutines for g++ --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66df4d3124a..685b2c25a0d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -336,6 +336,10 @@ if (COMPILER_GCC OR COMPILER_CLANG) set(COMPILER_FLAGS "${COMPILER_FLAGS} -falign-functions=32") endif () +if (COMPILER_GCC) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcoroutines") +endif () + # Compiler-specific coverage flags e.g. -fcoverage-mapping for gcc option(WITH_COVERAGE "Profile the resulting binary/binaries" OFF) From f0e193d5a51725f524945adf55e85b80413f9c77 Mon Sep 17 00:00:00 2001 From: MaxWk <610379995@qq.com> Date: Fri, 8 Oct 2021 20:25:37 +0800 Subject: [PATCH 081/264] add database alias --- src/Storages/System/StorageSystemDatabases.cpp | 7 +++++++ src/Storages/System/StorageSystemDatabases.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/Storages/System/StorageSystemDatabases.cpp b/src/Storages/System/StorageSystemDatabases.cpp index a781f44e9b2..fb7a1bc59b8 100644 --- a/src/Storages/System/StorageSystemDatabases.cpp +++ b/src/Storages/System/StorageSystemDatabases.cpp @@ -21,6 +21,13 @@ NamesAndTypesList StorageSystemDatabases::getNamesAndTypes() }; } +NamesAndAliases StorageSystemDatabases::getNamesAndAliases() +{ + return { + {"database", std::make_shared(), "name"} + }; +} + void StorageSystemDatabases::fillData(MutableColumns & res_columns, ContextPtr context, const SelectQueryInfo &) const { const auto access = context->getAccess(); diff --git a/src/Storages/System/StorageSystemDatabases.h b/src/Storages/System/StorageSystemDatabases.h index 4aaae1bfd7f..3de0da126d4 100644 --- a/src/Storages/System/StorageSystemDatabases.h +++ b/src/Storages/System/StorageSystemDatabases.h @@ -23,6 +23,8 @@ public: static NamesAndTypesList getNamesAndTypes(); + static NamesAndAliases getNamesAndAliases(); + protected: using IStorageSystemOneBlock::IStorageSystemOneBlock; From f47e7aa8b84cb9b851e96a034a2bf6a9d5298dd3 Mon Sep 17 00:00:00 2001 From: MaxWk <610379995@qq.com> Date: Fri, 8 Oct 2021 20:27:13 +0800 Subject: [PATCH 082/264] add test --- .../02047_alias_for_table_and_database_name.reference | 2 ++ .../0_stateless/02047_alias_for_table_and_database_name.sql | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 tests/queries/0_stateless/02047_alias_for_table_and_database_name.reference create mode 100644 tests/queries/0_stateless/02047_alias_for_table_and_database_name.sql diff --git a/tests/queries/0_stateless/02047_alias_for_table_and_database_name.reference b/tests/queries/0_stateless/02047_alias_for_table_and_database_name.reference new file mode 100644 index 00000000000..324e7ff9ab8 --- /dev/null +++ b/tests/queries/0_stateless/02047_alias_for_table_and_database_name.reference @@ -0,0 +1,2 @@ +numbers numbers +default default diff --git a/tests/queries/0_stateless/02047_alias_for_table_and_database_name.sql b/tests/queries/0_stateless/02047_alias_for_table_and_database_name.sql new file mode 100644 index 00000000000..2fabd2affd4 --- /dev/null +++ b/tests/queries/0_stateless/02047_alias_for_table_and_database_name.sql @@ -0,0 +1,2 @@ +SELECT name,table from system.tables where database = 'system' and name = 'numbers'; +SELECt name,database from system.databases where name = 'default'; From 7fa3257bb6b5bf5ef8576f70c4657335442a0c70 Mon Sep 17 00:00:00 2001 From: Artur Filatenkov <613623@mail.ru> Date: Fri, 8 Oct 2021 15:37:24 +0300 Subject: [PATCH 083/264] correct test --- tests/integration/test_settings_profile/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_settings_profile/test.py b/tests/integration/test_settings_profile/test.py index 7be0b395764..78efe7ffcad 100644 --- a/tests/integration/test_settings_profile/test.py +++ b/tests/integration/test_settings_profile/test.py @@ -201,7 +201,7 @@ def test_show_profiles(): assert instance.query("SHOW CREATE PROFILE xyz") == "CREATE SETTINGS PROFILE xyz\n" assert instance.query( - "SHOW CREATE SETTINGS PROFILE default") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" + "SHOW CREATE SETTINGS PROFILE default") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" assert instance.query( "SHOW CREATE PROFILES") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" \ "CREATE SETTINGS PROFILE readonly SETTINGS readonly = 1\n" \ From 340b53ef853348758c9042b16a8599120ebc8d22 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 17:03:54 +0300 Subject: [PATCH 084/264] Remove some more streams. --- programs/benchmark/Benchmark.cpp | 17 ++-- programs/copier/ClusterCopier.cpp | 1 - programs/copier/Internals.h | 2 +- src/Client/ClientBase.cpp | 11 ++- src/Client/ClientBase.h | 7 +- src/Columns/ColumnAggregateFunction.cpp | 2 +- src/Columns/ColumnArray.cpp | 2 +- src/Columns/ColumnDecimal.cpp | 2 +- src/Columns/ColumnFixedString.cpp | 2 +- src/Columns/ColumnLowCardinality.cpp | 2 +- src/Columns/ColumnMap.cpp | 2 +- src/Columns/ColumnNullable.cpp | 2 +- src/Columns/ColumnString.cpp | 2 +- src/Columns/ColumnTuple.cpp | 2 +- src/Columns/ColumnVector.cpp | 2 +- .../ExpressionBlockInputStream.cpp | 39 ---------- src/DataStreams/ExpressionBlockInputStream.h | 52 ------------- ...wOutputStream.cpp => InternalTextLogs.cpp} | 9 +-- ...gsRowOutputStream.h => InternalTextLogs.h} | 9 +-- .../MaterializingBlockInputStream.cpp | 28 ------- .../MaterializingBlockInputStream.h | 21 ----- src/DataStreams/RemoteBlockInputStream.cpp | 69 ---------------- src/DataStreams/RemoteBlockInputStream.h | 78 ------------------- src/Dictionaries/MongoDBDictionarySource.cpp | 2 +- .../PostgreSQLDictionarySource.cpp | 2 +- src/Interpreters/InterpreterInsertQuery.cpp | 2 +- src/Interpreters/InterpreterSelectQuery.cpp | 5 +- src/Interpreters/MutationsInterpreter.cpp | 2 +- src/Interpreters/ThreadStatusExt.cpp | 2 +- .../getHeaderForProcessingStage.cpp | 8 +- .../Algorithms/CollapsingSortedAlgorithm.h | 2 +- .../Algorithms/MergingSortedAlgorithm.cpp | 2 +- .../Algorithms/ReplacingSortedAlgorithm.h | 2 +- .../Algorithms/VersionedCollapsingAlgorithm.h | 2 +- .../Merges/MergingSortedTransform.cpp | 2 +- .../Sources/SourceFromInputStream.cpp | 5 -- .../Transforms/ColumnGathererTransform.cpp} | 2 +- .../Transforms/ColumnGathererTransform.h} | 0 .../Transforms/DistinctSortedTransform.cpp} | 2 +- .../Transforms/DistinctSortedTransform.h} | 0 .../Transforms}/MongoDBSource.cpp | 0 .../Transforms}/MongoDBSource.h | 0 .../Transforms}/PostgreSQLSource.cpp | 0 .../Transforms}/PostgreSQLSource.h | 0 .../Transforms/buildPushingToViewsChain.cpp} | 2 +- .../Transforms/buildPushingToViewsChain.h} | 0 src/Storages/MergeTree/MergeTask.cpp | 5 +- src/Storages/MergeTree/MergeTask.h | 2 +- .../MergeTree/MergeTreeDataMergerMutator.cpp | 6 +- src/Storages/MergeTree/MutateTask.cpp | 6 +- .../PostgreSQLReplicationHandler.cpp | 2 +- src/Storages/StorageMongoDB.cpp | 2 +- src/Storages/StoragePostgreSQL.cpp | 2 +- src/Storages/StorageReplicatedMergeTree.cpp | 1 - src/Storages/StorageS3Cluster.cpp | 2 +- src/Storages/getStructureOfRemoteTable.cpp | 12 +-- .../tests/gtest_row_source_bits_test.cpp | 2 +- src/TableFunctions/TableFunctionS3Cluster.cpp | 2 +- 58 files changed, 73 insertions(+), 378 deletions(-) delete mode 100644 src/DataStreams/ExpressionBlockInputStream.cpp delete mode 100644 src/DataStreams/ExpressionBlockInputStream.h rename src/DataStreams/{InternalTextLogsRowOutputStream.cpp => InternalTextLogs.cpp} (94%) rename src/DataStreams/{InternalTextLogsRowOutputStream.h => InternalTextLogs.h} (57%) delete mode 100644 src/DataStreams/MaterializingBlockInputStream.cpp delete mode 100644 src/DataStreams/MaterializingBlockInputStream.h delete mode 100644 src/DataStreams/RemoteBlockInputStream.cpp delete mode 100644 src/DataStreams/RemoteBlockInputStream.h rename src/{DataStreams/ColumnGathererStream.cpp => Processors/Transforms/ColumnGathererTransform.cpp} (98%) rename src/{DataStreams/ColumnGathererStream.h => Processors/Transforms/ColumnGathererTransform.h} (100%) rename src/{DataStreams/DistinctSortedBlockInputStream.cpp => Processors/Transforms/DistinctSortedTransform.cpp} (98%) rename src/{DataStreams/DistinctSortedBlockInputStream.h => Processors/Transforms/DistinctSortedTransform.h} (100%) rename src/{DataStreams => Processors/Transforms}/MongoDBSource.cpp (100%) rename src/{DataStreams => Processors/Transforms}/MongoDBSource.h (100%) rename src/{DataStreams => Processors/Transforms}/PostgreSQLSource.cpp (100%) rename src/{DataStreams => Processors/Transforms}/PostgreSQLSource.h (100%) rename src/{DataStreams/PushingToViewsBlockOutputStream.cpp => Processors/Transforms/buildPushingToViewsChain.cpp} (99%) rename src/{DataStreams/PushingToViewsBlockOutputStream.h => Processors/Transforms/buildPushingToViewsChain.h} (100%) diff --git a/programs/benchmark/Benchmark.cpp b/programs/benchmark/Benchmark.cpp index be57a3b92a0..caa0a87bde2 100644 --- a/programs/benchmark/Benchmark.cpp +++ b/programs/benchmark/Benchmark.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -424,20 +424,19 @@ private: if (reconnect) connection.disconnect(); - RemoteBlockInputStream stream( + RemoteQueryExecutor executor( connection, query, {}, global_context, nullptr, Scalars(), Tables(), query_processing_stage); if (!query_id.empty()) - stream.setQueryId(query_id); + executor.setQueryId(query_id); Progress progress; - stream.setProgressCallback([&progress](const Progress & value) { progress.incrementPiecewiseAtomically(value); }); + executor.setProgressCallback([&progress](const Progress & value) { progress.incrementPiecewiseAtomically(value); }); - stream.readPrefix(); - while (Block block = stream.read()); + BlockStreamProfileInfo info; + while (Block block = executor.read()) + info.update(block); - stream.readSuffix(); - - const BlockStreamProfileInfo & info = stream.getProfileInfo(); + executor.finish(); double seconds = watch.elapsedSeconds(); diff --git a/programs/copier/ClusterCopier.cpp b/programs/copier/ClusterCopier.cpp index 30b99b69351..60e1590d3bd 100644 --- a/programs/copier/ClusterCopier.cpp +++ b/programs/copier/ClusterCopier.cpp @@ -14,7 +14,6 @@ #include #include #include -#include namespace DB { diff --git a/programs/copier/Internals.h b/programs/copier/Internals.h index 54e7e7719e0..45531e750b9 100644 --- a/programs/copier/Internals.h +++ b/programs/copier/Internals.h @@ -49,7 +49,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index cde5a5f9977..99cadabfaea 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -48,7 +48,7 @@ #include #include -#include +#include namespace fs = std::filesystem; @@ -95,6 +95,9 @@ void interruptSignalHandler(int signum) _exit(signum); } +ClientBase::~ClientBase() = default; +ClientBase::ClientBase() = default; + void ClientBase::setupSignalHandler() { exit_on_signal.test_and_set(); @@ -393,8 +396,7 @@ void ClientBase::initLogsOutputStream() } } - logs_out_stream = std::make_shared(*wb, stdout_is_a_tty); - logs_out_stream->writePrefix(); + logs_out_stream = std::make_unique(*wb, stdout_is_a_tty); } } @@ -641,9 +643,6 @@ void ClientBase::onEndOfStream() if (block_out_stream) block_out_stream->writeSuffix(); - if (logs_out_stream) - logs_out_stream->writeSuffix(); - resetOutput(); if (is_interactive && !written_first_block) diff --git a/src/Client/ClientBase.h b/src/Client/ClientBase.h index bf9e8fdfe47..b122803e1db 100644 --- a/src/Client/ClientBase.h +++ b/src/Client/ClientBase.h @@ -32,12 +32,17 @@ enum MultiQueryProcessingStage void interruptSignalHandler(int signum); +class InternalTextLogs; + class ClientBase : public Poco::Util::Application { public: using Arguments = std::vector; + ClientBase(); + ~ClientBase() override; + void init(int argc, char ** argv); protected: @@ -177,7 +182,7 @@ protected: /// The user could specify special file for server logs (stderr by default) std::unique_ptr out_logs_buf; String server_logs_file; - BlockOutputStreamPtr logs_out_stream; + std::unique_ptr logs_out_stream; String home_path; String history_file; /// Path to a file containing command history. diff --git a/src/Columns/ColumnAggregateFunction.cpp b/src/Columns/ColumnAggregateFunction.cpp index 5224ff0fbdb..cd1185d99db 100644 --- a/src/Columns/ColumnAggregateFunction.cpp +++ b/src/Columns/ColumnAggregateFunction.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Columns/ColumnArray.cpp b/src/Columns/ColumnArray.cpp index 8e613ae93c2..5e40b89cc7e 100644 --- a/src/Columns/ColumnArray.cpp +++ b/src/Columns/ColumnArray.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/src/Columns/ColumnDecimal.cpp b/src/Columns/ColumnDecimal.cpp index d50138bc582..d8c5ced4b6b 100644 --- a/src/Columns/ColumnDecimal.cpp +++ b/src/Columns/ColumnDecimal.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include template bool decimalLess(T x, T y, UInt32 x_scale, UInt32 y_scale); diff --git a/src/Columns/ColumnFixedString.cpp b/src/Columns/ColumnFixedString.cpp index ce39ab0994c..2bfd46a9607 100644 --- a/src/Columns/ColumnFixedString.cpp +++ b/src/Columns/ColumnFixedString.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Columns/ColumnLowCardinality.cpp b/src/Columns/ColumnLowCardinality.cpp index 6f7bc58406d..5b33baab345 100644 --- a/src/Columns/ColumnLowCardinality.cpp +++ b/src/Columns/ColumnLowCardinality.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Columns/ColumnMap.cpp b/src/Columns/ColumnMap.cpp index 03addee4f8d..4374ca30c99 100644 --- a/src/Columns/ColumnMap.cpp +++ b/src/Columns/ColumnMap.cpp @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Columns/ColumnNullable.cpp b/src/Columns/ColumnNullable.cpp index d4d62f9580c..4b3340a6b50 100644 --- a/src/Columns/ColumnNullable.cpp +++ b/src/Columns/ColumnNullable.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include namespace DB diff --git a/src/Columns/ColumnString.cpp b/src/Columns/ColumnString.cpp index bb34f524fdf..2beb9add318 100644 --- a/src/Columns/ColumnString.cpp +++ b/src/Columns/ColumnString.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Columns/ColumnTuple.cpp b/src/Columns/ColumnTuple.cpp index f053c32fda1..d157f18bf32 100644 --- a/src/Columns/ColumnTuple.cpp +++ b/src/Columns/ColumnTuple.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index 7f3cdaeec7f..56c2cef3243 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/DataStreams/ExpressionBlockInputStream.cpp b/src/DataStreams/ExpressionBlockInputStream.cpp deleted file mode 100644 index 4840a6263f6..00000000000 --- a/src/DataStreams/ExpressionBlockInputStream.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - - -namespace DB -{ - -ExpressionBlockInputStream::ExpressionBlockInputStream(const BlockInputStreamPtr & input, const ExpressionActionsPtr & expression_) - : expression(expression_) -{ - children.push_back(input); - cached_header = children.back()->getHeader(); - expression->execute(cached_header, true); -} - -String ExpressionBlockInputStream::getName() const { return "Expression"; } - -Block ExpressionBlockInputStream::getTotals() -{ - totals = children.back()->getTotals(); - expression->execute(totals); - - return totals; -} - -Block ExpressionBlockInputStream::getHeader() const -{ - return cached_header.cloneEmpty(); -} - -Block ExpressionBlockInputStream::readImpl() -{ - Block res = children.back()->read(); - if (res) - expression->execute(res); - return res; -} - -} diff --git a/src/DataStreams/ExpressionBlockInputStream.h b/src/DataStreams/ExpressionBlockInputStream.h deleted file mode 100644 index fae54fbcfbf..00000000000 --- a/src/DataStreams/ExpressionBlockInputStream.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include - - -namespace DB -{ - -class ExpressionActions; - -/** Executes a certain expression over the block. - * The expression consists of column identifiers from the block, constants, common functions. - * For example: hits * 2 + 3, url LIKE '%yandex%' - * The expression processes each row independently of the others. - */ -class ExpressionBlockInputStream : public IBlockInputStream -{ -public: - using ExpressionActionsPtr = std::shared_ptr; - - ExpressionBlockInputStream(const BlockInputStreamPtr & input, const ExpressionActionsPtr & expression_); - - String getName() const override; - Block getTotals() override; - Block getHeader() const override; - -protected: - ExpressionActionsPtr expression; - - Block readImpl() override; - -private: - Block cached_header; -}; - -/// ExpressionBlockInputStream that could generate many out blocks for single input block. -class InflatingExpressionBlockInputStream : public ExpressionBlockInputStream -{ -public: - InflatingExpressionBlockInputStream(const BlockInputStreamPtr & input, const ExpressionActionsPtr & expression_) - : ExpressionBlockInputStream(input, expression_) - {} - -protected: - Block readImpl() override; - -private: - ExtraBlockPtr not_processed; - size_t action_number = 0; -}; - -} diff --git a/src/DataStreams/InternalTextLogsRowOutputStream.cpp b/src/DataStreams/InternalTextLogs.cpp similarity index 94% rename from src/DataStreams/InternalTextLogsRowOutputStream.cpp rename to src/DataStreams/InternalTextLogs.cpp index 14247b8f2aa..a5883d17f28 100644 --- a/src/DataStreams/InternalTextLogsRowOutputStream.cpp +++ b/src/DataStreams/InternalTextLogs.cpp @@ -1,4 +1,4 @@ -#include "InternalTextLogsRowOutputStream.h" +#include "InternalTextLogs.h" #include #include #include @@ -13,12 +13,7 @@ namespace DB { -Block InternalTextLogsRowOutputStream::getHeader() const -{ - return InternalTextLogsQueue::getSampleBlock(); -} - -void InternalTextLogsRowOutputStream::write(const Block & block) +void InternalTextLogs::write(const Block & block) { const auto & array_event_time = typeid_cast(*block.getByName("event_time").column).getData(); const auto & array_microseconds = typeid_cast(*block.getByName("event_time_microseconds").column).getData(); diff --git a/src/DataStreams/InternalTextLogsRowOutputStream.h b/src/DataStreams/InternalTextLogs.h similarity index 57% rename from src/DataStreams/InternalTextLogsRowOutputStream.h rename to src/DataStreams/InternalTextLogs.h index 8ade76b34a7..1312c1d327c 100644 --- a/src/DataStreams/InternalTextLogsRowOutputStream.h +++ b/src/DataStreams/InternalTextLogs.h @@ -9,16 +9,15 @@ namespace DB /// Prints internal server logs /// Input blocks have to have the same structure as SystemLogsQueue::getSampleBlock() /// NOTE: IRowOutputFormat does not suite well for this case -class InternalTextLogsRowOutputStream : public IBlockOutputStream +class InternalTextLogs { public: - InternalTextLogsRowOutputStream(WriteBuffer & buf_out, bool color_) : wb(buf_out), color(color_) {} + InternalTextLogs(WriteBuffer & buf_out, bool color_) : wb(buf_out), color(color_) {} - Block getHeader() const override; - void write(const Block & block) override; + void write(const Block & block); - void flush() override + void flush() { wb.next(); } diff --git a/src/DataStreams/MaterializingBlockInputStream.cpp b/src/DataStreams/MaterializingBlockInputStream.cpp deleted file mode 100644 index e0f287d44fa..00000000000 --- a/src/DataStreams/MaterializingBlockInputStream.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - - -namespace DB -{ - -MaterializingBlockInputStream::MaterializingBlockInputStream(const BlockInputStreamPtr & input) -{ - children.push_back(input); -} - -String MaterializingBlockInputStream::getName() const -{ - return "Materializing"; -} - -Block MaterializingBlockInputStream::getHeader() const -{ - return materializeBlock(children.back()->getHeader()); -} - -Block MaterializingBlockInputStream::readImpl() -{ - return materializeBlock(children.back()->read()); -} - -} diff --git a/src/DataStreams/MaterializingBlockInputStream.h b/src/DataStreams/MaterializingBlockInputStream.h deleted file mode 100644 index 90fd91bd550..00000000000 --- a/src/DataStreams/MaterializingBlockInputStream.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -namespace DB -{ - -/** Converts columns-constants to full columns ("materializes" them). - */ -class MaterializingBlockInputStream : public IBlockInputStream -{ -public: - MaterializingBlockInputStream(const BlockInputStreamPtr & input); - String getName() const override; - Block getHeader() const override; - -protected: - Block readImpl() override; -}; - -} diff --git a/src/DataStreams/RemoteBlockInputStream.cpp b/src/DataStreams/RemoteBlockInputStream.cpp deleted file mode 100644 index 7caa54cff22..00000000000 --- a/src/DataStreams/RemoteBlockInputStream.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -namespace DB -{ - -RemoteBlockInputStream::RemoteBlockInputStream( - Connection & connection, - const String & query_, const Block & header_, ContextPtr context_, - const ThrottlerPtr & throttler, const Scalars & scalars_, const Tables & external_tables_, QueryProcessingStage::Enum stage_) - : query_executor(connection, query_, header_, context_, throttler, scalars_, external_tables_, stage_) -{ - init(); -} - -RemoteBlockInputStream::RemoteBlockInputStream( - const ConnectionPoolWithFailoverPtr & pool, - std::vector && connections, - const String & query_, const Block & header_, ContextPtr context_, - const ThrottlerPtr & throttler, const Scalars & scalars_, const Tables & external_tables_, QueryProcessingStage::Enum stage_) - : query_executor(pool, std::move(connections), query_, header_, context_, throttler, scalars_, external_tables_, stage_) -{ - init(); -} - -RemoteBlockInputStream::RemoteBlockInputStream( - const ConnectionPoolWithFailoverPtr & pool, - const String & query_, const Block & header_, ContextPtr context_, - const ThrottlerPtr & throttler, const Scalars & scalars_, const Tables & external_tables_, QueryProcessingStage::Enum stage_) - : query_executor(pool, query_, header_, context_, throttler, scalars_, external_tables_, stage_) -{ - init(); -} - -void RemoteBlockInputStream::init() -{ - query_executor.setProgressCallback([this](const Progress & progress) { progressImpl(progress); }); - query_executor.setProfileInfoCallback([this](const BlockStreamProfileInfo & info_) { info.setFrom(info_, true); }); - query_executor.setLogger(log); -} - -void RemoteBlockInputStream::cancel(bool kill) -{ - if (kill) - is_killed = true; - - bool old_val = false; - if (!is_cancelled.compare_exchange_strong(old_val, true, std::memory_order_seq_cst, std::memory_order_relaxed)) - return; - - query_executor.cancel(); -} - -Block RemoteBlockInputStream::readImpl() -{ - auto block = query_executor.read(); - - if (isCancelledOrThrowIfKilled()) - return Block(); - - return block; -} - -void RemoteBlockInputStream::readSuffixImpl() -{ - query_executor.finish(); -} - -} diff --git a/src/DataStreams/RemoteBlockInputStream.h b/src/DataStreams/RemoteBlockInputStream.h deleted file mode 100644 index 60bfa5d6990..00000000000 --- a/src/DataStreams/RemoteBlockInputStream.h +++ /dev/null @@ -1,78 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include -#include -#include -#include - -#include - -namespace DB -{ - -class Context; - -/** This class allows one to launch queries on remote replicas of one shard and get results - */ -class RemoteBlockInputStream : public IBlockInputStream -{ -public: - /// Takes already set connection. - RemoteBlockInputStream( - Connection & connection, - const String & query_, const Block & header_, ContextPtr context_, - const ThrottlerPtr & throttler = nullptr, const Scalars & scalars_ = Scalars(), const Tables & external_tables_ = Tables(), - QueryProcessingStage::Enum stage_ = QueryProcessingStage::Complete); - - /// Accepts several connections already taken from pool. - RemoteBlockInputStream( - const ConnectionPoolWithFailoverPtr & pool, - std::vector && connections, - const String & query_, const Block & header_, ContextPtr context_, - const ThrottlerPtr & throttler = nullptr, const Scalars & scalars_ = Scalars(), const Tables & external_tables_ = Tables(), - QueryProcessingStage::Enum stage_ = QueryProcessingStage::Complete); - - /// Takes a pool and gets one or several connections from it. - RemoteBlockInputStream( - const ConnectionPoolWithFailoverPtr & pool, - const String & query_, const Block & header_, ContextPtr context_, - const ThrottlerPtr & throttler = nullptr, const Scalars & scalars_ = Scalars(), const Tables & external_tables_ = Tables(), - QueryProcessingStage::Enum stage_ = QueryProcessingStage::Complete); - - /// Set the query_id. For now, used by performance test to later find the query - /// in the server query_log. Must be called before sending the query to the server. - void setQueryId(const std::string & query_id) { query_executor.setQueryId(query_id); } - - /// Specify how we allocate connections on a shard. - void setPoolMode(PoolMode pool_mode) { query_executor.setPoolMode(pool_mode); } - - void setMainTable(StorageID main_table_) { query_executor.setMainTable(std::move(main_table_)); } - - /// Prevent default progress notification because progress' callback is called by its own. - void progress(const Progress & /*value*/) override {} - - void cancel(bool kill) override; - - String getName() const override { return "Remote"; } - - Block getHeader() const override { return query_executor.getHeader(); } - Block getTotals() override { return query_executor.getTotals(); } - Block getExtremes() override { return query_executor.getExtremes(); } - -protected: - Block readImpl() override; - void readSuffixImpl() override; - -private: - RemoteQueryExecutor query_executor; - Poco::Logger * log = &Poco::Logger::get("RemoteBlockInputStream"); - - void init(); -}; - -} diff --git a/src/Dictionaries/MongoDBDictionarySource.cpp b/src/Dictionaries/MongoDBDictionarySource.cpp index 21c69b71b67..1e8be726941 100644 --- a/src/Dictionaries/MongoDBDictionarySource.cpp +++ b/src/Dictionaries/MongoDBDictionarySource.cpp @@ -67,7 +67,7 @@ void registerDictionarySourceMongoDB(DictionarySourceFactory & factory) // Poco/MongoDB/BSONWriter.h:54: void writeCString(const std::string & value); // src/IO/WriteHelpers.h:146 #define writeCString(s, buf) #include -#include +#include namespace DB diff --git a/src/Dictionaries/PostgreSQLDictionarySource.cpp b/src/Dictionaries/PostgreSQLDictionarySource.cpp index 484d16e1f03..a3324b7d769 100644 --- a/src/Dictionaries/PostgreSQLDictionarySource.cpp +++ b/src/Dictionaries/PostgreSQLDictionarySource.cpp @@ -8,7 +8,7 @@ #if USE_LIBPQXX #include #include -#include +#include #include "readInvalidateQuery.h" #include #include diff --git a/src/Interpreters/InterpreterInsertQuery.cpp b/src/Interpreters/InterpreterInsertQuery.cpp index 41b724c690e..a36941ea07a 100644 --- a/src/Interpreters/InterpreterInsertQuery.cpp +++ b/src/Interpreters/InterpreterInsertQuery.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index 12922e45a55..85cc889319f 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -65,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -1815,8 +1816,8 @@ void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum proc Block block_with_count{ {std::move(column), std::make_shared(func, argument_types, desc.parameters), desc.column_name}}; - auto istream = std::make_shared(block_with_count); - auto prepared_count = std::make_unique(Pipe(std::make_shared(istream)), context); + auto source = std::make_shared(block_with_count); + auto prepared_count = std::make_unique(Pipe(std::move(source)), context); prepared_count->setStepDescription("Optimized trivial count"); query_plan.addStep(std::move(prepared_count)); from_stage = QueryProcessingStage::WithMergeableState; diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index e5a129cbe12..2c12c4a6879 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -214,7 +214,7 @@ bool isStorageTouchedByMutations( ASTPtr select_query = prepareQueryAffectedAST(commands, storage, context_copy); /// Interpreter must be alive, when we use result of execute() method. - /// For some reason it may copy context and and give it into ExpressionBlockInputStream + /// For some reason it may copy context and and give it into ExpressionTransform /// after that we will use context from destroyed stack frame in our stream. InterpreterSelectQuery interpreter(select_query, context_copy, storage, metadata_snapshot, SelectQueryOptions().ignoreLimits()); auto io = interpreter.execute(); diff --git a/src/Interpreters/ThreadStatusExt.cpp b/src/Interpreters/ThreadStatusExt.cpp index ddfb832f6b2..465b8e31b08 100644 --- a/src/Interpreters/ThreadStatusExt.cpp +++ b/src/Interpreters/ThreadStatusExt.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include diff --git a/src/Interpreters/getHeaderForProcessingStage.cpp b/src/Interpreters/getHeaderForProcessingStage.cpp index 19837cc05d9..1510b477725 100644 --- a/src/Interpreters/getHeaderForProcessingStage.cpp +++ b/src/Interpreters/getHeaderForProcessingStage.cpp @@ -3,8 +3,8 @@ #include #include #include -#include #include +#include namespace DB { @@ -120,9 +120,9 @@ Block getHeaderForProcessingStage( TreeRewriterResult new_rewriter_result = *query_info.syntax_analyzer_result; removeJoin(*query->as(), new_rewriter_result, context); - auto stream = std::make_shared( - metadata_snapshot->getSampleBlockForColumns(column_names, storage.getVirtuals(), storage.getStorageID())); - return InterpreterSelectQuery(query, context, stream, SelectQueryOptions(processed_stage).analyze()).getSampleBlock(); + auto pipe = Pipe(std::make_shared( + metadata_snapshot->getSampleBlockForColumns(column_names, storage.getVirtuals(), storage.getStorageID()))); + return InterpreterSelectQuery(query, context, std::move(pipe), SelectQueryOptions(processed_stage).analyze()).getSampleBlock(); } } throw Exception("Logical Error: unknown processed stage.", ErrorCodes::LOGICAL_ERROR); diff --git a/src/Processors/Merges/Algorithms/CollapsingSortedAlgorithm.h b/src/Processors/Merges/Algorithms/CollapsingSortedAlgorithm.h index 18ebaad5596..f457af05bd5 100644 --- a/src/Processors/Merges/Algorithms/CollapsingSortedAlgorithm.h +++ b/src/Processors/Merges/Algorithms/CollapsingSortedAlgorithm.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include namespace Poco { diff --git a/src/Processors/Merges/Algorithms/MergingSortedAlgorithm.cpp b/src/Processors/Merges/Algorithms/MergingSortedAlgorithm.cpp index 511bd9dd74f..6b2f0f571a1 100644 --- a/src/Processors/Merges/Algorithms/MergingSortedAlgorithm.cpp +++ b/src/Processors/Merges/Algorithms/MergingSortedAlgorithm.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include namespace DB diff --git a/src/Processors/Merges/Algorithms/ReplacingSortedAlgorithm.h b/src/Processors/Merges/Algorithms/ReplacingSortedAlgorithm.h index 7a193470f89..ca3bbd9d757 100644 --- a/src/Processors/Merges/Algorithms/ReplacingSortedAlgorithm.h +++ b/src/Processors/Merges/Algorithms/ReplacingSortedAlgorithm.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include namespace Poco { diff --git a/src/Processors/Merges/Algorithms/VersionedCollapsingAlgorithm.h b/src/Processors/Merges/Algorithms/VersionedCollapsingAlgorithm.h index 6e859d86020..2226762d541 100644 --- a/src/Processors/Merges/Algorithms/VersionedCollapsingAlgorithm.h +++ b/src/Processors/Merges/Algorithms/VersionedCollapsingAlgorithm.h @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include namespace DB diff --git a/src/Processors/Merges/MergingSortedTransform.cpp b/src/Processors/Merges/MergingSortedTransform.cpp index 62c7f4f762f..667972e3cf6 100644 --- a/src/Processors/Merges/MergingSortedTransform.cpp +++ b/src/Processors/Merges/MergingSortedTransform.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/src/Processors/Sources/SourceFromInputStream.cpp b/src/Processors/Sources/SourceFromInputStream.cpp index 7c88c6dfbeb..57e449370a5 100644 --- a/src/Processors/Sources/SourceFromInputStream.cpp +++ b/src/Processors/Sources/SourceFromInputStream.cpp @@ -1,7 +1,6 @@ #include #include #include -#include namespace DB { @@ -109,10 +108,6 @@ void SourceFromInputStream::work() if (is_stream_finished) return; - /// Don't cancel for RemoteBlockInputStream (otherwise readSuffix can stack) - if (!typeid_cast(stream.get())) - stream->cancel(false); - if (rows_before_limit) { const auto & info = stream->getProfileInfo(); diff --git a/src/DataStreams/ColumnGathererStream.cpp b/src/Processors/Transforms/ColumnGathererTransform.cpp similarity index 98% rename from src/DataStreams/ColumnGathererStream.cpp rename to src/Processors/Transforms/ColumnGathererTransform.cpp index 9b2fac79bb0..ddb8a5a0d68 100644 --- a/src/DataStreams/ColumnGathererStream.cpp +++ b/src/Processors/Transforms/ColumnGathererTransform.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/DataStreams/ColumnGathererStream.h b/src/Processors/Transforms/ColumnGathererTransform.h similarity index 100% rename from src/DataStreams/ColumnGathererStream.h rename to src/Processors/Transforms/ColumnGathererTransform.h diff --git a/src/DataStreams/DistinctSortedBlockInputStream.cpp b/src/Processors/Transforms/DistinctSortedTransform.cpp similarity index 98% rename from src/DataStreams/DistinctSortedBlockInputStream.cpp rename to src/Processors/Transforms/DistinctSortedTransform.cpp index 47421941b45..01cef654388 100644 --- a/src/DataStreams/DistinctSortedBlockInputStream.cpp +++ b/src/Processors/Transforms/DistinctSortedTransform.cpp @@ -1,4 +1,4 @@ -#include +#include namespace DB { diff --git a/src/DataStreams/DistinctSortedBlockInputStream.h b/src/Processors/Transforms/DistinctSortedTransform.h similarity index 100% rename from src/DataStreams/DistinctSortedBlockInputStream.h rename to src/Processors/Transforms/DistinctSortedTransform.h diff --git a/src/DataStreams/MongoDBSource.cpp b/src/Processors/Transforms/MongoDBSource.cpp similarity index 100% rename from src/DataStreams/MongoDBSource.cpp rename to src/Processors/Transforms/MongoDBSource.cpp diff --git a/src/DataStreams/MongoDBSource.h b/src/Processors/Transforms/MongoDBSource.h similarity index 100% rename from src/DataStreams/MongoDBSource.h rename to src/Processors/Transforms/MongoDBSource.h diff --git a/src/DataStreams/PostgreSQLSource.cpp b/src/Processors/Transforms/PostgreSQLSource.cpp similarity index 100% rename from src/DataStreams/PostgreSQLSource.cpp rename to src/Processors/Transforms/PostgreSQLSource.cpp diff --git a/src/DataStreams/PostgreSQLSource.h b/src/Processors/Transforms/PostgreSQLSource.h similarity index 100% rename from src/DataStreams/PostgreSQLSource.h rename to src/Processors/Transforms/PostgreSQLSource.h diff --git a/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/src/Processors/Transforms/buildPushingToViewsChain.cpp similarity index 99% rename from src/DataStreams/PushingToViewsBlockOutputStream.cpp rename to src/Processors/Transforms/buildPushingToViewsChain.cpp index dac4c0620cb..e5abc3bd416 100644 --- a/src/DataStreams/PushingToViewsBlockOutputStream.cpp +++ b/src/Processors/Transforms/buildPushingToViewsChain.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/src/DataStreams/PushingToViewsBlockOutputStream.h b/src/Processors/Transforms/buildPushingToViewsChain.h similarity index 100% rename from src/DataStreams/PushingToViewsBlockOutputStream.h rename to src/Processors/Transforms/buildPushingToViewsChain.h diff --git a/src/Storages/MergeTree/MergeTask.cpp b/src/Storages/MergeTree/MergeTask.cpp index 0810d45a805..357659b3bbb 100644 --- a/src/Storages/MergeTree/MergeTask.cpp +++ b/src/Storages/MergeTree/MergeTask.cpp @@ -20,12 +20,9 @@ #include "Processors/Merges/AggregatingSortedTransform.h" #include "Processors/Merges/VersionedCollapsingTransform.h" #include "Processors/Executors/PipelineExecutingBlockInputStream.h" -#include "DataStreams/DistinctSortedBlockInputStream.h" #include "DataStreams/TTLBlockInputStream.h" #include -#include -#include -#include +#include namespace DB { diff --git a/src/Storages/MergeTree/MergeTask.h b/src/Storages/MergeTree/MergeTask.h index aceca912cea..05903f94c91 100644 --- a/src/Storages/MergeTree/MergeTask.h +++ b/src/Storages/MergeTree/MergeTask.h @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index b35a41d5d19..903f4cd27fc 100644 --- a/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -17,11 +17,7 @@ #include #include -#include -#include -#include -#include -#include +#include #include #include #include diff --git a/src/Storages/MergeTree/MutateTask.cpp b/src/Storages/MergeTree/MutateTask.cpp index e38342e21dd..b8941fc9d84 100644 --- a/src/Storages/MergeTree/MutateTask.cpp +++ b/src/Storages/MergeTree/MutateTask.cpp @@ -4,10 +4,8 @@ #include #include #include -#include -#include -#include -#include +#include +#include #include #include #include diff --git a/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp b/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp index 6eb0c568725..873a4b4860c 100644 --- a/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp +++ b/src/Storages/PostgreSQL/PostgreSQLReplicationHandler.cpp @@ -1,6 +1,6 @@ #include "PostgreSQLReplicationHandler.h" -#include +#include #include #include #include diff --git a/src/Storages/StorageMongoDB.cpp b/src/Storages/StorageMongoDB.cpp index 2a1f7cc2aa9..5521b9de39c 100644 --- a/src/Storages/StorageMongoDB.cpp +++ b/src/Storages/StorageMongoDB.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace DB { diff --git a/src/Storages/StoragePostgreSQL.cpp b/src/Storages/StoragePostgreSQL.cpp index 47a3e4091f5..edb4713a60e 100644 --- a/src/Storages/StoragePostgreSQL.cpp +++ b/src/Storages/StoragePostgreSQL.cpp @@ -1,7 +1,7 @@ #include "StoragePostgreSQL.h" #if USE_LIBPQXX -#include +#include #include #include diff --git a/src/Storages/StorageReplicatedMergeTree.cpp b/src/Storages/StorageReplicatedMergeTree.cpp index 50c7fe0610d..416d37cd351 100644 --- a/src/Storages/StorageReplicatedMergeTree.cpp +++ b/src/Storages/StorageReplicatedMergeTree.cpp @@ -60,7 +60,6 @@ #include #include -#include #include #include diff --git a/src/Storages/StorageS3Cluster.cpp b/src/Storages/StorageS3Cluster.cpp index e4ae27e43bf..c9a0a4873c3 100644 --- a/src/Storages/StorageS3Cluster.cpp +++ b/src/Storages/StorageS3Cluster.cpp @@ -11,7 +11,6 @@ #include "Client/Connection.h" #include "Core/QueryProcessingStage.h" #include -#include "DataStreams/RemoteBlockInputStream.h" #include #include #include @@ -32,6 +31,7 @@ #include #include "Processors/Sources/SourceWithProgress.h" #include +#include #include #include #include diff --git a/src/Storages/getStructureOfRemoteTable.cpp b/src/Storages/getStructureOfRemoteTable.cpp index fb828b8f744..639692beda5 100644 --- a/src/Storages/getStructureOfRemoteTable.cpp +++ b/src/Storages/getStructureOfRemoteTable.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include @@ -71,17 +71,16 @@ ColumnsDescription getStructureOfRemoteTableInShard( }; /// Execute remote query without restrictions (because it's not real user query, but part of implementation) - auto input = std::make_shared(shard_info.pool, query, sample_block, new_context); - input->setPoolMode(PoolMode::GET_ONE); + RemoteQueryExecutor executor(shard_info.pool, query, sample_block, new_context); + executor.setPoolMode(PoolMode::GET_ONE); if (!table_func_ptr) - input->setMainTable(table_id); - input->readPrefix(); + executor.setMainTable(table_id); const DataTypeFactory & data_type_factory = DataTypeFactory::instance(); ParserExpression expr_parser; - while (Block current = input->read()) + while (Block current = executor.read()) { ColumnPtr name = current.getByName("name").column; ColumnPtr type = current.getByName("type").column; @@ -111,6 +110,7 @@ ColumnsDescription getStructureOfRemoteTableInShard( } } + executor.finish(); return res; } diff --git a/src/Storages/tests/gtest_row_source_bits_test.cpp b/src/Storages/tests/gtest_row_source_bits_test.cpp index a6d9179c106..0e7db4b8ab8 100644 --- a/src/Storages/tests/gtest_row_source_bits_test.cpp +++ b/src/Storages/tests/gtest_row_source_bits_test.cpp @@ -1,6 +1,6 @@ #include -#include +#include using DB::RowSourcePart; diff --git a/src/TableFunctions/TableFunctionS3Cluster.cpp b/src/TableFunctions/TableFunctionS3Cluster.cpp index 313ad9d4dcc..160fc3c2468 100644 --- a/src/TableFunctions/TableFunctionS3Cluster.cpp +++ b/src/TableFunctions/TableFunctionS3Cluster.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include #include From e157d22ef7bb762d7f2f9e88b8aa48447af266b1 Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Fri, 8 Oct 2021 18:25:25 +0300 Subject: [PATCH 085/264] Update test.py --- tests/integration/test_settings_profile/test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/integration/test_settings_profile/test.py b/tests/integration/test_settings_profile/test.py index 78efe7ffcad..048d09daaa5 100644 --- a/tests/integration/test_settings_profile/test.py +++ b/tests/integration/test_settings_profile/test.py @@ -203,11 +203,11 @@ def test_show_profiles(): assert instance.query( "SHOW CREATE SETTINGS PROFILE default") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" assert instance.query( - "SHOW CREATE PROFILES") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" \ + "SHOW CREATE PROFILES") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" \ "CREATE SETTINGS PROFILE readonly SETTINGS readonly = 1\n" \ "CREATE SETTINGS PROFILE xyz\n" - expected_access = "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" \ + expected_access = "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" \ "CREATE SETTINGS PROFILE readonly SETTINGS readonly = 1\n" \ "CREATE SETTINGS PROFILE xyz\n" assert expected_access in instance.query("SHOW ACCESS") From c6bce1a4cf73c0796050188e3b1bdbc6bc53ce81 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 20:21:19 +0300 Subject: [PATCH 086/264] Update Native. --- src/Client/Connection.cpp | 49 ++++- src/Client/Connection.h | 31 +-- ...eBlockInputStream.cpp => NativeReader.cpp} | 22 +-- ...ativeBlockInputStream.h => NativeReader.h} | 16 +- ...BlockOutputStream.cpp => NativeWriter.cpp} | 8 +- ...tiveBlockOutputStream.h => NativeWriter.h} | 14 +- src/DataStreams/TemporaryFileStream.cpp | 13 +- src/DataStreams/TemporaryFileStream.h | 3 +- src/Formats/FormatFactory.cpp | 4 - src/Formats/NativeFormat.cpp | 81 +++++++- src/Formats/registerFormats.cpp | 4 - src/Interpreters/Aggregator.cpp | 6 +- src/Interpreters/Aggregator.h | 3 +- src/Processors/Formats/Impl/NativeFormat.h | 179 ------------------ .../Sources/SourceFromSingleChunk.cpp | 26 +++ .../Sources/SourceFromSingleChunk.h | 4 +- .../Transforms/AggregatingTransform.cpp | 8 +- .../Transforms/MergeSortingTransform.cpp | 15 +- .../Transforms/SortingTransform.cpp | 4 +- src/Server/TCPHandler.cpp | 12 +- src/Server/TCPHandler.h | 8 +- src/Storages/Distributed/DirectoryMonitor.cpp | 21 +- src/Storages/Distributed/DistributedSink.cpp | 8 +- src/Storages/MergeTree/DataPartsExchange.cpp | 10 +- .../MergeTree/MergeTreeWriteAheadLog.cpp | 4 +- .../MergeTree/MergeTreeWriteAheadLog.h | 6 +- src/Storages/StorageJoin.cpp | 2 +- src/Storages/StorageSet.cpp | 17 +- src/Storages/StorageStripeLog.cpp | 9 +- utils/wal-dump/main.cpp | 4 +- 30 files changed, 245 insertions(+), 346 deletions(-) rename src/DataStreams/{NativeBlockInputStream.cpp => NativeReader.cpp} (91%) rename src/DataStreams/{NativeBlockInputStream.h => NativeReader.h} (86%) rename src/DataStreams/{NativeBlockOutputStream.cpp => NativeWriter.cpp} (95%) rename src/DataStreams/{NativeBlockOutputStream.h => NativeWriter.h} (78%) delete mode 100644 src/Processors/Formats/Impl/NativeFormat.h create mode 100644 src/Processors/Sources/SourceFromSingleChunk.cpp diff --git a/src/Client/Connection.cpp b/src/Client/Connection.cpp index 7324e08bc4c..2aa157bb318 100644 --- a/src/Client/Connection.cpp +++ b/src/Client/Connection.cpp @@ -9,8 +9,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -58,6 +58,35 @@ namespace ErrorCodes extern const int EMPTY_DATA_PASSED; } +Connection::~Connection() = default; + +Connection::Connection(const String & host_, UInt16 port_, + const String & default_database_, + const String & user_, const String & password_, + const String & cluster_, + const String & cluster_secret_, + const String & client_name_, + Protocol::Compression compression_, + Protocol::Secure secure_, + Poco::Timespan sync_request_timeout_) + : host(host_), port(port_), default_database(default_database_) + , user(user_), password(password_) + , cluster(cluster_) + , cluster_secret(cluster_secret_) + , client_name(client_name_) + , compression(compression_) + , secure(secure_) + , sync_request_timeout(sync_request_timeout_) + , log_wrapper(*this) +{ + /// Don't connect immediately, only on first need. + + if (user.empty()) + user = "default"; + + setDescription(); +} + void Connection::connect(const ConnectionTimeouts & timeouts) { @@ -533,11 +562,11 @@ void Connection::sendData(const Block & block, const String & name, bool scalar) if (!block_out) { if (compression == Protocol::Compression::Enable) - maybe_compressed_out = std::make_shared(*out, compression_codec); + maybe_compressed_out = std::make_unique(*out, compression_codec); else maybe_compressed_out = out; - block_out = std::make_shared(*maybe_compressed_out, server_revision, block.cloneEmpty()); + block_out = std::make_unique(*maybe_compressed_out, server_revision, block.cloneEmpty()); } if (scalar) @@ -866,18 +895,18 @@ Packet Connection::receivePacket() Block Connection::receiveData() { initBlockInput(); - return receiveDataImpl(block_in); + return receiveDataImpl(*block_in); } Block Connection::receiveLogData() { initBlockLogsInput(); - return receiveDataImpl(block_logs_in); + return receiveDataImpl(*block_logs_in); } -Block Connection::receiveDataImpl(BlockInputStreamPtr & stream) +Block Connection::receiveDataImpl(NativeReader & reader) { String external_table_name; readStringBinary(external_table_name, *in); @@ -885,7 +914,7 @@ Block Connection::receiveDataImpl(BlockInputStreamPtr & stream) size_t prev_bytes = in->count(); /// Read one block from network. - Block res = stream->read(); + Block res = reader.read(); if (throttler) throttler->add(in->count() - prev_bytes); @@ -912,7 +941,7 @@ void Connection::initBlockInput() maybe_compressed_in = in; } - block_in = std::make_shared(*maybe_compressed_in, server_revision); + block_in = std::make_unique(*maybe_compressed_in, server_revision); } } @@ -922,7 +951,7 @@ void Connection::initBlockLogsInput() if (!block_logs_in) { /// Have to return superset of SystemLogsQueue::getSampleBlock() columns - block_logs_in = std::make_shared(*in, server_revision); + block_logs_in = std::make_unique(*in, server_revision); } } diff --git a/src/Client/Connection.h b/src/Client/Connection.h index 84ce6edac73..a5130d876ea 100644 --- a/src/Client/Connection.h +++ b/src/Client/Connection.h @@ -32,6 +32,9 @@ struct ConnectionParameters; using ConnectionPtr = std::shared_ptr; using Connections = std::vector; +class NativeReader; +class NativeWriter; + /** Connection with database server, to use by client. * How to use - see Core/Protocol.h @@ -53,25 +56,9 @@ public: const String & client_name_, Protocol::Compression compression_, Protocol::Secure secure_, - Poco::Timespan sync_request_timeout_ = Poco::Timespan(DBMS_DEFAULT_SYNC_REQUEST_TIMEOUT_SEC, 0)) - : - host(host_), port(port_), default_database(default_database_), - user(user_), password(password_), - cluster(cluster_), - cluster_secret(cluster_secret_), - client_name(client_name_), - compression(compression_), - secure(secure_), - sync_request_timeout(sync_request_timeout_), - log_wrapper(*this) - { - /// Don't connect immediately, only on first need. + Poco::Timespan sync_request_timeout_ = Poco::Timespan(DBMS_DEFAULT_SYNC_REQUEST_TIMEOUT_SEC, 0)); - if (user.empty()) - user = "default"; - - setDescription(); - } + ~Connection() override; static ServerConnectionPtr createConnection(const ConnectionParameters & parameters, ContextPtr context); @@ -217,12 +204,12 @@ private: /// From where to read query execution result. std::shared_ptr maybe_compressed_in; - BlockInputStreamPtr block_in; - BlockInputStreamPtr block_logs_in; + std::unique_ptr block_in; + std::unique_ptr block_logs_in; /// Where to write data for INSERT. std::shared_ptr maybe_compressed_out; - BlockOutputStreamPtr block_out; + std::unique_ptr block_out; /// Logger is created lazily, for avoid to run DNS request in constructor. class LoggerWrapper @@ -261,7 +248,7 @@ private: Block receiveData(); Block receiveLogData(); - Block receiveDataImpl(BlockInputStreamPtr & stream); + Block receiveDataImpl(NativeReader & reader); std::vector receiveMultistringMessage(UInt64 msg_type) const; std::unique_ptr receiveException() const; diff --git a/src/DataStreams/NativeBlockInputStream.cpp b/src/DataStreams/NativeReader.cpp similarity index 91% rename from src/DataStreams/NativeBlockInputStream.cpp rename to src/DataStreams/NativeReader.cpp index 2fb661260f0..92c37a3f764 100644 --- a/src/DataStreams/NativeBlockInputStream.cpp +++ b/src/DataStreams/NativeReader.cpp @@ -8,7 +8,7 @@ #include #include -#include +#include #include @@ -23,17 +23,17 @@ namespace ErrorCodes } -NativeBlockInputStream::NativeBlockInputStream(ReadBuffer & istr_, UInt64 server_revision_) +NativeReader::NativeReader(ReadBuffer & istr_, UInt64 server_revision_) : istr(istr_), server_revision(server_revision_) { } -NativeBlockInputStream::NativeBlockInputStream(ReadBuffer & istr_, const Block & header_, UInt64 server_revision_) +NativeReader::NativeReader(ReadBuffer & istr_, const Block & header_, UInt64 server_revision_) : istr(istr_), header(header_), server_revision(server_revision_) { } -NativeBlockInputStream::NativeBlockInputStream(ReadBuffer & istr_, UInt64 server_revision_, +NativeReader::NativeReader(ReadBuffer & istr_, UInt64 server_revision_, IndexForNativeFormat::Blocks::const_iterator index_block_it_, IndexForNativeFormat::Blocks::const_iterator index_block_end_) : istr(istr_), server_revision(server_revision_), @@ -57,7 +57,7 @@ NativeBlockInputStream::NativeBlockInputStream(ReadBuffer & istr_, UInt64 server } // also resets few vars from IBlockInputStream (I didn't want to propagate resetParser upthere) -void NativeBlockInputStream::resetParser() +void NativeReader::resetParser() { istr_concrete = nullptr; use_index = false; @@ -67,11 +67,11 @@ void NativeBlockInputStream::resetParser() read_suffix_is_called = false; #endif - is_cancelled.store(false); - is_killed.store(false); + // is_cancelled.store(false); + // is_killed.store(false); } -void NativeBlockInputStream::readData(const IDataType & type, ColumnPtr & column, ReadBuffer & istr, size_t rows, double avg_value_size_hint) +void NativeReader::readData(const IDataType & type, ColumnPtr & column, ReadBuffer & istr, size_t rows, double avg_value_size_hint) { ISerialization::DeserializeBinaryBulkSettings settings; settings.getter = [&](ISerialization::SubstreamPath) -> ReadBuffer * { return &istr; }; @@ -91,13 +91,13 @@ void NativeBlockInputStream::readData(const IDataType & type, ColumnPtr & column } -Block NativeBlockInputStream::getHeader() const +Block NativeReader::getHeader() const { return header; } -Block NativeBlockInputStream::readImpl() +Block NativeReader::read() { Block res; @@ -215,7 +215,7 @@ Block NativeBlockInputStream::readImpl() return res; } -void NativeBlockInputStream::updateAvgValueSizeHints(const Block & block) +void NativeReader::updateAvgValueSizeHints(const Block & block) { auto rows = block.rows(); if (rows < 10) diff --git a/src/DataStreams/NativeBlockInputStream.h b/src/DataStreams/NativeReader.h similarity index 86% rename from src/DataStreams/NativeBlockInputStream.h rename to src/DataStreams/NativeReader.h index 8f3d2843e0f..cfd58bde2cc 100644 --- a/src/DataStreams/NativeBlockInputStream.h +++ b/src/DataStreams/NativeReader.h @@ -57,32 +57,28 @@ struct IndexForNativeFormat * Can also be used to store data on disk. * In this case, can use the index. */ -class NativeBlockInputStream : public IBlockInputStream +class NativeReader { public: /// If a non-zero server_revision is specified, additional block information may be expected and read. - NativeBlockInputStream(ReadBuffer & istr_, UInt64 server_revision_); + NativeReader(ReadBuffer & istr_, UInt64 server_revision_); /// For cases when data structure (header) is known in advance. /// NOTE We may use header for data validation and/or type conversions. It is not implemented. - NativeBlockInputStream(ReadBuffer & istr_, const Block & header_, UInt64 server_revision_); + NativeReader(ReadBuffer & istr_, const Block & header_, UInt64 server_revision_); /// For cases when we have an index. It allows to skip columns. Only columns specified in the index will be read. - NativeBlockInputStream(ReadBuffer & istr_, UInt64 server_revision_, + NativeReader(ReadBuffer & istr_, UInt64 server_revision_, IndexForNativeFormat::Blocks::const_iterator index_block_it_, IndexForNativeFormat::Blocks::const_iterator index_block_end_); - String getName() const override { return "Native"; } - static void readData(const IDataType & type, ColumnPtr & column, ReadBuffer & istr, size_t rows, double avg_value_size_hint); - Block getHeader() const override; + Block getHeader() const; void resetParser(); - -protected: - Block readImpl() override; + Block read(); private: ReadBuffer & istr; diff --git a/src/DataStreams/NativeBlockOutputStream.cpp b/src/DataStreams/NativeWriter.cpp similarity index 95% rename from src/DataStreams/NativeBlockOutputStream.cpp rename to src/DataStreams/NativeWriter.cpp index 2bd41094147..6e26c443e29 100644 --- a/src/DataStreams/NativeBlockOutputStream.cpp +++ b/src/DataStreams/NativeWriter.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include @@ -20,7 +20,7 @@ namespace ErrorCodes } -NativeBlockOutputStream::NativeBlockOutputStream( +NativeWriter::NativeWriter( WriteBuffer & ostr_, UInt64 client_revision_, const Block & header_, bool remove_low_cardinality_, WriteBuffer * index_ostr_, size_t initial_size_of_file_) : ostr(ostr_), client_revision(client_revision_), header(header_), @@ -35,7 +35,7 @@ NativeBlockOutputStream::NativeBlockOutputStream( } -void NativeBlockOutputStream::flush() +void NativeWriter::flush() { ostr.next(); } @@ -62,7 +62,7 @@ static void writeData(const IDataType & type, const ColumnPtr & column, WriteBuf } -void NativeBlockOutputStream::write(const Block & block) +void NativeWriter::write(const Block & block) { /// Additional information about the block. if (client_revision > 0) diff --git a/src/DataStreams/NativeBlockOutputStream.h b/src/DataStreams/NativeWriter.h similarity index 78% rename from src/DataStreams/NativeBlockOutputStream.h rename to src/DataStreams/NativeWriter.h index 7ff6c8dfa33..67fc179b620 100644 --- a/src/DataStreams/NativeBlockOutputStream.h +++ b/src/DataStreams/NativeWriter.h @@ -1,8 +1,8 @@ #pragma once -#include #include #include +#include namespace DB { @@ -17,20 +17,20 @@ class CompressedWriteBuffer; * A stream can be specified to write the index. The index contains offsets to each part of each column. * If an `append` is made to an existing file, and you need to write the index, then specify `initial_size_of_file`. */ -class NativeBlockOutputStream : public IBlockOutputStream +class NativeWriter { public: /** If non-zero client_revision is specified, additional block information can be written. */ - NativeBlockOutputStream( + NativeWriter( WriteBuffer & ostr_, UInt64 client_revision_, const Block & header_, bool remove_low_cardinality_ = false, WriteBuffer * index_ostr_ = nullptr, size_t initial_size_of_file_ = 0); - Block getHeader() const override { return header; } - void write(const Block & block) override; - void flush() override; + Block getHeader() const { return header; } + void write(const Block & block); + void flush(); - String getContentType() const override { return "application/octet-stream"; } + static String getContentType() { return "application/octet-stream"; } private: WriteBuffer & ostr; diff --git a/src/DataStreams/TemporaryFileStream.cpp b/src/DataStreams/TemporaryFileStream.cpp index a57ad6ed243..826cf5508d8 100644 --- a/src/DataStreams/TemporaryFileStream.cpp +++ b/src/DataStreams/TemporaryFileStream.cpp @@ -1,7 +1,7 @@ #include #include -#include -#include +#include +#include #include #include #include @@ -17,13 +17,13 @@ namespace DB TemporaryFileStream::TemporaryFileStream(const std::string & path) : file_in(path) , compressed_in(file_in) - , block_in(std::make_shared(compressed_in, DBMS_TCP_PROTOCOL_VERSION)) + , block_in(std::make_unique(compressed_in, DBMS_TCP_PROTOCOL_VERSION)) {} TemporaryFileStream::TemporaryFileStream(const std::string & path, const Block & header_) : file_in(path) , compressed_in(file_in) - , block_in(std::make_shared(compressed_in, header_, 0)) + , block_in(std::make_unique(compressed_in, header_, 0)) {} /// Flush data from input stream into file for future reading @@ -31,18 +31,15 @@ void TemporaryFileStream::write(const std::string & path, const Block & header, { WriteBufferFromFile file_buf(path); CompressedWriteBuffer compressed_buf(file_buf, CompressionCodecFactory::instance().get(codec, {})); - NativeBlockOutputStream output(compressed_buf, 0, header); + NativeWriter output(compressed_buf, 0, header); auto pipeline = QueryPipelineBuilder::getPipeline(std::move(builder)); PullingPipelineExecutor executor(pipeline); - output.writePrefix(); - Block block; while (executor.pull(block)) output.write(block); - output.writeSuffix(); compressed_buf.finalize(); } diff --git a/src/DataStreams/TemporaryFileStream.h b/src/DataStreams/TemporaryFileStream.h index f87e32eee48..c0c13605928 100644 --- a/src/DataStreams/TemporaryFileStream.h +++ b/src/DataStreams/TemporaryFileStream.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace DB { @@ -14,7 +15,7 @@ struct TemporaryFileStream { ReadBufferFromFile file_in; CompressedReadBuffer compressed_in; - BlockInputStreamPtr block_in; + std::unique_ptr block_in; explicit TemporaryFileStream(const std::string & path); TemporaryFileStream(const std::string & path, const Block & header_); diff --git a/src/Formats/FormatFactory.cpp b/src/Formats/FormatFactory.cpp index d9ae718dbd9..9901081d7dd 100644 --- a/src/Formats/FormatFactory.cpp +++ b/src/Formats/FormatFactory.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -138,9 +137,6 @@ InputFormatPtr FormatFactory::getInput( UInt64 max_block_size, const std::optional & _format_settings) const { - if (name == "Native") - return std::make_shared(sample, buf); - auto format_settings = _format_settings ? *_format_settings : getFormatSettings(context); diff --git a/src/Formats/NativeFormat.cpp b/src/Formats/NativeFormat.cpp index f9cafbe5459..45a6853b3af 100644 --- a/src/Formats/NativeFormat.cpp +++ b/src/Formats/NativeFormat.cpp @@ -1,33 +1,96 @@ -#include -#include +#include +#include #include +#include +#include namespace DB { + +class NativeInputFormat final : public IInputFormat +{ +public: + NativeInputFormat(ReadBuffer & buf, const Block & header) + : IInputFormat(header, buf) + , reader(buf, header) {} + + String getName() const override { return "Native"; } + + void resetParser() override + { + reader.resetParser(); + } + + Chunk generate() override + { + auto block = reader.read(); + + assertBlocksHaveEqualStructure(getPort().getHeader(), block, getName()); + block.checkNumberOfRows(); + + size_t num_rows = block.rows(); + return Chunk(block.getColumns(), num_rows); + } + +private: + NativeReader reader; +}; + +class NativeOutputFormat final : public IOutputFormat +{ +public: + NativeOutputFormat(WriteBuffer & buf, const Block & header) + : IOutputFormat(header, buf) + , writer(buf, 0, header) + { + } + + String getName() const override { return "Native"; } + + std::string getContentType() const override + { + return writer.getContentType(); + } + +protected: + void consume(Chunk chunk) override + { + if (chunk) + { + + auto block = getPort(PortKind::Main).getHeader(); + block.setColumns(chunk.detachColumns()); + writer.write(block); + } + } + +private: + NativeWriter writer; +}; + void registerInputFormatNative(FormatFactory & factory) { - factory.registerInputFormat("Native", []( + factory.registerInputFormatProcessor("Native", []( ReadBuffer & buf, const Block & sample, - UInt64 /* max_block_size */, - FormatFactory::ReadCallback /* callback */, + const RowInputFormatParams &, const FormatSettings &) { - return std::make_shared(buf, sample, 0); + return std::make_shared(buf, sample); }); } void registerOutputFormatNative(FormatFactory & factory) { - factory.registerOutputFormat("Native", []( + factory.registerOutputFormatProcessor("Native", []( WriteBuffer & buf, const Block & sample, - FormatFactory::WriteCallback, + const RowOutputFormatParams &, const FormatSettings &) { - return std::make_shared(buf, 0, sample); + return std::make_shared(buf, sample); }); } diff --git a/src/Formats/registerFormats.cpp b/src/Formats/registerFormats.cpp index de479c07bae..2686022980f 100644 --- a/src/Formats/registerFormats.cpp +++ b/src/Formats/registerFormats.cpp @@ -21,8 +21,6 @@ void registerFileSegmentationEngineJSONAsString(FormatFactory & factory); void registerInputFormatNative(FormatFactory & factory); void registerOutputFormatNative(FormatFactory & factory); -void registerInputFormatProcessorNative(FormatFactory & factory); -void registerOutputFormatProcessorNative(FormatFactory & factory); void registerInputFormatProcessorRowBinary(FormatFactory & factory); void registerOutputFormatProcessorRowBinary(FormatFactory & factory); void registerInputFormatProcessorTabSeparated(FormatFactory & factory); @@ -96,8 +94,6 @@ void registerFormats() registerInputFormatNative(factory); registerOutputFormatNative(factory); - registerInputFormatProcessorNative(factory); - registerOutputFormatProcessorNative(factory); registerInputFormatProcessorRowBinary(factory); registerOutputFormatProcessorRowBinary(factory); registerInputFormatProcessorTabSeparated(factory); diff --git a/src/Interpreters/Aggregator.cpp b/src/Interpreters/Aggregator.cpp index 8763b04dde1..63e3577af55 100644 --- a/src/Interpreters/Aggregator.cpp +++ b/src/Interpreters/Aggregator.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include @@ -1068,7 +1068,7 @@ void Aggregator::writeToTemporaryFile(AggregatedDataVariants & data_variants, co const std::string & path = file->path(); WriteBufferFromFile file_buf(path); CompressedWriteBuffer compressed_buf(file_buf); - NativeBlockOutputStream block_out(compressed_buf, DBMS_TCP_PROTOCOL_VERSION, getHeader(false)); + NativeWriter block_out(compressed_buf, DBMS_TCP_PROTOCOL_VERSION, getHeader(false)); LOG_DEBUG(log, "Writing part of aggregation data into temporary file {}.", path); ProfileEvents::increment(ProfileEvents::ExternalAggregationWritePart); @@ -1193,7 +1193,7 @@ template void Aggregator::writeToTemporaryFileImpl( AggregatedDataVariants & data_variants, Method & method, - IBlockOutputStream & out) const + NativeWriter & out) const { size_t max_temporary_block_size_rows = 0; size_t max_temporary_block_size_bytes = 0; diff --git a/src/Interpreters/Aggregator.h b/src/Interpreters/Aggregator.h index 1524453ab34..85ce83868c6 100644 --- a/src/Interpreters/Aggregator.h +++ b/src/Interpreters/Aggregator.h @@ -853,6 +853,7 @@ using ManyAggregatedDataVariants = std::vector; using ManyAggregatedDataVariantsPtr = std::shared_ptr; class CompiledAggregateFunctionsHolder; +class NativeWriter; /** How are "total" values calculated with WITH TOTALS? * (For more details, see TotalsHavingTransform.) @@ -1150,7 +1151,7 @@ private: void writeToTemporaryFileImpl( AggregatedDataVariants & data_variants, Method & method, - IBlockOutputStream & out) const; + NativeWriter & out) const; /// Merge NULL key data from hash table `src` into `dst`. template diff --git a/src/Processors/Formats/Impl/NativeFormat.h b/src/Processors/Formats/Impl/NativeFormat.h deleted file mode 100644 index 4757274e1c9..00000000000 --- a/src/Processors/Formats/Impl/NativeFormat.h +++ /dev/null @@ -1,179 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - - -namespace DB -{ - -class NativeInputFormatFromNativeBlockInputStream : public IInputFormat -{ -public: - NativeInputFormatFromNativeBlockInputStream(const Block & header, ReadBuffer & in_) - : IInputFormat(header, in_) - , stream(std::make_shared(*in, header, 0)) - { - } - - String getName() const override { return "NativeInputFormatFromNativeBlockInputStream"; } - -protected: - void resetParser() override - { - IInputFormat::resetParser(); - stream->resetParser(); - read_prefix = false; - read_suffix = false; - } - - - Chunk generate() override - { - /// TODO: do something with totals and extremes. - - if (!read_prefix) - { - stream->readPrefix(); - read_prefix = true; - } - - auto block = stream->read(); - if (!block) - { - if (!read_suffix) - { - stream->readSuffix(); - read_suffix = true; - } - - return Chunk(); - } - - assertBlocksHaveEqualStructure(getPort().getHeader(), block, getName()); - block.checkNumberOfRows(); - - UInt64 num_rows = block.rows(); - return Chunk(block.getColumns(), num_rows); - } - -private: - std::shared_ptr stream; - bool read_prefix = false; - bool read_suffix = false; -}; - - -class NativeOutputFormatFromNativeBlockOutputStream : public IOutputFormat -{ -public: - NativeOutputFormatFromNativeBlockOutputStream(const Block & header, WriteBuffer & out_) - : IOutputFormat(header, out_) - , stream(std::make_shared(out, 0, header)) - { - } - - String getName() const override { return "NativeOutputFormatFromNativeBlockOutputStream"; } - - void setRowsBeforeLimit(size_t rows_before_limit) override - { - stream->setRowsBeforeLimit(rows_before_limit); - } - - void onProgress(const Progress & progress) override - { - stream->onProgress(progress); - } - - std::string getContentType() const override - { - return stream->getContentType(); - } - -protected: - void consume(Chunk chunk) override - { - writePrefixIfNot(); - - if (chunk) - { - - auto block = getPort(PortKind::Main).getHeader(); - block.setColumns(chunk.detachColumns()); - stream->write(block); - } - } - - void consumeTotals(Chunk chunk) override - { - writePrefixIfNot(); - - auto block = getPort(PortKind::Totals).getHeader(); - block.setColumns(chunk.detachColumns()); - stream->setTotals(block); - } - - void consumeExtremes(Chunk chunk) override - { - writePrefixIfNot(); - - auto block = getPort(PortKind::Extremes).getHeader(); - block.setColumns(chunk.detachColumns()); - stream->setExtremes(block); - } - - void finalize() override - { - writePrefixIfNot(); - writeSuffixIfNot(); - } - -private: - std::shared_ptr stream; - bool prefix_written = false; - bool suffix_written = false; - - void writePrefixIfNot() - { - if (!prefix_written) - stream->writePrefix(); - - prefix_written = true; - } - - void writeSuffixIfNot() - { - if (!suffix_written) - stream->writeSuffix(); - - suffix_written = true; - } -}; - -void registerInputFormatProcessorNative(FormatFactory & factory) -{ - factory.registerInputFormatProcessor("Native", []( - ReadBuffer & buf, - const Block & sample, - const RowInputFormatParams &, - const FormatSettings &) - { - return std::make_shared(sample, buf); - }); -} - -void registerOutputFormatProcessorNative(FormatFactory & factory) -{ - factory.registerOutputFormatProcessor("Native", []( - WriteBuffer & buf, - const Block & sample, - const RowOutputFormatParams &, - const FormatSettings &) - { - return std::make_shared(sample, buf); - }); -} - -} diff --git a/src/Processors/Sources/SourceFromSingleChunk.cpp b/src/Processors/Sources/SourceFromSingleChunk.cpp new file mode 100644 index 00000000000..776ed98599f --- /dev/null +++ b/src/Processors/Sources/SourceFromSingleChunk.cpp @@ -0,0 +1,26 @@ +#include +#include +#include + +namespace DB +{ + +SourceFromSingleChunk::SourceFromSingleChunk(Block header, Chunk chunk_) : SourceWithProgress(std::move(header)), chunk(std::move(chunk_)) {} +SourceFromSingleChunk::SourceFromSingleChunk(Block data) : SourceWithProgress(data.cloneEmpty()), chunk(data.getColumns(), data.rows()) +{ + const auto & sample = getPort().getHeader(); + bool has_aggregate_functions = false; + for (auto & type : sample.getDataTypes()) + if (typeid_cast(type.get())) + has_aggregate_functions = true; + + if (has_aggregate_functions) + { + auto info = std::make_shared(); + info->bucket_num = data.info.bucket_num; + info->is_overflows = data.info.is_overflows; + chunk.setChunkInfo(std::move(info)); + } +} + +} diff --git a/src/Processors/Sources/SourceFromSingleChunk.h b/src/Processors/Sources/SourceFromSingleChunk.h index 8268fa5b0a6..e06387b556f 100644 --- a/src/Processors/Sources/SourceFromSingleChunk.h +++ b/src/Processors/Sources/SourceFromSingleChunk.h @@ -8,8 +8,8 @@ namespace DB class SourceFromSingleChunk : public SourceWithProgress { public: - explicit SourceFromSingleChunk(Block header, Chunk chunk_) : SourceWithProgress(std::move(header)), chunk(std::move(chunk_)) {} - explicit SourceFromSingleChunk(Block data) : SourceWithProgress(data.cloneEmpty()), chunk(data.getColumns(), data.rows()) {} + explicit SourceFromSingleChunk(Block header, Chunk chunk_); + explicit SourceFromSingleChunk(Block data); String getName() const override { return "SourceFromSingleChunk"; } protected: diff --git a/src/Processors/Transforms/AggregatingTransform.cpp b/src/Processors/Transforms/AggregatingTransform.cpp index 7e5480c37ca..9011d188b81 100644 --- a/src/Processors/Transforms/AggregatingTransform.cpp +++ b/src/Processors/Transforms/AggregatingTransform.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include @@ -56,9 +56,8 @@ namespace public: SourceFromNativeStream(const Block & header, const std::string & path) : ISource(header), file_in(path), compressed_in(file_in), - block_in(std::make_shared(compressed_in, DBMS_TCP_PROTOCOL_VERSION)) + block_in(std::make_unique(compressed_in, DBMS_TCP_PROTOCOL_VERSION)) { - block_in->readPrefix(); } String getName() const override { return "SourceFromNativeStream"; } @@ -71,7 +70,6 @@ namespace auto block = block_in->read(); if (!block) { - block_in->readSuffix(); block_in.reset(); return {}; } @@ -82,7 +80,7 @@ namespace private: ReadBufferFromFile file_in; CompressedReadBuffer compressed_in; - BlockInputStreamPtr block_in; + std::unique_ptr block_in; }; } diff --git a/src/Processors/Transforms/MergeSortingTransform.cpp b/src/Processors/Transforms/MergeSortingTransform.cpp index ca78a29071e..6e379a3c4ba 100644 --- a/src/Processors/Transforms/MergeSortingTransform.cpp +++ b/src/Processors/Transforms/MergeSortingTransform.cpp @@ -6,8 +6,8 @@ #include #include #include -#include -#include +#include +#include #include @@ -33,11 +33,10 @@ public: BufferingToFileTransform(const Block & header, Poco::Logger * log_, std::string path_) : IAccumulatingTransform(header, header), log(log_) , path(std::move(path_)), file_buf_out(path), compressed_buf_out(file_buf_out) - , out_stream(std::make_shared(compressed_buf_out, 0, header)) + , out_stream(std::make_unique(compressed_buf_out, 0, header)) { LOG_INFO(log, "Sorting and writing part of data into temporary file {}", path); ProfileEvents::increment(ProfileEvents::ExternalSortWritePart); - out_stream->writePrefix(); } String getName() const override { return "BufferingToFileTransform"; } @@ -51,7 +50,6 @@ public: { if (out_stream) { - out_stream->writeSuffix(); compressed_buf_out.next(); file_buf_out.next(); LOG_INFO(log, "Done writing part of data into temporary file {}", path); @@ -60,7 +58,7 @@ public: file_in = std::make_unique(path); compressed_in = std::make_unique(*file_in); - block_in = std::make_shared(*compressed_in, getOutputPort().getHeader(), 0); + block_in = std::make_unique(*compressed_in, getOutputPort().getHeader(), 0); } if (!block_in) @@ -69,7 +67,6 @@ public: auto block = block_in->read(); if (!block) { - block_in->readSuffix(); block_in.reset(); return {}; } @@ -83,11 +80,11 @@ private: std::string path; WriteBufferFromFile file_buf_out; CompressedWriteBuffer compressed_buf_out; - BlockOutputStreamPtr out_stream; + std::unique_ptr out_stream; std::unique_ptr file_in; std::unique_ptr compressed_in; - BlockInputStreamPtr block_in; + std::unique_ptr block_in; }; MergeSortingTransform::MergeSortingTransform( diff --git a/src/Processors/Transforms/SortingTransform.cpp b/src/Processors/Transforms/SortingTransform.cpp index 11f23530c9e..2c9098adaa6 100644 --- a/src/Processors/Transforms/SortingTransform.cpp +++ b/src/Processors/Transforms/SortingTransform.cpp @@ -9,8 +9,8 @@ #include #include -#include -#include +#include +#include namespace ProfileEvents diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index cbb055e956c..f3247e7bc2b 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -16,8 +16,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -1369,7 +1369,7 @@ bool TCPHandler::receiveUnexpectedData(bool throw_exception) else maybe_compressed_in = in; - auto skip_block_in = std::make_shared(*maybe_compressed_in, client_tcp_protocol_version); + auto skip_block_in = std::make_shared(*maybe_compressed_in, client_tcp_protocol_version); bool read_ok = skip_block_in->read(); if (!read_ok) @@ -1399,7 +1399,7 @@ void TCPHandler::initBlockInput() else if (state.need_receive_data_for_input) header = state.input_header; - state.block_in = std::make_shared( + state.block_in = std::make_unique( *state.maybe_compressed_in, header, client_tcp_protocol_version); @@ -1430,7 +1430,7 @@ void TCPHandler::initBlockOutput(const Block & block) state.maybe_compressed_out = out; } - state.block_out = std::make_shared( + state.block_out = std::make_unique( *state.maybe_compressed_out, client_tcp_protocol_version, block.cloneEmpty(), @@ -1444,7 +1444,7 @@ void TCPHandler::initLogsBlockOutput(const Block & block) { /// Use uncompressed stream since log blocks usually contain only one row const Settings & query_settings = query_context->getSettingsRef(); - state.logs_block_out = std::make_shared( + state.logs_block_out = std::make_unique( *out, client_tcp_protocol_version, block.cloneEmpty(), diff --git a/src/Server/TCPHandler.h b/src/Server/TCPHandler.h index 624031b60b7..d001b12ee66 100644 --- a/src/Server/TCPHandler.h +++ b/src/Server/TCPHandler.h @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "IServer.h" @@ -44,15 +46,15 @@ struct QueryState /// destroyed after input/output blocks, because they may contain other /// threads that use this queue. InternalTextLogsQueuePtr logs_queue; - BlockOutputStreamPtr logs_block_out; + std::unique_ptr logs_block_out; /// From where to read data for INSERT. std::shared_ptr maybe_compressed_in; - BlockInputStreamPtr block_in; + std::unique_ptr block_in; /// Where to write result data. std::shared_ptr maybe_compressed_out; - BlockOutputStreamPtr block_out; + std::unique_ptr block_out; Block block_for_insert; /// Query text. diff --git a/src/Storages/Distributed/DirectoryMonitor.cpp b/src/Storages/Distributed/DirectoryMonitor.cpp index 433776ffb08..167e36ebbe3 100644 --- a/src/Storages/Distributed/DirectoryMonitor.cpp +++ b/src/Storages/Distributed/DirectoryMonitor.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -189,7 +189,7 @@ namespace if (header_buf.hasPendingData()) { - NativeBlockInputStream header_block_in(header_buf, DBMS_TCP_PROTOCOL_VERSION); + NativeReader header_block_in(header_buf, DBMS_TCP_PROTOCOL_VERSION); distributed_header.block_header = header_block_in.read(); if (!distributed_header.block_header) throw Exception(ErrorCodes::CANNOT_READ_ALL_DATA, "Cannot read header from the {} batch", in.getFileName()); @@ -268,8 +268,7 @@ namespace void writeAndConvert(RemoteInserter & remote, ReadBufferFromFile & in) { CompressedReadBuffer decompressing_in(in); - NativeBlockInputStream block_in(decompressing_in, DBMS_TCP_PROTOCOL_VERSION); - block_in.readPrefix(); + NativeReader block_in(decompressing_in, DBMS_TCP_PROTOCOL_VERSION); while (Block block = block_in.read()) { @@ -282,8 +281,6 @@ namespace converting_actions->execute(block); remote.write(block); } - - block_in.readSuffix(); } void writeRemoteConvert( @@ -909,7 +906,7 @@ public: { std::unique_ptr in; std::unique_ptr decompressing_in; - std::unique_ptr block_in; + std::unique_ptr block_in; Poco::Logger * log = nullptr; @@ -919,12 +916,11 @@ public: { in = std::make_unique(file_name); decompressing_in = std::make_unique(*in); - block_in = std::make_unique(*decompressing_in, DBMS_TCP_PROTOCOL_VERSION); + block_in = std::make_unique(*decompressing_in, DBMS_TCP_PROTOCOL_VERSION); log = &Poco::Logger::get("DirectoryMonitorSource"); readDistributedHeader(*in, log); - block_in->readPrefix(); first_block = block_in->read(); } @@ -957,10 +953,7 @@ protected: auto block = data.block_in->read(); if (!block) - { - data.block_in->readSuffix(); return {}; - } size_t num_rows = block.rows(); return Chunk(block.getColumns(), num_rows); @@ -1048,8 +1041,7 @@ void StorageDistributedDirectoryMonitor::processFilesWithBatching(const std::map LOG_DEBUG(log, "Processing batch {} with old format (no header/rows)", in.getFileName()); CompressedReadBuffer decompressing_in(in); - NativeBlockInputStream block_in(decompressing_in, DBMS_TCP_PROTOCOL_VERSION); - block_in.readPrefix(); + NativeReader block_in(decompressing_in, DBMS_TCP_PROTOCOL_VERSION); while (Block block = block_in.read()) { @@ -1059,7 +1051,6 @@ void StorageDistributedDirectoryMonitor::processFilesWithBatching(const std::map if (!header) header = block.cloneEmpty(); } - block_in.readSuffix(); } } catch (const Exception & e) diff --git a/src/Storages/Distributed/DistributedSink.cpp b/src/Storages/Distributed/DistributedSink.cpp index ad828e786b4..1841be22b72 100644 --- a/src/Storages/Distributed/DistributedSink.cpp +++ b/src/Storages/Distributed/DistributedSink.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -707,7 +707,7 @@ void DistributedSink::writeToShard(const Block & block, const std::vector -#include +#include #include #include #include @@ -222,7 +222,7 @@ void Service::sendPartFromMemory( writeStringBinary(name, out); projection->checksums.write(out); - NativeBlockOutputStream block_out(out, 0, projection_sample_block); + NativeWriter block_out(out, 0, projection_sample_block); block_out.write(part_in_memory->block); } @@ -230,7 +230,7 @@ void Service::sendPartFromMemory( if (!part_in_memory) throw Exception("Part " + part->name + " is not stored in memory", ErrorCodes::LOGICAL_ERROR); - NativeBlockOutputStream block_out(out, 0, metadata_snapshot->getSampleBlock()); + NativeWriter block_out(out, 0, metadata_snapshot->getSampleBlock()); part->checksums.write(out); block_out.write(part_in_memory->block); @@ -569,7 +569,7 @@ MergeTreeData::MutableDataPartPtr Fetcher::downloadPartToMemory( if (!checksums.read(in)) throw Exception("Cannot deserialize checksums", ErrorCodes::CORRUPTED_DATA); - NativeBlockInputStream block_in(in, 0); + NativeReader block_in(in, 0); auto block = block_in.read(); throttler->add(block.bytes()); @@ -599,7 +599,7 @@ MergeTreeData::MutableDataPartPtr Fetcher::downloadPartToMemory( if (!checksums.read(in)) throw Exception("Cannot deserialize checksums", ErrorCodes::CORRUPTED_DATA); - NativeBlockInputStream block_in(in, 0); + NativeReader block_in(in, 0); auto block = block_in.read(); throttler->add(block.bytes()); diff --git a/src/Storages/MergeTree/MergeTreeWriteAheadLog.cpp b/src/Storages/MergeTree/MergeTreeWriteAheadLog.cpp index 2c1d785236c..28f25296a7b 100644 --- a/src/Storages/MergeTree/MergeTreeWriteAheadLog.cpp +++ b/src/Storages/MergeTree/MergeTreeWriteAheadLog.cpp @@ -57,7 +57,7 @@ void MergeTreeWriteAheadLog::init() /// Small hack: in NativeBlockOutputStream header is used only in `getHeader` method. /// To avoid complex logic of changing it during ALTERs we leave it empty. - block_out = std::make_unique(*out, 0, Block{}); + block_out = std::make_unique(*out, 0, Block{}); min_block_number = std::numeric_limits::max(); max_block_number = -1; bytes_at_last_sync = 0; @@ -119,7 +119,7 @@ MergeTreeData::MutableDataPartsVector MergeTreeWriteAheadLog::restore(const Stor MergeTreeData::MutableDataPartsVector parts; auto in = disk->readFile(path, {}, 0); - NativeBlockInputStream block_in(*in, 0); + NativeReader block_in(*in, 0); NameSet dropped_parts; while (!in->eof()) diff --git a/src/Storages/MergeTree/MergeTreeWriteAheadLog.h b/src/Storages/MergeTree/MergeTreeWriteAheadLog.h index 8d1ea3c332e..7624dc303e0 100644 --- a/src/Storages/MergeTree/MergeTreeWriteAheadLog.h +++ b/src/Storages/MergeTree/MergeTreeWriteAheadLog.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #include #include #include @@ -78,7 +78,7 @@ private: String path; std::unique_ptr out; - std::unique_ptr block_out; + std::unique_ptr block_out; Int64 min_block_number = std::numeric_limits::max(); Int64 max_block_number = -1; diff --git a/src/Storages/StorageJoin.cpp b/src/Storages/StorageJoin.cpp index 2acdba18c2d..1353c8d67aa 100644 --- a/src/Storages/StorageJoin.cpp +++ b/src/Storages/StorageJoin.cpp @@ -107,7 +107,7 @@ void StorageJoin::mutate(const MutationCommands & commands, ContextPtr context) auto backup_buf = disk->writeFile(path + tmp_backup_file_name); auto compressed_backup_buf = CompressedWriteBuffer(*backup_buf); - auto backup_stream = NativeBlockOutputStream(compressed_backup_buf, 0, metadata_snapshot->getSampleBlock()); + auto backup_stream = NativeWriter(compressed_backup_buf, 0, metadata_snapshot->getSampleBlock()); auto new_data = std::make_shared(table_join, metadata_snapshot->getSampleBlock().sortColumns(), overwrite); diff --git a/src/Storages/StorageSet.cpp b/src/Storages/StorageSet.cpp index fe55123335a..58c56f1401f 100644 --- a/src/Storages/StorageSet.cpp +++ b/src/Storages/StorageSet.cpp @@ -4,8 +4,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -54,7 +54,7 @@ private: String backup_file_name; std::unique_ptr backup_buf; CompressedWriteBuffer compressed_backup_buf; - NativeBlockOutputStream backup_stream; + NativeWriter backup_stream; bool persistent; }; @@ -212,19 +212,20 @@ void StorageSetOrJoinBase::restoreFromFile(const String & file_path) { auto backup_buf = disk->readFile(file_path); CompressedReadBuffer compressed_backup_buf(*backup_buf); - NativeBlockInputStream backup_stream(compressed_backup_buf, 0); - - backup_stream.readPrefix(); + NativeReader backup_stream(compressed_backup_buf, 0); + BlockStreamProfileInfo info; while (Block block = backup_stream.read()) + { + info.update(block); insertBlock(block); + } finishInsert(); - backup_stream.readSuffix(); /// TODO Add speed, compressed bytes, data volume in memory, compression ratio ... Generalize all statistics logging in project. LOG_INFO(&Poco::Logger::get("StorageSetOrJoinBase"), "Loaded from backup file {}. {} rows, {}. State has {} unique rows.", - file_path, backup_stream.getProfileInfo().rows, ReadableSize(backup_stream.getProfileInfo().bytes), getSize()); + file_path, info.rows, ReadableSize(info.bytes), getSize()); } diff --git a/src/Storages/StorageStripeLog.cpp b/src/Storages/StorageStripeLog.cpp index f1ab365e458..2dc2577f245 100644 --- a/src/Storages/StorageStripeLog.cpp +++ b/src/Storages/StorageStripeLog.cpp @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include #include @@ -136,7 +136,7 @@ private: */ bool started = false; std::optional data_in; - std::optional block_in; + std::optional block_in; void start() { @@ -214,7 +214,6 @@ public: if (done) return; - block_out.writeSuffix(); data_out->next(); data_out_compressed->next(); data_out_compressed->finalize(); @@ -245,7 +244,7 @@ private: String index_out_file; std::unique_ptr index_out_compressed; std::unique_ptr index_out; - NativeBlockOutputStream block_out; + NativeWriter block_out; bool done = false; }; diff --git a/utils/wal-dump/main.cpp b/utils/wal-dump/main.cpp index 361aa9df887..0e47c39fb5a 100644 --- a/utils/wal-dump/main.cpp +++ b/utils/wal-dump/main.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -21,7 +21,7 @@ static void dump(const std::string & bin_path) { DB::ReadBufferFromFile in(bin_path); - DB::NativeBlockInputStream block_in(in, 0); + DB::NativeReader block_in(in, 0); DB::Block block; DB::WriteBufferFromFileDescriptor out(STDOUT_FILENO); From 1f6d5482b1452673275d19d1423b01956665e95e Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 21:33:51 +0300 Subject: [PATCH 087/264] Fix some tests. --- src/Formats/NativeFormat.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Formats/NativeFormat.cpp b/src/Formats/NativeFormat.cpp index 45a6853b3af..b94cb279412 100644 --- a/src/Formats/NativeFormat.cpp +++ b/src/Formats/NativeFormat.cpp @@ -3,6 +3,7 @@ #include #include #include +#include namespace DB @@ -14,18 +15,21 @@ class NativeInputFormat final : public IInputFormat public: NativeInputFormat(ReadBuffer & buf, const Block & header) : IInputFormat(header, buf) - , reader(buf, header) {} + , reader(buf, header, 0) {} String getName() const override { return "Native"; } void resetParser() override { + IInputFormat::resetParser(); reader.resetParser(); } Chunk generate() override { auto block = reader.read(); + if (!block) + return {}; assertBlocksHaveEqualStructure(getPort().getHeader(), block, getName()); block.checkNumberOfRows(); @@ -59,8 +63,16 @@ protected: { if (chunk) { - auto block = getPort(PortKind::Main).getHeader(); + + // const auto & info = chunk.getChunkInfo(); + // const auto * agg_info = typeid_cast(info.get()); + // if (agg_info) + // { + // block.info.bucket_num = agg_info->bucket_num; + // block.info.is_overflows = agg_info->is_overflows; + // } + block.setColumns(chunk.detachColumns()); writer.write(block); } From 21bdc12b9c7269036b6ca62425a90b98c0422111 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 21:38:12 +0300 Subject: [PATCH 088/264] Pull libcxx --- contrib/libcxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libcxx b/contrib/libcxx index 2fa892f69ac..61e60294b1d 160000 --- a/contrib/libcxx +++ b/contrib/libcxx @@ -1 +1 @@ -Subproject commit 2fa892f69acbaa40f8a18c6484854a6183a34482 +Subproject commit 61e60294b1de01483caa9f5d00f437c99b674de6 From 2ad2f20176bb16d536217c0ad1f1737fbd1479fc Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 21:55:09 +0300 Subject: [PATCH 089/264] Add NOLINT --- src/Core/examples/coro.cpp | 58 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Core/examples/coro.cpp b/src/Core/examples/coro.cpp index a9728314495..e3a990e228d 100644 --- a/src/Core/examples/coro.cpp +++ b/src/Core/examples/coro.cpp @@ -27,11 +27,11 @@ namespace std template -struct suspend_value +struct suspend_value // NOLINT(readability-identifier-naming) { - constexpr bool await_ready() const noexcept { return true; } - constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} - constexpr T await_resume() const noexcept + constexpr bool await_ready() const noexcept { return true; } // NOLINT(readability-identifier-naming) + constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} // NOLINT(readability-identifier-naming) + constexpr T await_resume() const noexcept // NOLINT(readability-identifier-naming) { std::cout << " ret " << val << std::endl; return val; @@ -41,57 +41,57 @@ struct suspend_value }; template -struct resumable +struct Task { - struct promise_type + struct promise_type // NOLINT(readability-identifier-naming) { using coro_handle = std::coroutine_handle; - auto get_return_object() { return coro_handle::from_promise(*this); } - auto initial_suspend() { return std::suspend_never(); } - auto final_suspend() noexcept { return suspend_value{*r->value}; } + auto get_return_object() { return coro_handle::from_promise(*this); } // NOLINT(readability-identifier-naming) + auto initial_suspend() { return std::suspend_never(); } // NOLINT(readability-identifier-naming) + auto final_suspend() noexcept { return suspend_value{*r->value}; } // NOLINT(readability-identifier-naming) //void return_void() {} - void return_value(T value_) { r->value = value_; } - void unhandled_exception() + void return_value(T value_) { r->value = value_; } // NOLINT(readability-identifier-naming) + void unhandled_exception() // NOLINT(readability-identifier-naming) { DB::tryLogCurrentException("Logger"); - r->exception = std::current_exception(); + r->exception = std::current_exception(); // NOLINT(bugprone-throw-keyword-missing) } explicit promise_type(std::string tag_) : tag(tag_) {} ~promise_type() { std::cout << "~promise_type " << tag << std::endl; } std::string tag; coro_handle next; - resumable * r = nullptr; + Task * r = nullptr; }; using coro_handle = std::coroutine_handle; - bool await_ready() const noexcept { return false; } - void await_suspend(coro_handle g) noexcept + bool await_ready() const noexcept { return false; } // NOLINT(readability-identifier-naming) + void await_suspend(coro_handle g) noexcept // NOLINT(readability-identifier-naming) { std::cout << " await_suspend " << my.promise().tag << std::endl; std::cout << " g tag " << g.promise().tag << std::endl; g.promise().next = my; } - T await_resume() noexcept + T await_resume() noexcept // NOLINT(readability-identifier-naming) { std::cout << " await_res " << my.promise().tag << std::endl; return *value; } - resumable(coro_handle handle) : my(handle), tag(handle.promise().tag) + explicit Task(coro_handle handle) : my(handle), tag(handle.promise().tag) { assert(handle); my.promise().r = this; - std::cout << " resumable " << tag << std::endl; + std::cout << " Task " << tag << std::endl; } - resumable(resumable &) = delete; - resumable(resumable &&rhs) : my(rhs.my), tag(rhs.tag) + Task(Task &) = delete; + Task(Task &&rhs) : my(rhs.my), tag(rhs.tag) { rhs.my = {}; - std::cout << " resumable&& " << tag << std::endl; + std::cout << " Task&& " << tag << std::endl; } - static bool resume_impl(resumable *r) + static bool resumeImpl(Task *r) { if (r->value) return false; @@ -100,7 +100,7 @@ struct resumable if (next) { - if (resume_impl(next.promise().r)) + if (resumeImpl(next.promise().r)) return true; next = {}; } @@ -116,7 +116,7 @@ struct resumable bool resume() { - return resume_impl(this); + return resumeImpl(this); } T res() @@ -124,9 +124,9 @@ struct resumable return *value; } - ~resumable() + ~Task() { - std::cout << " ~resumable " << tag << std::endl; + std::cout << " ~Task " << tag << std::endl; } private: @@ -136,7 +136,7 @@ private: std::exception_ptr exception; }; -resumable boo([[maybe_unused]] std::string tag) +Task boo([[maybe_unused]] std::string tag) { std::cout << "x" << std::endl; co_await std::suspend_always(); @@ -145,7 +145,7 @@ resumable boo([[maybe_unused]] std::string tag) co_return 1; } -resumable bar([[maybe_unused]] std::string tag) +Task bar([[maybe_unused]] std::string tag) { std::cout << "a" << std::endl; int res1 = co_await boo("boo1"); @@ -157,7 +157,7 @@ resumable bar([[maybe_unused]] std::string tag) co_return res1 + res2; // 1 + 1 = 2 } -resumable foo([[maybe_unused]] std::string tag) { +Task foo([[maybe_unused]] std::string tag) { std::cout << "Hello" << std::endl; auto res1 = co_await bar("bar1"); std::cout << "Coro " << res1 << std::endl; From 75af011068122162c87722a05ddb80d30508c6f2 Mon Sep 17 00:00:00 2001 From: vesslanjin Date: Fri, 8 Oct 2021 14:58:23 -0400 Subject: [PATCH 090/264] use while instead of popcnt + for Co-authored-by: Zhu Jasper jasper.zhu@intel.com --- src/Columns/ColumnFixedString.cpp | 9 ++------- src/Columns/ColumnVector.cpp | 9 ++------- src/Columns/ColumnsCommon.cpp | 9 ++------- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/Columns/ColumnFixedString.cpp b/src/Columns/ColumnFixedString.cpp index 1080f29b5aa..ea66ba73d8e 100644 --- a/src/Columns/ColumnFixedString.cpp +++ b/src/Columns/ColumnFixedString.cpp @@ -248,19 +248,14 @@ ColumnPtr ColumnFixedString::filter(const IColumn::Filter & filt, ssize_t result UInt16 mask = _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_cast(filt_pos)), zero16)); mask = ~mask; - if (0 == mask) - { - /// Nothing is inserted. - } - else if (0xFFFF == mask) + if (0xFFFF == mask) { res->chars.insert(data_pos, data_pos + chars_per_simd_elements); } else { size_t res_chars_size = res->chars.size(); - size_t pcnt = __builtin_popcount(mask); - for (size_t j = 0; j < pcnt; ++j) + while(mask) { size_t index = __builtin_ctz(mask); res->chars.resize(res_chars_size + n); diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index 61ba2074bd7..f45b0581213 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -327,18 +327,13 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s UInt16 mask = _mm_movemask_epi8(_mm_cmpeq_epi8(_mm_loadu_si128(reinterpret_cast(filt_pos)), zero16)); mask = ~mask; - if (0 == mask) - { - /// Nothing is inserted. - } - else if (0xFFFF == mask) + if (0xFFFF == mask) { res_data.insert(data_pos, data_pos + SIMD_BYTES); } else { - size_t pcnt = __builtin_popcount(mask); - for (size_t j = 0; j < pcnt; ++j) + while(mask) { size_t index = __builtin_ctz(mask); res_data.push_back(data_pos[index]); diff --git a/src/Columns/ColumnsCommon.cpp b/src/Columns/ColumnsCommon.cpp index b4614abe490..8a6f5c24a32 100644 --- a/src/Columns/ColumnsCommon.cpp +++ b/src/Columns/ColumnsCommon.cpp @@ -241,11 +241,7 @@ namespace zero_vec)); mask = ~mask; - if (mask == 0) - { - /// SIMD_BYTES consecutive rows do not pass the filter - } - else if (mask == 0xffff) + if (mask == 0xffff) { /// SIMD_BYTES consecutive rows pass the filter const auto first = offsets_pos == offsets_begin; @@ -262,8 +258,7 @@ namespace } else { - size_t pcnt = __builtin_popcount(mask); - for (size_t j = 0; j < pcnt; ++j) + while(mask) { size_t index = __builtin_ctz(mask); copy_array(offsets_pos + index); From 7a5cc357ecb6df1ec14b008dbc04d8a14de1776a Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Fri, 8 Oct 2021 22:44:08 +0300 Subject: [PATCH 091/264] Fix style --- src/Core/examples/coro.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Core/examples/coro.cpp b/src/Core/examples/coro.cpp index e3a990e228d..e11d0af9e22 100644 --- a/src/Core/examples/coro.cpp +++ b/src/Core/examples/coro.cpp @@ -1,5 +1,3 @@ -#include - #include #include #include @@ -157,7 +155,8 @@ Task bar([[maybe_unused]] std::string tag) co_return res1 + res2; // 1 + 1 = 2 } -Task foo([[maybe_unused]] std::string tag) { +Task foo([[maybe_unused]] std::string tag) +{ std::cout << "Hello" << std::endl; auto res1 = co_await bar("bar1"); std::cout << "Coro " << res1 << std::endl; From 8513994a659fd287a3a890fcd413cc23cc3d061d Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Fri, 8 Oct 2021 23:51:21 +0300 Subject: [PATCH 092/264] add logging in ZooKeeper client --- src/Common/ZooKeeper/ZooKeeperImpl.cpp | 46 ++++++++++++++++---------- src/Common/ZooKeeper/ZooKeeperImpl.h | 6 ++-- 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.cpp b/src/Common/ZooKeeper/ZooKeeperImpl.cpp index d79a94169b2..cf607a3d70e 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.cpp +++ b/src/Common/ZooKeeper/ZooKeeperImpl.cpp @@ -289,7 +289,7 @@ ZooKeeper::~ZooKeeper() { try { - finalize(false, false); + finalize(false, false, "destructor called"); if (send_thread.joinable()) send_thread.join(); @@ -299,7 +299,7 @@ ZooKeeper::~ZooKeeper() } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } } @@ -317,6 +317,7 @@ ZooKeeper::ZooKeeper( session_timeout(session_timeout_), operation_timeout(std::min(operation_timeout_, session_timeout_)) { + log = &Poco::Logger::get("ZooKeeperClient"); std::atomic_store(&zk_log, std::move(zk_log_)); if (!root_path.empty()) @@ -450,6 +451,10 @@ void ZooKeeper::connect( message << fail_reasons.str() << "\n"; throw Exception(message.str(), Error::ZCONNECTIONLOSS); } + else + { + LOG_TEST(log, "Connected to ZooKeeper at {} with session_id {}", socket.peerAddress().toString(), session_id); + } } @@ -604,8 +609,8 @@ void ZooKeeper::sendThread() } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); - finalize(true, false); + tryLogCurrentException(log); + finalize(true, false, "exception in sendThread"); } } @@ -663,8 +668,8 @@ void ZooKeeper::receiveThread() } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); - finalize(false, true); + tryLogCurrentException(log); + finalize(false, true, "exception in receiveThread"); } } @@ -799,7 +804,7 @@ void ZooKeeper::receiveEvent() } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); /// Unrecoverable. Don't leave incorrect state in memory. if (!response) @@ -819,7 +824,7 @@ void ZooKeeper::receiveEvent() catch (...) { /// Throw initial exception, not exception from callback. - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } throw; @@ -832,10 +837,15 @@ void ZooKeeper::receiveEvent() } -void ZooKeeper::finalize(bool error_send, bool error_receive) +void ZooKeeper::finalize(bool error_send, bool error_receive, const String & reason) { /// If some thread (send/receive) already finalizing session don't try to do it - if (finalization_started.exchange(true)) + bool already_started = finalization_started.exchange(true); + + LOG_TEST(log, "Finalizing session {}: finalization_started={}, queue_closed={}, reason={}", + session_id, already_started, requests_queue.isClosed(), reason); + + if (already_started) return; auto expire_session_if_not_expired = [&] @@ -860,7 +870,7 @@ void ZooKeeper::finalize(bool error_send, bool error_receive) /// This happens for example, when "Cannot push request to queue within operation timeout". /// Just mark session expired in case of error on close request, otherwise sendThread may not stop. expire_session_if_not_expired(); - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } /// Send thread will exit after sending close request or on expired flag @@ -879,7 +889,7 @@ void ZooKeeper::finalize(bool error_send, bool error_receive) catch (...) { /// We must continue to execute all callbacks, because the user is waiting for them. - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } if (!error_receive && receive_thread.joinable()) @@ -908,7 +918,7 @@ void ZooKeeper::finalize(bool error_send, bool error_receive) catch (...) { /// We must continue to all other callbacks, because the user is waiting for them. - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } } } @@ -939,7 +949,7 @@ void ZooKeeper::finalize(bool error_send, bool error_receive) } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } } } @@ -967,7 +977,7 @@ void ZooKeeper::finalize(bool error_send, bool error_receive) } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } } } @@ -983,14 +993,14 @@ void ZooKeeper::finalize(bool error_send, bool error_receive) } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } } } } catch (...) { - tryLogCurrentException(__PRETTY_FUNCTION__); + tryLogCurrentException(log); } } @@ -1028,7 +1038,7 @@ void ZooKeeper::pushRequest(RequestInfo && info) } catch (...) { - finalize(false, false); + finalize(false, false, getCurrentExceptionMessage(false, false, false)); throw; } diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.h b/src/Common/ZooKeeper/ZooKeeperImpl.h index ce37ca7b650..53908e5b0c7 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.h +++ b/src/Common/ZooKeeper/ZooKeeperImpl.h @@ -187,7 +187,7 @@ public: /// it will do read in another session, that read may not see the /// already performed write. - void finalize() override { finalize(false, false); } + void finalize() override { finalize(false, false, "unknown"); } void setZooKeeperLog(std::shared_ptr zk_log_); @@ -240,6 +240,8 @@ private: ThreadFromGlobalPool send_thread; ThreadFromGlobalPool receive_thread; + Poco::Logger * log; + void connect( const Nodes & node, Poco::Timespan connection_timeout); @@ -257,7 +259,7 @@ private: void close(); /// Call all remaining callbacks and watches, passing errors to them. - void finalize(bool error_send, bool error_receive); + void finalize(bool error_send, bool error_receive, const String & reason); template void write(const T &); From e42a687b803ee4b0e514cd1dba9d43b171d45867 Mon Sep 17 00:00:00 2001 From: kssenii Date: Fri, 8 Oct 2021 23:52:15 +0300 Subject: [PATCH 093/264] Fix --- .../test.py | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/tests/integration/test_postgresql_replica_database_engine/test.py b/tests/integration/test_postgresql_replica_database_engine/test.py index 92423598a35..d3ce2295614 100644 --- a/tests/integration/test_postgresql_replica_database_engine/test.py +++ b/tests/integration/test_postgresql_replica_database_engine/test.py @@ -77,7 +77,8 @@ def create_materialized_db(ip, port, materialized_database='test_database', postgres_database='postgres_database', settings=[]): - create_query = "CREATE DATABASE {} ENGINE = MaterializedPostgreSQL('{}:{}', '{}', 'postgres', 'mysecretpassword')".format(materialized_database, ip, port, postgres_database) + instance.query(f"DROP DATABASE IF EXISTS {materialized_database}") + create_query = f"CREATE DATABASE {materialized_database} ENGINE = MaterializedPostgreSQL('{ip}:{port}', '{postgres_database}', 'postgres', 'mysecretpassword')" if len(settings) > 0: create_query += " SETTINGS " for i in range(len(settings)): @@ -131,6 +132,14 @@ def assert_nested_table_is_created(table_name, materialized_database='test_datab assert(table_name in database_tables) +@pytest.mark.timeout(320) +def assert_number_of_columns(expected, table_name, database_name='test_database'): + result = instance.query(f"select count() from system.columns where table = '{table_name}' and database = '{database_name}' and not startsWith(name, '_')") + while (int(result) != expected): + time.sleep(1) + result = instance.query(f"select count() from system.columns where table = '{table_name}' and database = '{database_name}' and not startsWith(name, '_')") + + @pytest.mark.timeout(320) def check_tables_are_synchronized(table_name, order_by='key', postgres_database='postgres_database', materialized_database='test_database'): assert_nested_table_is_created(table_name, materialized_database) @@ -479,27 +488,30 @@ def test_table_schema_changes(started_cluster): expected = instance.query("SELECT key, value1, value3 FROM test_database.postgresql_replica_3 ORDER BY key"); - altered_table = random.randint(0, 4) - cursor.execute("ALTER TABLE postgresql_replica_{} DROP COLUMN value2".format(altered_table)) + altered_idx = random.randint(0, 4) + altered_table = f'postgresql_replica_{altered_idx}' + cursor.execute(f"ALTER TABLE {altered_table} DROP COLUMN value2") for i in range(NUM_TABLES): - cursor.execute("INSERT INTO postgresql_replica_{} VALUES (50, {}, {})".format(i, i, i)) - cursor.execute("UPDATE postgresql_replica_{} SET value3 = 12 WHERE key%2=0".format(i)) + cursor.execute(f"INSERT INTO postgresql_replica_{i} VALUES (50, {i}, {i})") + cursor.execute(f"UPDATE {altered_table} SET value3 = 12 WHERE key%2=0") - assert_nested_table_is_created('postgresql_replica_{}'.format(altered_table)) - check_tables_are_synchronized('postgresql_replica_{}'.format(altered_table)) + time.sleep(2) + assert_nested_table_is_created(altered_table) + assert_number_of_columns(3, altered_table) + check_tables_are_synchronized(altered_table) print('check1 OK') for i in range(NUM_TABLES): check_tables_are_synchronized('postgresql_replica_{}'.format(i)); for i in range(NUM_TABLES): - if i != altered_table: + if i != altered_idx: instance.query("INSERT INTO postgres_database.postgresql_replica_{} SELECT 51 + number, {}, {}, {} from numbers(49)".format(i, i, i, i)) else: instance.query("INSERT INTO postgres_database.postgresql_replica_{} SELECT 51 + number, {}, {} from numbers(49)".format(i, i, i)) - check_tables_are_synchronized('postgresql_replica_{}'.format(altered_table)); + check_tables_are_synchronized(altered_table); print('check2 OK') for i in range(NUM_TABLES): check_tables_are_synchronized('postgresql_replica_{}'.format(i)); @@ -645,6 +657,7 @@ def test_virtual_columns(started_cluster): cursor.execute("ALTER TABLE postgresql_replica_0 ADD COLUMN value2 integer") instance.query("INSERT INTO postgres_database.postgresql_replica_0 SELECT number, number, number from numbers(10, 10)") + assert_number_of_columns(3, 'postgresql_replica_0') check_tables_are_synchronized('postgresql_replica_0'); result = instance.query('SELECT key, value, value2, _sign, _version FROM test_database.postgresql_replica_0;') From 5d6da023bbf590f511a8be1c59d280eba757b068 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 9 Oct 2021 01:42:08 +0300 Subject: [PATCH 094/264] clickhouse-test: fix hung check under stress tests https://clickhouse-test-reports.s3.yandex.net/29856/e2d6698244d43979b3fe2478dfdcd8dc3a91a0fd/stress_test_(address).html#fail1 --- tests/clickhouse-test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/clickhouse-test b/tests/clickhouse-test index 6bbfa97ab66..f00e5574c67 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -87,8 +87,11 @@ class Client(clickhouse_driver.Client): return data # Helpers -def make_clickhouse_client(base_args, *args, **kwargs): +def make_clickhouse_client(base_args): return Client(host=base_args.tcp_host, port=base_args.tcp_port, + # hung check in stress tests may remove the database, + # hence we should use 'system'. + database='system', settings=get_additional_client_options_dict(base_args)) def clickhouse_execute_one(base_args, *args, **kwargs): return make_clickhouse_client(base_args).execute_one(*args, **kwargs) From 42ca2b4bb241827edf69bbd6938d6b19c31935f1 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 9 Oct 2021 01:43:00 +0300 Subject: [PATCH 095/264] clickhouse-test: remove not existing options for pylint https://clickhouse-test-reports.s3.yandex.net/29856/e2d6698244d43979b3fe2478dfdcd8dc3a91a0fd/style_check/test_run.txt.out.log --- tests/clickhouse-test | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/clickhouse-test b/tests/clickhouse-test index f00e5574c67..f10e38b87e5 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -1,11 +1,7 @@ #!/usr/bin/env python3 # pylint: disable=too-many-return-statements -# pylint: disable=consider-using-f-string # pylint: disable=global-variable-not-assigned -# pylint: disable=consider-using-with -# pylint: disable=unspecified-encoding -# pylint: disable=consider-using-min-builtin import enum import shutil From 860f74db623ac3f00aa2811e0de9154fd0f777bc Mon Sep 17 00:00:00 2001 From: taiyang-li <654010905@qq.com> Date: Sat, 9 Oct 2021 11:15:13 +0800 Subject: [PATCH 096/264] remove unused var --- src/Storages/StorageS3Cluster.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Storages/StorageS3Cluster.cpp b/src/Storages/StorageS3Cluster.cpp index e4ae27e43bf..3314571c565 100644 --- a/src/Storages/StorageS3Cluster.cpp +++ b/src/Storages/StorageS3Cluster.cpp @@ -89,7 +89,6 @@ Pipe StorageS3Cluster::read( StorageS3::updateClientAndAuthSettings(context, client_auth); auto cluster = context->getCluster(cluster_name)->getClusterWithReplicasAsShards(context->getSettings()); - S3::URI s3_uri(Poco::URI{filename}); StorageS3::updateClientAndAuthSettings(context, client_auth); auto iterator = std::make_shared(*client_auth.client, client_auth.uri); From 89a52930c68e6c256aa9fe959dd4bb33aaddfc85 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Sat, 9 Oct 2021 11:47:08 +0800 Subject: [PATCH 097/264] Cosmetic refactoring of server constants. --- src/Functions/FunctionConstantBase.h | 17 ++++------------- src/Functions/serverConstants.cpp | 19 +++++++++++-------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/Functions/FunctionConstantBase.h b/src/Functions/FunctionConstantBase.h index 35096a9942f..2d237c77256 100644 --- a/src/Functions/FunctionConstantBase.h +++ b/src/Functions/FunctionConstantBase.h @@ -12,18 +12,9 @@ template class FunctionConstantBase : public IFunction { public: - - /// For server-level constants (uptime(), version(), etc) - explicit FunctionConstantBase(ContextPtr context, T && constant_value_) - : is_distributed(context->isDistributed()) - , constant_value(std::forward(constant_value_)) - { - } - - /// For real constants (pi(), e(), etc) - explicit FunctionConstantBase(const T & constant_value_) - : is_distributed(false) - , constant_value(constant_value_) + template + explicit FunctionConstantBase(U && constant_value_, bool is_distributed_ = false) + : constant_value(std::forward(constant_value_)), is_distributed(is_distributed_) { } @@ -56,8 +47,8 @@ public: } private: - bool is_distributed; const T constant_value; + bool is_distributed; }; } diff --git a/src/Functions/serverConstants.cpp b/src/Functions/serverConstants.cpp index 9a53a5cf582..49d45368439 100644 --- a/src/Functions/serverConstants.cpp +++ b/src/Functions/serverConstants.cpp @@ -24,7 +24,7 @@ namespace public: static constexpr auto name = "buildId"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionBuildId(ContextPtr context) : FunctionConstantBase(context, SymbolIndex::instance()->getBuildIDHex()) {} + explicit FunctionBuildId(ContextPtr context) : FunctionConstantBase(SymbolIndex::instance()->getBuildIDHex(), context->isDistributed()) {} }; #endif @@ -35,7 +35,7 @@ namespace public: static constexpr auto name = "hostName"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionHostName(ContextPtr context) : FunctionConstantBase(context, DNSResolver::instance().getHostName()) {} + explicit FunctionHostName(ContextPtr context) : FunctionConstantBase(DNSResolver::instance().getHostName(), context->isDistributed()) {} }; @@ -44,7 +44,7 @@ namespace public: static constexpr auto name = "serverUUID"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionServerUUID(ContextPtr context) : FunctionConstantBase(context, ServerUUID::get()) {} + explicit FunctionServerUUID(ContextPtr context) : FunctionConstantBase(ServerUUID::get(), context->isDistributed()) {} }; @@ -53,7 +53,7 @@ namespace public: static constexpr auto name = "tcpPort"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionTcpPort(ContextPtr context) : FunctionConstantBase(context, context->getTCPPort()) {} + explicit FunctionTcpPort(ContextPtr context) : FunctionConstantBase(context->getTCPPort(), context->isDistributed()) {} }; @@ -63,7 +63,7 @@ namespace public: static constexpr auto name = "timezone"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionTimezone(ContextPtr context) : FunctionConstantBase(context, String{DateLUT::instance().getTimeZone()}) {} + explicit FunctionTimezone(ContextPtr context) : FunctionConstantBase(String{DateLUT::instance().getTimeZone()}, context->isDistributed()) {} }; @@ -73,7 +73,7 @@ namespace public: static constexpr auto name = "uptime"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionUptime(ContextPtr context) : FunctionConstantBase(context, context->getUptimeSeconds()) {} + explicit FunctionUptime(ContextPtr context) : FunctionConstantBase(context->getUptimeSeconds(), context->isDistributed()) {} }; @@ -83,14 +83,17 @@ namespace public: static constexpr auto name = "version"; static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } - explicit FunctionVersion(ContextPtr context) : FunctionConstantBase(context, VERSION_STRING) {} + explicit FunctionVersion(ContextPtr context) : FunctionConstantBase(VERSION_STRING, context->isDistributed()) {} }; class FunctionZooKeeperSessionUptime : public FunctionConstantBase { public: static constexpr auto name = "zookeeperSessionUptime"; - explicit FunctionZooKeeperSessionUptime(ContextPtr context) : FunctionConstantBase(context, context->getZooKeeperSessionUptime()) {} + explicit FunctionZooKeeperSessionUptime(ContextPtr context) + : FunctionConstantBase(context->getZooKeeperSessionUptime(), context->isDistributed()) + { + } static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } }; } From 5cc379392579978f5f398497c8a494508c2e40b3 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Sat, 9 Oct 2021 11:50:06 +0800 Subject: [PATCH 098/264] Add shutdown_wait_unfinished_queries setting --- programs/server/Server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index cd5d72cfba4..79a41078a77 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -1550,7 +1550,8 @@ if (ThreadFuzzer::instance().isEffective()) LOG_INFO(log, "Closed all listening sockets."); /// Killing remaining queries. - global_context->getProcessList().killAllQueries(); + if (!config().getBool("shutdown_wait_unfinished_queries", false)) + global_context->getProcessList().killAllQueries(); if (current_connections) current_connections = waitServersToFinish(*servers, config().getInt("shutdown_wait_unfinished", 5)); From f7c1e25526eba1d7221f48eed9e6d8dc3263b7d8 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Sat, 9 Oct 2021 09:00:51 +0300 Subject: [PATCH 099/264] Fix tidy --- src/Core/examples/coro.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/examples/coro.cpp b/src/Core/examples/coro.cpp index e11d0af9e22..0f152d8090a 100644 --- a/src/Core/examples/coro.cpp +++ b/src/Core/examples/coro.cpp @@ -77,7 +77,7 @@ struct Task return *value; } - explicit Task(coro_handle handle) : my(handle), tag(handle.promise().tag) + Task(coro_handle handle) : my(handle), tag(handle.promise().tag) // NOLINT(google-explicit-constructor) { assert(handle); my.promise().r = this; From bed09ee68d01da683b685e8b5dbd93925e0c93fb Mon Sep 17 00:00:00 2001 From: vesslanjin Date: Sat, 9 Oct 2021 02:56:10 -0400 Subject: [PATCH 100/264] Whitespace fix Signed-off-by: vesslanjin --- src/Columns/ColumnFixedString.cpp | 2 +- src/Columns/ColumnVector.cpp | 2 +- src/Columns/ColumnsCommon.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Columns/ColumnFixedString.cpp b/src/Columns/ColumnFixedString.cpp index ea66ba73d8e..ab14ea3fb87 100644 --- a/src/Columns/ColumnFixedString.cpp +++ b/src/Columns/ColumnFixedString.cpp @@ -255,7 +255,7 @@ ColumnPtr ColumnFixedString::filter(const IColumn::Filter & filt, ssize_t result else { size_t res_chars_size = res->chars.size(); - while(mask) + while (mask) { size_t index = __builtin_ctz(mask); res->chars.resize(res_chars_size + n); diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index f45b0581213..85218402428 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -333,7 +333,7 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s } else { - while(mask) + while (mask) { size_t index = __builtin_ctz(mask); res_data.push_back(data_pos[index]); diff --git a/src/Columns/ColumnsCommon.cpp b/src/Columns/ColumnsCommon.cpp index 8a6f5c24a32..d2f6883552a 100644 --- a/src/Columns/ColumnsCommon.cpp +++ b/src/Columns/ColumnsCommon.cpp @@ -258,7 +258,7 @@ namespace } else { - while(mask) + while (mask) { size_t index = __builtin_ctz(mask); copy_array(offsets_pos + index); From 939d38b13e20f0878f3a6f4c7d237ee97985945f Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Sat, 9 Oct 2021 10:01:58 +0300 Subject: [PATCH 101/264] Fix gtest build. --- src/Storages/tests/gtest_row_source_bits_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/tests/gtest_row_source_bits_test.cpp b/src/Storages/tests/gtest_row_source_bits_test.cpp index 0e7db4b8ab8..c8ea48ff43c 100644 --- a/src/Storages/tests/gtest_row_source_bits_test.cpp +++ b/src/Storages/tests/gtest_row_source_bits_test.cpp @@ -1,6 +1,6 @@ #include -#include +#include using DB::RowSourcePart; From 2204597cfef8767472f2dd25a6e6972fd45845c7 Mon Sep 17 00:00:00 2001 From: WangZengrui Date: Sat, 9 Oct 2021 16:49:49 +0800 Subject: [PATCH 102/264] add FunctionOSKernelVersion --- .../registerFunctionsMiscellaneous.cpp | 2 ++ src/Functions/serverConstants.cpp | 24 ++++++++++++++ src/Interpreters/getOSKernelVersion.cpp | 31 ------------------- src/Interpreters/getOSKernelVersion.h | 21 ------------- 4 files changed, 26 insertions(+), 52 deletions(-) delete mode 100644 src/Interpreters/getOSKernelVersion.cpp delete mode 100644 src/Interpreters/getOSKernelVersion.h diff --git a/src/Functions/registerFunctionsMiscellaneous.cpp b/src/Functions/registerFunctionsMiscellaneous.cpp index dfd986c5f82..8fc084b3d1a 100644 --- a/src/Functions/registerFunctionsMiscellaneous.cpp +++ b/src/Functions/registerFunctionsMiscellaneous.cpp @@ -81,6 +81,7 @@ void registerFunctionQueryID(FunctionFactory & factory); void registerFunctionInitialQueryID(FunctionFactory & factory); void registerFunctionServerUUID(FunctionFactory &); void registerFunctionZooKeeperSessionUptime(FunctionFactory &); +void registerFunctionOSKernelVersion(FunctionFactory &); #if USE_ICU void registerFunctionConvertCharset(FunctionFactory &); @@ -162,6 +163,7 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory) registerFunctionInitialQueryID(factory); registerFunctionServerUUID(factory); registerFunctionZooKeeperSessionUptime(factory); + registerFunctionOSKernelVersion(factory); #if USE_ICU registerFunctionConvertCharset(factory); diff --git a/src/Functions/serverConstants.cpp b/src/Functions/serverConstants.cpp index 9a53a5cf582..170f4cb86ee 100644 --- a/src/Functions/serverConstants.cpp +++ b/src/Functions/serverConstants.cpp @@ -7,6 +7,10 @@ #include #include +#if defined(OS_LINUX) +# include +#endif + #if !defined(ARCADIA_BUILD) # include #endif @@ -93,6 +97,17 @@ namespace explicit FunctionZooKeeperSessionUptime(ContextPtr context) : FunctionConstantBase(context, context->getZooKeeperSessionUptime()) {} static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } }; + +#if defined(OS_LINUX) + class FunctionOSKernelVersion : public FunctionConstantBase + { + public: + static constexpr auto name = "OSKernelVersion"; + explicit FunctionOSKernelVersion(ContextPtr context) : FunctionConstantBase(context, Poco::Environment::osName() + " " + Poco::Environment::osVersion()) {} + static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } + }; +#endif + } @@ -140,5 +155,14 @@ void registerFunctionZooKeeperSessionUptime(FunctionFactory & factory) factory.registerFunction(); } + +void registerFunctionOSKernelVersion(FunctionFactory & factory) +{ +#if defined(OS_LINUX) + factory.registerFunction(); +#endif +} + + } diff --git a/src/Interpreters/getOSKernelVersion.cpp b/src/Interpreters/getOSKernelVersion.cpp deleted file mode 100644 index c4b4564f46e..00000000000 --- a/src/Interpreters/getOSKernelVersion.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#if defined(OS_LINUX) -#include - - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int SYSTEM_ERROR; -} - -String getOSKernelVersion() -{ - struct utsname os_kernel_info; - int buf = uname(&os_kernel_info); - if (buf < 0) - { - throw Exception( - "EFAULT buffer is not valid.", - ErrorCodes::SYSTEM_ERROR); - } - else - { - return String(os_kernel_info.sysname) + " " + String(os_kernel_info.release); - } -} - -} - -#endif \ No newline at end of file diff --git a/src/Interpreters/getOSKernelVersion.h b/src/Interpreters/getOSKernelVersion.h deleted file mode 100644 index fc3c7583aef..00000000000 --- a/src/Interpreters/getOSKernelVersion.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#if defined(OS_LINUX) - -#include - -#include -#include - -namespace DB -{ - -/// Returns String with OS Kernel version. -/* To get name and information about current kernel. - For simplicity, the function can be implemented only for Linux. -*/ - -String getOSKernelVersion(); - -} - -#endif \ No newline at end of file From fecfcf9b66afa96a3107c5b2debe420c5c894161 Mon Sep 17 00:00:00 2001 From: romanzhukov Date: Sat, 9 Oct 2021 13:17:47 +0300 Subject: [PATCH 103/264] Update metrica.md --- docs/ru/getting-started/example-datasets/metrica.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/getting-started/example-datasets/metrica.md b/docs/ru/getting-started/example-datasets/metrica.md index 15c0cc14517..ee764ff4879 100644 --- a/docs/ru/getting-started/example-datasets/metrica.md +++ b/docs/ru/getting-started/example-datasets/metrica.md @@ -37,7 +37,7 @@ clickhouse-client --query "SELECT COUNT(*) FROM datasets.visits_v1" curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv # создадим таблицу hits_v1 clickhouse-client --query "CREATE DATABASE IF NOT EXISTS datasets" -clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" +clickhouse-client --query "CREATE TABLE datasets.hits_v1 ( WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, ClientIP6 FixedString(16), RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, URLDomain String, RefererDomain String, Refresh UInt8, IsRobot UInt8, RefererCategories Array(UInt16), URLCategories Array(UInt16), URLRegions Array(UInt32), RefererRegions Array(UInt32), ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), UTCEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, GeneralInterests Array(UInt16), RemoteIP UInt32, RemoteIP6 FixedString(16), WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming Int32, DNSTiming Int32, ConnectTiming Int32, ResponseStartTiming Int32, ResponseEndTiming Int32, FetchTiming Int32, RedirectTiming Int32, DOMInteractiveTiming Int32, DOMContentLoadedTiming Int32, DOMCompleteTiming Int32, LoadEventStartTiming Int32, LoadEventEndTiming Int32, NSToDOMContentLoadedTiming Int32, FirstPaintTiming Int32, RedirectCount Int8, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, GoalsReached Array(UInt32), OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32, YCLID UInt64, ShareService String, ShareURL String, ShareTitle String, ParsedParams Nested(Key1 String, Key2 String, Key3 String, Key4 String, Key5 String, ValueDouble Float64), IslandID FixedString(16), RequestNum UInt32, RequestTry UInt8) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" # создадим таблицу hits_100m_obfuscated clickhouse-client --query="CREATE TABLE hits_100m_obfuscated (WatchID UInt64, JavaEnable UInt8, Title String, GoodEvent Int16, EventTime DateTime, EventDate Date, CounterID UInt32, ClientIP UInt32, RegionID UInt32, UserID UInt64, CounterClass Int8, OS UInt8, UserAgent UInt8, URL String, Referer String, Refresh UInt8, RefererCategoryID UInt16, RefererRegionID UInt32, URLCategoryID UInt16, URLRegionID UInt32, ResolutionWidth UInt16, ResolutionHeight UInt16, ResolutionDepth UInt8, FlashMajor UInt8, FlashMinor UInt8, FlashMinor2 String, NetMajor UInt8, NetMinor UInt8, UserAgentMajor UInt16, UserAgentMinor FixedString(2), CookieEnable UInt8, JavascriptEnable UInt8, IsMobile UInt8, MobilePhone UInt8, MobilePhoneModel String, Params String, IPNetworkID UInt32, TraficSourceID Int8, SearchEngineID UInt16, SearchPhrase String, AdvEngineID UInt8, IsArtifical UInt8, WindowClientWidth UInt16, WindowClientHeight UInt16, ClientTimeZone Int16, ClientEventTime DateTime, SilverlightVersion1 UInt8, SilverlightVersion2 UInt8, SilverlightVersion3 UInt32, SilverlightVersion4 UInt16, PageCharset String, CodeVersion UInt32, IsLink UInt8, IsDownload UInt8, IsNotBounce UInt8, FUniqID UInt64, OriginalURL String, HID UInt32, IsOldCounter UInt8, IsEvent UInt8, IsParameter UInt8, DontCountHits UInt8, WithHash UInt8, HitColor FixedString(1), LocalEventTime DateTime, Age UInt8, Sex UInt8, Income UInt8, Interests UInt16, Robotness UInt8, RemoteIP UInt32, WindowName Int32, OpenerName Int32, HistoryLength Int16, BrowserLanguage FixedString(2), BrowserCountry FixedString(2), SocialNetwork String, SocialAction String, HTTPError UInt16, SendTiming UInt32, DNSTiming UInt32, ConnectTiming UInt32, ResponseStartTiming UInt32, ResponseEndTiming UInt32, FetchTiming UInt32, SocialSourceNetworkID UInt8, SocialSourcePage String, ParamPrice Int64, ParamOrderID String, ParamCurrency FixedString(3), ParamCurrencyID UInt16, OpenstatServiceName String, OpenstatCampaignID String, OpenstatAdID String, OpenstatSourceID String, UTMSource String, UTMMedium String, UTMCampaign String, UTMContent String, UTMTerm String, FromTag String, HasGCLID UInt8, RefererHash UInt64, URLHash UInt64, CLID UInt32) ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity = 8192" From 3940382c2f4e84c17eb7b9ff8819eca1a1bc579d Mon Sep 17 00:00:00 2001 From: Vladimir C Date: Sat, 9 Oct 2021 13:34:02 +0300 Subject: [PATCH 104/264] Remove defined(__POPCNT__) from column filter --- src/Columns/ColumnFixedString.cpp | 2 +- src/Columns/ColumnVector.cpp | 2 +- src/Columns/ColumnsCommon.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Columns/ColumnFixedString.cpp b/src/Columns/ColumnFixedString.cpp index ab14ea3fb87..733ecaa979a 100644 --- a/src/Columns/ColumnFixedString.cpp +++ b/src/Columns/ColumnFixedString.cpp @@ -231,7 +231,7 @@ ColumnPtr ColumnFixedString::filter(const IColumn::Filter & filt, ssize_t result const UInt8 * filt_end = filt_pos + col_size; const UInt8 * data_pos = chars.data(); -#if defined(__SSE2__) && defined(__POPCNT__) +#ifdef __SSE2__ /** A slightly more optimized version. * Based on the assumption that often pieces of consecutive values * completely pass or do not pass the filter. diff --git a/src/Columns/ColumnVector.cpp b/src/Columns/ColumnVector.cpp index 85218402428..a769cd93037 100644 --- a/src/Columns/ColumnVector.cpp +++ b/src/Columns/ColumnVector.cpp @@ -311,7 +311,7 @@ ColumnPtr ColumnVector::filter(const IColumn::Filter & filt, ssize_t result_s const UInt8 * filt_end = filt_pos + size; const T * data_pos = data.data(); -#if defined(__SSE2__) && defined(__POPCNT__) +#ifdef __SSE2__ /** A slightly more optimized version. * Based on the assumption that often pieces of consecutive values * completely pass or do not pass the filter. diff --git a/src/Columns/ColumnsCommon.cpp b/src/Columns/ColumnsCommon.cpp index d2f6883552a..a4d7de34382 100644 --- a/src/Columns/ColumnsCommon.cpp +++ b/src/Columns/ColumnsCommon.cpp @@ -229,7 +229,7 @@ namespace memcpy(&res_elems[elems_size_old], &src_elems[arr_offset], arr_size * sizeof(T)); }; - #if defined(__SSE2__) && defined(__POPCNT__) + #ifdef __SSE2__ const __m128i zero_vec = _mm_setzero_si128(); static constexpr size_t SIMD_BYTES = 16; const auto * filt_end_aligned = filt_pos + size / SIMD_BYTES * SIMD_BYTES; From 96a9d99ab658f3e0e0dc4c21bf6f01ebcbe41dbb Mon Sep 17 00:00:00 2001 From: WangZengrui Date: Sat, 9 Oct 2021 19:53:21 +0800 Subject: [PATCH 105/264] add test --- src/Functions/registerFunctionsMiscellaneous.cpp | 4 ++-- src/Functions/serverConstants.cpp | 12 ++++++------ .../02095_function_get_os_kernel_version.reference | 1 + .../02095_function_get_os_kernel_version.sql | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 tests/queries/0_stateless/02095_function_get_os_kernel_version.reference create mode 100644 tests/queries/0_stateless/02095_function_get_os_kernel_version.sql diff --git a/src/Functions/registerFunctionsMiscellaneous.cpp b/src/Functions/registerFunctionsMiscellaneous.cpp index 8fc084b3d1a..dc062ab148a 100644 --- a/src/Functions/registerFunctionsMiscellaneous.cpp +++ b/src/Functions/registerFunctionsMiscellaneous.cpp @@ -81,7 +81,7 @@ void registerFunctionQueryID(FunctionFactory & factory); void registerFunctionInitialQueryID(FunctionFactory & factory); void registerFunctionServerUUID(FunctionFactory &); void registerFunctionZooKeeperSessionUptime(FunctionFactory &); -void registerFunctionOSKernelVersion(FunctionFactory &); +void registerFunctionGetOSKernelVersion(FunctionFactory &); #if USE_ICU void registerFunctionConvertCharset(FunctionFactory &); @@ -163,7 +163,7 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory) registerFunctionInitialQueryID(factory); registerFunctionServerUUID(factory); registerFunctionZooKeeperSessionUptime(factory); - registerFunctionOSKernelVersion(factory); + registerFunctionGetOSKernelVersion(factory); #if USE_ICU registerFunctionConvertCharset(factory); diff --git a/src/Functions/serverConstants.cpp b/src/Functions/serverConstants.cpp index 170f4cb86ee..f92bd6f6653 100644 --- a/src/Functions/serverConstants.cpp +++ b/src/Functions/serverConstants.cpp @@ -99,12 +99,12 @@ namespace }; #if defined(OS_LINUX) - class FunctionOSKernelVersion : public FunctionConstantBase + class FunctionGetOSKernelVersion : public FunctionConstantBase { public: - static constexpr auto name = "OSKernelVersion"; - explicit FunctionOSKernelVersion(ContextPtr context) : FunctionConstantBase(context, Poco::Environment::osName() + " " + Poco::Environment::osVersion()) {} - static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } + static constexpr auto name = "getOSKernelVersion"; + explicit FunctionGetOSKernelVersion(ContextPtr context) : FunctionConstantBase(context, Poco::Environment::osName() + " " + Poco::Environment::osVersion()) {} + static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } }; #endif @@ -156,10 +156,10 @@ void registerFunctionZooKeeperSessionUptime(FunctionFactory & factory) } -void registerFunctionOSKernelVersion(FunctionFactory & factory) +void registerFunctionGetOSKernelVersion([[maybe_unused]] FunctionFactory & factory) { #if defined(OS_LINUX) - factory.registerFunction(); + factory.registerFunction(); #endif } diff --git a/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference b/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference new file mode 100644 index 00000000000..9ec3c4aef9b --- /dev/null +++ b/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference @@ -0,0 +1 @@ +Linux 0 diff --git a/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql b/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql new file mode 100644 index 00000000000..01cd1057d84 --- /dev/null +++ b/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql @@ -0,0 +1 @@ +WITH splitByChar(' ', getOSKernelVersion()) AS version_pair SELECT version_pair[1], toUInt32(splitByChar('.', version_pair[2])[1]) > 3 \ No newline at end of file From b8bde2d4513a5f9f0f8f2ffc563c2eaf6d591e1a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 9 Oct 2021 15:05:21 +0300 Subject: [PATCH 106/264] Fix test_backup_restore after #29649 CI: https://clickhouse-test-reports.s3.yandex.net/29856/42ca2b4bb241827edf69bbd6938d6b19c31935f1/integration_tests_(asan).html#fail1 Cc: @CurtizJ --- tests/integration/test_backup_restore/test.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/integration/test_backup_restore/test.py b/tests/integration/test_backup_restore/test.py index a093b06cd5c..b990cec2364 100644 --- a/tests/integration/test_backup_restore/test.py +++ b/tests/integration/test_backup_restore/test.py @@ -39,12 +39,10 @@ def get_last_backup_path(instance, database, table): return os.path.join(path_to_data, 'shadow', increment, 'data', database, table) def copy_backup_to_detached(instance, database, src_table, dst_table): - fp_increment = os.path.join(path_to_data, 'shadow/increment.txt') - increment = instance.exec_in_container(['cat', fp_increment]).strip() - fp_backup = os.path.join(path_to_data, 'shadow', increment, 'data', database, src_table) + fp_backup = os.path.join(path_to_data, 'shadow', '*', 'data', database, src_table) fp_detached = os.path.join(path_to_data, 'data', database, dst_table, 'detached') - logging.debug(f'copy from {fp_backup} to {fp_detached}. increment {fp_increment}') - instance.exec_in_container(['cp', '-r', f'{fp_backup}', '-T' , f'{fp_detached}']) + logging.debug(f'copy from {fp_backup} to {fp_detached}') + instance.exec_in_container(['bash', '-c', f'cp -r {fp_backup} -T {fp_detached}']) def test_restore(started_cluster): instance.query("CREATE TABLE test.tbl1 AS test.tbl") From 473f7bee3ad023b21de225c280b0d8e62979fdcc Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Sat, 9 Oct 2021 12:16:37 +0000 Subject: [PATCH 107/264] refactor --- programs/server/users.xml | 4 ++-- src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp | 3 +++ src/Server/HTTP/WriteBufferFromHTTPServerResponse.h | 8 ++++++++ src/Server/HTTPHandler.cpp | 9 ++++++--- tests/integration/test_settings_profile/test.py | 6 +++--- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/programs/server/users.xml b/programs/server/users.xml index b935937a1e5..4cd0c88a0a2 100644 --- a/programs/server/users.xml +++ b/programs/server/users.xml @@ -19,8 +19,8 @@ --> random - - 1 + + diff --git a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp index 9131413a887..cba0b6f0592 100644 --- a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp +++ b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.cpp @@ -29,6 +29,9 @@ void WriteBufferFromHTTPServerResponse::startSendHeaders() { headers_started_sending = true; + if (add_cors_header) + response.set("Access-Control-Allow-Origin", "*"); + setResponseDefaultHeaders(response, keep_alive_timeout); if (!is_http_method_head) diff --git a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h index 7ce99b16261..665c2daebbd 100644 --- a/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h +++ b/src/Server/HTTP/WriteBufferFromHTTPServerResponse.h @@ -36,6 +36,7 @@ private: HTTPServerResponse & response; bool is_http_method_head; + bool add_cors_header = false; unsigned keep_alive_timeout = 0; bool compress = false; CompressionMethod compression_method; @@ -103,6 +104,13 @@ public: compression_level = level; } + /// Turn CORS on or off. + /// The setting has any effect only if HTTP headers haven't been sent yet. + void addHeaderCORS(bool enable_cors) + { + add_cors_header = enable_cors; + } + /// Don't send HTTP headers with progress more frequently. void setSendProgressInterval(size_t send_progress_interval_ms_) { diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 9edef8a7223..c50d0e753ed 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -745,10 +745,13 @@ void HTTPHandler::processQuery( if (in_post_compressed && settings.http_native_compression_disable_checksumming_on_decompress) static_cast(*in_post_maybe_compressed).disableChecksumming(); - /// Add CORS header if 'add_http_cors_header' setting is turned on or config has http_options_response, - /// which means that there are some headers to be sent, and the client passed Origin header. - if (settings.add_http_cors_header && config.has("http_options_response") && !request.get("Origin", "").empty()) + /// Add CORS header if 'add_http_cors_header' setting is turned on send * in Access-Control-Allow-Origin, + /// or if config has http_options_response, which means that there + /// are some headers to be sent, and the client passed Origin header. + if (config.has("http_options_response") && !request.get("Origin", "").empty()) tryAddHeadersFromConfig(response, config); + else if (settings.add_http_cors_header) + used_output.out->addHeaderCORS(settings.add_http_cors_header && !request.get("Origin", "").empty()); auto append_callback = [context = context] (ProgressCallback callback) { diff --git a/tests/integration/test_settings_profile/test.py b/tests/integration/test_settings_profile/test.py index 048d09daaa5..7be0b395764 100644 --- a/tests/integration/test_settings_profile/test.py +++ b/tests/integration/test_settings_profile/test.py @@ -201,13 +201,13 @@ def test_show_profiles(): assert instance.query("SHOW CREATE PROFILE xyz") == "CREATE SETTINGS PROFILE xyz\n" assert instance.query( - "SHOW CREATE SETTINGS PROFILE default") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" + "SHOW CREATE SETTINGS PROFILE default") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" assert instance.query( - "SHOW CREATE PROFILES") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" \ + "SHOW CREATE PROFILES") == "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" \ "CREATE SETTINGS PROFILE readonly SETTINGS readonly = 1\n" \ "CREATE SETTINGS PROFILE xyz\n" - expected_access = "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\', add_http_cors_header = 1\n" \ + expected_access = "CREATE SETTINGS PROFILE default SETTINGS max_memory_usage = 10000000000, load_balancing = \\'random\\'\n" \ "CREATE SETTINGS PROFILE readonly SETTINGS readonly = 1\n" \ "CREATE SETTINGS PROFILE xyz\n" assert expected_access in instance.query("SHOW ACCESS") From 12f59f2dcac5ec74e40724c612e95f4093cadbc5 Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Sat, 9 Oct 2021 12:52:20 +0000 Subject: [PATCH 108/264] refactor --- programs/server/users.xml | 5 +---- src/Server/HTTPHandler.cpp | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/programs/server/users.xml b/programs/server/users.xml index 4cd0c88a0a2..847e7768ed0 100644 --- a/programs/server/users.xml +++ b/programs/server/users.xml @@ -18,10 +18,7 @@ first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors. --> random - - - - + diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index c50d0e753ed..42ff154e807 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -746,12 +746,12 @@ void HTTPHandler::processQuery( static_cast(*in_post_maybe_compressed).disableChecksumming(); /// Add CORS header if 'add_http_cors_header' setting is turned on send * in Access-Control-Allow-Origin, - /// or if config has http_options_response, which means that there + /// or if config has http_options_response, which means that there /// are some headers to be sent, and the client passed Origin header. if (config.has("http_options_response") && !request.get("Origin", "").empty()) tryAddHeadersFromConfig(response, config); - else if (settings.add_http_cors_header) - used_output.out->addHeaderCORS(settings.add_http_cors_header && !request.get("Origin", "").empty()); + else if (settings.add_http_cors_header && !request.get("Origin", "").empty()) + used_output.out->addHeaderCORS(true); auto append_callback = [context = context] (ProgressCallback callback) { From a853cd57ca67014bcd5e73145aa1daf14f274b2f Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Sat, 9 Oct 2021 12:56:00 +0000 Subject: [PATCH 109/264] refactoring --- src/Server/HTTPHandler.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Server/HTTPHandler.cpp b/src/Server/HTTPHandler.cpp index 42ff154e807..b7e7ac2ac33 100644 --- a/src/Server/HTTPHandler.cpp +++ b/src/Server/HTTPHandler.cpp @@ -748,10 +748,13 @@ void HTTPHandler::processQuery( /// Add CORS header if 'add_http_cors_header' setting is turned on send * in Access-Control-Allow-Origin, /// or if config has http_options_response, which means that there /// are some headers to be sent, and the client passed Origin header. - if (config.has("http_options_response") && !request.get("Origin", "").empty()) - tryAddHeadersFromConfig(response, config); - else if (settings.add_http_cors_header && !request.get("Origin", "").empty()) - used_output.out->addHeaderCORS(true); + if (!request.get("Origin", "").empty()) + { + if (config.has("http_options_response")) + tryAddHeadersFromConfig(response, config); + else if (settings.add_http_cors_header) + used_output.out->addHeaderCORS(true); + } auto append_callback = [context = context] (ProgressCallback callback) { From 98ecd59ebe5ebbc25884c6a577b85d13219039ec Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Sat, 9 Oct 2021 16:00:37 +0300 Subject: [PATCH 110/264] Update users.xml --- programs/server/users.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/server/users.xml b/programs/server/users.xml index 847e7768ed0..0f7dfadb8ea 100644 --- a/programs/server/users.xml +++ b/programs/server/users.xml @@ -18,7 +18,7 @@ first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors. --> random - + From 7753cc9c2843f737e8a946e2866626d724009477 Mon Sep 17 00:00:00 2001 From: Filatenkov Artur <58165623+FArthur-cmd@users.noreply.github.com> Date: Sat, 9 Oct 2021 16:01:01 +0300 Subject: [PATCH 111/264] Update users.xml --- programs/server/users.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/server/users.xml b/programs/server/users.xml index 0f7dfadb8ea..fd5fe414579 100644 --- a/programs/server/users.xml +++ b/programs/server/users.xml @@ -18,7 +18,7 @@ first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors. --> random - + From c66942bba5eff720ad1e336bfde6bd676266f1df Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 9 Oct 2021 16:15:31 +0300 Subject: [PATCH 112/264] Fix test_input_format_parallel_parsing_memory_tracking::test_memory_tracking_total Server has pretty low memory limit 3GB, so let's use local to generate the data. --- .../test_input_format_parallel_parsing_memory_tracking/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration/test_input_format_parallel_parsing_memory_tracking/test.py b/tests/integration/test_input_format_parallel_parsing_memory_tracking/test.py index e8866d3a235..bc7f32bf544 100644 --- a/tests/integration/test_input_format_parallel_parsing_memory_tracking/test.py +++ b/tests/integration/test_input_format_parallel_parsing_memory_tracking/test.py @@ -30,7 +30,7 @@ def test_memory_tracking_total(): CREATE TABLE null (row String) ENGINE=Null; ''') instance.exec_in_container(['bash', '-c', - 'clickhouse client -q "SELECT arrayStringConcat(arrayMap(x->toString(cityHash64(x)), range(1000)), \' \') from numbers(10000)" > data.json']) + 'clickhouse local -q "SELECT arrayStringConcat(arrayMap(x->toString(cityHash64(x)), range(1000)), \' \') from numbers(10000)" > data.json']) for it in range(0, 20): # the problem can be triggered only via HTTP, # since clickhouse-client parses the data by itself. From 24568c9de5dc629fd1ec7054566a48530a6ce777 Mon Sep 17 00:00:00 2001 From: Artur <613623@mail.ru> Date: Sat, 9 Oct 2021 13:55:30 +0000 Subject: [PATCH 113/264] update test reference --- tests/queries/0_stateless/00372_cors_header.reference | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/queries/0_stateless/00372_cors_header.reference b/tests/queries/0_stateless/00372_cors_header.reference index e22493782f0..2f1465d1598 100644 --- a/tests/queries/0_stateless/00372_cors_header.reference +++ b/tests/queries/0_stateless/00372_cors_header.reference @@ -1,3 +1,3 @@ 1 +1 0 -0 From f25fbe37403355cb16e0b0c39689f1f1bb3ec50f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 9 Oct 2021 18:37:38 +0300 Subject: [PATCH 114/264] Update CCTZ --- contrib/cctz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/cctz b/contrib/cctz index c0f1bcb97fd..9edd0861d83 160000 --- a/contrib/cctz +++ b/contrib/cctz @@ -1 +1 @@ -Subproject commit c0f1bcb97fd2782f7c3f972fadd5aad5affac4b8 +Subproject commit 9edd0861d8328b2ae77e8fb5f4d7dcd1cf33b42b From f0b7e54e83d4435734eecb56b3881d30e1d5d96c Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 9 Oct 2021 18:42:53 +0300 Subject: [PATCH 115/264] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d203fcba4c8..718aa751cc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -### ClickHouse release v21.10, 2021-10-08 +### ClickHouse release v21.10, 2021-10-14 #### Backward Incompatible Change From bc093e2b23bd64e34042374d13a4a3cef7939c29 Mon Sep 17 00:00:00 2001 From: WangZengrui Date: Sun, 10 Oct 2021 00:06:11 +0800 Subject: [PATCH 116/264] fix test --- .../0_stateless/02095_function_get_os_kernel_version.reference | 2 +- .../0_stateless/02095_function_get_os_kernel_version.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference b/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference index 9ec3c4aef9b..9b075671eac 100644 --- a/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference +++ b/tests/queries/0_stateless/02095_function_get_os_kernel_version.reference @@ -1 +1 @@ -Linux 0 +Linux diff --git a/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql b/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql index 01cd1057d84..ed38abb64a9 100644 --- a/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql +++ b/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql @@ -1 +1 @@ -WITH splitByChar(' ', getOSKernelVersion()) AS version_pair SELECT version_pair[1], toUInt32(splitByChar('.', version_pair[2])[1]) > 3 \ No newline at end of file +WITH splitByChar(' ', getOSKernelVersion()) AS version_pair SELECT version_pair[1] \ No newline at end of file From f908531b76fac8f42fe5eeeb4496e7535142b633 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Sat, 9 Oct 2021 19:12:47 +0300 Subject: [PATCH 117/264] Fix debug build. --- src/DataStreams/NativeReader.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/DataStreams/NativeReader.cpp b/src/DataStreams/NativeReader.cpp index 92c37a3f764..079dff80eae 100644 --- a/src/DataStreams/NativeReader.cpp +++ b/src/DataStreams/NativeReader.cpp @@ -61,14 +61,6 @@ void NativeReader::resetParser() { istr_concrete = nullptr; use_index = false; - -#ifndef NDEBUG - read_prefix_is_called = false; - read_suffix_is_called = false; -#endif - - // is_cancelled.store(false); - // is_killed.store(false); } void NativeReader::readData(const IDataType & type, ColumnPtr & column, ReadBuffer & istr, size_t rows, double avg_value_size_hint) From 0828ecae975d8f92756e28430d610c9bdce7b8d1 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 9 Oct 2021 19:46:36 +0300 Subject: [PATCH 118/264] Better exception message while reading column from Arrow-supported formats --- .../Formats/Impl/ArrowColumnToCHColumn.cpp | 13 ++++++++++++- .../Formats/Impl/ParquetBlockInputFormat.cpp | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Processors/Formats/Impl/ArrowColumnToCHColumn.cpp b/src/Processors/Formats/Impl/ArrowColumnToCHColumn.cpp index feb826d5aa0..3dada0d62be 100644 --- a/src/Processors/Formats/Impl/ArrowColumnToCHColumn.cpp +++ b/src/Processors/Formats/Impl/ArrowColumnToCHColumn.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -568,7 +569,17 @@ void ArrowColumnToCHColumn::arrowTableToCHChunk(Chunk & res, std::shared_ptrgetName(), header_column.type->getName())); + throw; + } + column.type = header_column.type; num_rows = column.column->size(); columns_list.push_back(std::move(column.column)); diff --git a/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp b/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp index 5137318c6e1..8f088a3f84a 100644 --- a/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp +++ b/src/Processors/Formats/Impl/ParquetBlockInputFormat.cpp @@ -15,6 +15,7 @@ #include + namespace DB { From c61f09c4dc1df370fd73b00c450a029afc3a6544 Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Sat, 9 Oct 2021 18:20:13 +0300 Subject: [PATCH 119/264] fix test for replication consistency --- tests/queries/0_stateless/replication.lib | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/queries/0_stateless/replication.lib b/tests/queries/0_stateless/replication.lib index e7fa2dd5404..61491630f46 100755 --- a/tests/queries/0_stateless/replication.lib +++ b/tests/queries/0_stateless/replication.lib @@ -40,6 +40,17 @@ function check_replication_consistency() table_name_prefix=$1 check_query_part=$2 + # Wait for all queries to finish (query may still be running if thread is killed by timeout) + num_tries=0 + while [[ $($CLICKHOUSE_CLIENT -q "SELECT count() FROM system.processes WHERE current_database=currentDatabase() AND query LIKE '%$table_name_prefix%'") -ne 1 ]]; do + sleep 0.5; + num_tries=$((num_tries-1)) + if [ $num_tries -eq 100 ]; then + $CLICKHOUSE_CLIENT -q "SELECT count() FROM system.processes WHERE current_database=currentDatabase() AND query LIKE '%$table_name_prefix%' FORMAT Vertical" + break + fi + done + # Do not check anything if all replicas are readonly, # because is this case all replicas are probably lost (it may happen and it's not a bug) res=$($CLICKHOUSE_CLIENT -q "SELECT count() - sum(is_readonly) FROM system.replicas WHERE database=currentDatabase() AND table LIKE '$table_name_prefix%'") From 7f5852a7114e5e4da08f363ec81dcbfe4079d2f0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sat, 9 Oct 2021 18:37:28 +0000 Subject: [PATCH 120/264] New buildId variant Links from Distributed --- docs/en/engines/table-engines/special/distributed.md | 3 ++- docs/en/sql-reference/functions/other-functions.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/en/engines/table-engines/special/distributed.md b/docs/en/engines/table-engines/special/distributed.md index 368849359ef..9503944a7a8 100644 --- a/docs/en/engines/table-engines/special/distributed.md +++ b/docs/en/engines/table-engines/special/distributed.md @@ -197,5 +197,6 @@ When the `max_parallel_replicas` option is enabled, query processing is parallel - [Virtual columns](../../../engines/table-engines/special/index.md#table_engines-virtual_columns) - [background_distributed_schedule_pool_size](../../../operations/settings/settings.md#background_distributed_schedule_pool_size) +- [shardNum()](../../../sql-reference/functions/other-functions.md#shard-num) and [shardCount()](../../../sql-reference/functions/other-functions.md#shard-count) functions + -[Original article](https://clickhouse.com/docs/en/operations/table_engines/distributed/) diff --git a/docs/en/sql-reference/functions/other-functions.md b/docs/en/sql-reference/functions/other-functions.md index 9828c91909b..6864ba7705b 100644 --- a/docs/en/sql-reference/functions/other-functions.md +++ b/docs/en/sql-reference/functions/other-functions.md @@ -701,7 +701,7 @@ If it is executed in the context of a distributed table, then it generates a nor ## buildId() {#buildid} -Returns the compiler build id of the running binary. +Returns the build ID generated by a compiler for the running ClickHouse server binary. If it is executed in the context of a distributed table, then it generates a normal column with values relevant to each shard. Otherwise it produces a constant value. From 2b272f5781ac22659dc8da6e4f657a359a74dac6 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sat, 9 Oct 2021 19:17:02 +0000 Subject: [PATCH 121/264] Virtual column in Distributed updated, link fixed, links added Translated that part --- docs/en/engines/table-engines/special/distributed.md | 8 ++++---- docs/ru/engines/table-engines/special/distributed.md | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/docs/en/engines/table-engines/special/distributed.md b/docs/en/engines/table-engines/special/distributed.md index 9503944a7a8..6593a5dc17f 100644 --- a/docs/en/engines/table-engines/special/distributed.md +++ b/docs/en/engines/table-engines/special/distributed.md @@ -188,15 +188,15 @@ When the `max_parallel_replicas` option is enabled, query processing is parallel ## Virtual Columns {#virtual-columns} -- `_shard_num` — Contains the `shard_num` (from `system.clusters`). Type: [UInt32](../../../sql-reference/data-types/int-uint.md). +- `_shard_num` — Contains the `shard_num` value from the table `system.clusters`. Type: [UInt32](../../../sql-reference/data-types/int-uint.md). !!! note "Note" - Since [`remote`](../../../sql-reference/table-functions/remote.md)/`cluster` table functions internally create temporary instance of the same Distributed engine, `_shard_num` is available there too. + Since [remote](../../../sql-reference/table-functions/remote.md) and [cluster](../../../sql-reference/table-functions/cluster.md) table functions internally create temporary Distributed table, `_shard_num` is available there too. **See Also** -- [Virtual columns](../../../engines/table-engines/special/index.md#table_engines-virtual_columns) -- [background_distributed_schedule_pool_size](../../../operations/settings/settings.md#background_distributed_schedule_pool_size) +- [Virtual columns](../../../engines/table-engines/index.md#table_engines-virtual_columns) description +- [background_distributed_schedule_pool_size](../../../operations/settings/settings.md#background_distributed_schedule_pool_size) setting - [shardNum()](../../../sql-reference/functions/other-functions.md#shard-num) and [shardCount()](../../../sql-reference/functions/other-functions.md#shard-count) functions diff --git a/docs/ru/engines/table-engines/special/distributed.md b/docs/ru/engines/table-engines/special/distributed.md index b1f6f56623d..ff1dc7c4057 100644 --- a/docs/ru/engines/table-engines/special/distributed.md +++ b/docs/ru/engines/table-engines/special/distributed.md @@ -136,3 +136,15 @@ logs - имя кластера в конфигурационном файле с При выставлении опции max_parallel_replicas выполнение запроса распараллеливается по всем репликам внутри одного шарда. Подробнее смотрите раздел [max_parallel_replicas](../../../operations/settings/settings.md#settings-max_parallel_replicas). +## Виртуальные столбцы {#virtual-columns} + +- `_shard_num` — содержит значение `shard_num` из таблицы `system.clusters`. Тип: [UInt32](../../../sql-reference/data-types/int-uint.md). + +!!! note "Примечание" + Так как табличные функции [remote](../../../sql-reference/table-functions/remote.md) и [cluster](../../../sql-reference/table-functions/cluster.md) создают временную таблицу на движке `Distributed`, то в ней также доступен столбец `_shard_num`. + +**Смотрите также** + +- общее описание [виртуальных столбцов](../../../engines/table-engines/index.md#table_engines-virtual_columns) +- настройка [background_distributed_schedule_pool_size](../../../operations/settings/settings.md#background_distributed_schedule_pool_size) +- функции [shardNum()](../../../sql-reference/functions/other-functions.md#shard-num) и [shardCount()](../../../sql-reference/functions/other-functions.md#shard-count) From 17552931af3806c528c34a3788b53d572f6726e0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sat, 9 Oct 2021 19:27:24 +0000 Subject: [PATCH 122/264] ru other functuins addons --- docs/ru/sql-reference/functions/date-time-functions.md | 1 + docs/ru/sql-reference/functions/other-functions.md | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md index 282962b9e3f..d4777faf354 100644 --- a/docs/ru/sql-reference/functions/date-time-functions.md +++ b/docs/ru/sql-reference/functions/date-time-functions.md @@ -26,6 +26,7 @@ SELECT ## timeZone {#timezone} Возвращает часовой пояс сервера. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. **Синтаксис** diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index d3e0f8b946e..31e81b04330 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -8,6 +8,7 @@ toc_title: "Прочие функции" ## hostName() {#hostname} Возвращает строку - имя хоста, на котором эта функция была выполнена. При распределённой обработке запроса, это будет имя хоста удалённого сервера, если функция выполняется на удалённом сервере. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. ## getMacro {#getmacro} @@ -643,10 +644,17 @@ SELECT ## uptime() {#uptime} Возвращает аптайм сервера в секундах. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. ## version() {#version} Возвращает версию сервера в виде строки. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. + +## buildId() {#buildid} + +Возвращает ID сборки, сгенерированный компилятором для запущенного сервера ClickHouse. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. ## rowNumberInBlock {#function-rownumberinblock} @@ -2304,3 +2312,4 @@ SELECT count(DISTINCT t) FROM (SELECT initialQueryID() AS t FROM remote('127.0.0 │ 1 │ └─────────┘ ``` + From b9969232f54f4e947aff6aa07eea165bf00695da Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Sun, 10 Oct 2021 01:12:36 +0300 Subject: [PATCH 123/264] Update 02095_function_get_os_kernel_version.sql --- .../0_stateless/02095_function_get_os_kernel_version.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql b/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql index ed38abb64a9..d62b360f7e0 100644 --- a/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql +++ b/tests/queries/0_stateless/02095_function_get_os_kernel_version.sql @@ -1 +1 @@ -WITH splitByChar(' ', getOSKernelVersion()) AS version_pair SELECT version_pair[1] \ No newline at end of file +WITH splitByChar(' ', getOSKernelVersion()) AS version_pair SELECT version_pair[1] From cc1fbe27a7e5d0ad35678a9c78a3312f580e8a77 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 03:40:51 +0300 Subject: [PATCH 124/264] Fix build due to conflicts in serverConstants Refs: #29755 Refs: #29913 --- src/Functions/serverConstants.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Functions/serverConstants.cpp b/src/Functions/serverConstants.cpp index 8fc103b2382..900a6dbf2a9 100644 --- a/src/Functions/serverConstants.cpp +++ b/src/Functions/serverConstants.cpp @@ -106,7 +106,7 @@ namespace { public: static constexpr auto name = "getOSKernelVersion"; - explicit FunctionGetOSKernelVersion(ContextPtr context) : FunctionConstantBase(context, Poco::Environment::osName() + " " + Poco::Environment::osVersion()) {} + explicit FunctionGetOSKernelVersion(ContextPtr context) : FunctionConstantBase(Poco::Environment::osName() + " " + Poco::Environment::osVersion(), context->isDistributed()) {} static FunctionPtr create(ContextPtr context) { return std::make_shared(context); } }; #endif From 4bc90d1dd7dbd4b8a9b6920d00ca24e8b160358e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 01:51:41 +0300 Subject: [PATCH 125/264] Fix data-race between flush() and startup() in StorageBuffer Stress tests found [1], TSan report: ================== WARNING: ThreadSanitizer: data race (pid=485) Read of size 8 at 0x7b5001280bd8 by thread T567 (mutexes: write M612061890855345680): 1 std::__1::shared_ptr::operator bool() const obj-x86_64-linux-gnu/../contrib/libcxx/include/memory:2851:62 (clickhouse+0x159140a6) 2 bool std::__1::operator!=() obj-x86_64-linux-gnu/../contrib/libcxx/include/memory:3447:30 (clickhouse+0x159140a6) 3 DB::BackgroundSchedulePoolTaskHolder::operator bool() const obj-x86_64-linux-gnu/../src/Core/BackgroundSchedulePool.h:164:46 (clickhouse+0x159140a6) 4 DB::StorageBuffer::flush() obj-x86_64-linux-gnu/../src/Storages/StorageBuffer.cpp:675:10 (clickhouse+0x159140a6) Previous write of size 8 at 0x7b5001280bd8 by thread T586 (mutexes: write M191819750614415520): 2 std::__1::shared_ptr::operator=(std::__1::shared_ptr&&) obj-x86_64-linux-gnu/../contrib/libcxx/include/memory:3243:34 (clickhouse+0x15913e22) 3 DB::BackgroundSchedulePoolTaskHolder::operator=() obj-x86_64-linux-gnu/../src/Core/BackgroundSchedulePool.h:156:110 (clickhouse+0x15913e22) 4 DB::StorageBuffer::startup() obj-x86_64-linux-gnu/../src/Storages/StorageBuffer.cpp:668:18 (clickhouse+0x15913e22) 5 DB::InterpreterCreateQuery::doCreateTable() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterCreateQuery.cpp:1092:10 (clickhouse+0x149bef7b) 6 DB::InterpreterCreateQuery::createTable() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterCreateQuery.cpp:952:20 (clickhouse+0x149ba9f5) 7 DB::InterpreterCreateQuery::execute() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterCreateQuery.cpp:1302:16 (clickhouse+0x149c1086) [1]: https://clickhouse-test-reports.s3.yandex.net/0/1c9778603ff49563d1d3d0d357de0608167e504d/stress_test_(thread).html Fixes: #29416 --- src/Storages/StorageBuffer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Storages/StorageBuffer.cpp b/src/Storages/StorageBuffer.cpp index 9747ea2dbf6..c3ce70955bf 100644 --- a/src/Storages/StorageBuffer.cpp +++ b/src/Storages/StorageBuffer.cpp @@ -130,6 +130,8 @@ StorageBuffer::StorageBuffer( storage_metadata.setConstraints(constraints_); storage_metadata.setComment(comment); setInMemoryMetadata(storage_metadata); + + flush_handle = bg_pool.createTask(log->name() + "/Bg", [this]{ backgroundFlush(); }); } @@ -667,7 +669,6 @@ void StorageBuffer::startup() LOG_WARNING(log, "Storage {} is run with readonly settings, it will not be able to insert data. Set appropriate buffer_profile to fix this.", getName()); } - flush_handle = bg_pool.createTask(log->name() + "/Bg", [this]{ backgroundFlush(); }); flush_handle->activateAndSchedule(); } From 2bab572caf91d2fc8962f409fea34149ecec8c95 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 00:46:28 +0300 Subject: [PATCH 126/264] Fix lock-order-inversion between periodic dictionary reload and config reload Integration tests found [1], TSan report: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=11) Cycle in lock order graph: M3152 (0x7b9000000058) => M3153 (0x7b9000000438) => M3152 Mutex M3153 acquired here while holding mutex M3152 in main thread: 3 std::__1::lock_guard::lock_guard(std::__1::recursive_mutex&) obj-x86_64-linux-gnu/../contrib/libcxx/include/__mutex_base:91:27 (clickhouse+0x15716b81) 4 DB::ExternalLoader::addConfigRepository() const obj-x86_64-linux-gnu/../src/Interpreters/ExternalLoader.cpp:1283:21 (clickhouse+0x15716b81) 5 DB::Context::loadOrReloadDictionaries() obj-x86_64-linux-gnu/../src/Interpreters/Context.cpp:1453:62 (clickhouse+0x155d7bad) 6 DB::Server::main()::$_1::operator()() const obj-x86_64-linux-gnu/../programs/server/Server.cpp:852:29 (clickhouse+0x9b1944c) 13 DB::ConfigReloader::reloadIfNewer() obj-x86_64-linux-gnu/../src/Common/Config/ConfigReloader.cpp:137:13 (clickhouse+0x17045e2e) 14 DB::ConfigReloader::ConfigReloader() obj-x86_64-linux-gnu/../src/Common/Config/ConfigReloader.cpp:33:9 (clickhouse+0x17044e51) 16 DB::Server::main(std::__1::vector, std::__1::allocator >, std::__1::allocator, std::__1::allocator > > > const&) obj-x86_64-linux-gnu/../programs/server/Server.cpp:803:33 (clickhouse+0x9b0c41d) 17 Poco::Util::Application::run() obj-x86_64-linux-gnu/../contrib/poco/Util/src/Application.cpp:334:8 (clickhouse+0x19ffc08b) 18 DB::Server::run() obj-x86_64-linux-gnu/../programs/server/Server.cpp:405:25 (clickhouse+0x9b03ebe) 19 Poco::Util::ServerApplication::run(int, char**) obj-x86_64-linux-gnu/../contrib/poco/Util/src/ServerApplication.cpp:611:9 (clickhouse+0x1a01c246) 20 mainEntryClickHouseServer(int, char**) obj-x86_64-linux-gnu/../programs/server/Server.cpp:183:20 (clickhouse+0x9b02576) 21 main obj-x86_64-linux-gnu/../programs/main.cpp:372:12 (clickhouse+0x9b00a3a) Mutex M3152 acquired here while holding mutex M3153 in thread T2: 3 std::__1::lock_guard::lock_guard() obj-x86_64-linux-gnu/../contrib/libcxx/include/__mutex_base:91:27 (clickhouse+0x155d63b8) 4 DB::Context::getExternalDictionariesLoader() obj-x86_64-linux-gnu/../src/Interpreters/Context.cpp:1337:21 (clickhouse+0x155d63b8) 5 DB::Context::getExternalDictionariesLoader() const obj-x86_64-linux-gnu/../src/Interpreters/Context.cpp:1332:41 (clickhouse+0x155d6359) 6 DB::DatabaseDictionary::tryGetTable() const obj-x86_64-inux-gnu/../src/Databases/DatabaseDictionary.cpp:76:38 (clickhouse+0x157819ad) 7 DB::DatabaseCatalog::getTableImpl() const obj-x86_64-linux-gnu/../src/Interpreters/DatabaseCatalog.cpp:285:28 (clickhouse+0x1564a1fa) 8 DB::DatabaseCatalog::getTable() const obj-x86_64-linux-gnu/../src/Interpreters/DatabaseCatalog.cpp:656:16 (clickhouse+0x1564fa2a) 9 DB::JoinedTables::getLeftTableStorage() obj-x86_64-linux-gnu/../src/Interpreters/JoinedTables.cpp:219:40 (clickhouse+0x15eeef45) 10 DB::InterpreterSelectQuery::InterpreterSelectQuery() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:321:33 (clickhouse+0x15b792be) 19 DB::ClickHouseDictionarySource::doInvalidateQuery() const obj-x86_64-linux-gnu/../src/Dictionaries/ClickHouseDictionarySource.cpp:207:36 (clickhouse+0x12872d2d) 20 DB::ClickHouseDictionarySource::isModified() const obj-x86_64-linux-gnu/../src/Dictionaries/ClickHouseDictionarySource.cpp:144:25 (clickhouse+0x12872534) 21 DB::IDictionary::isModified() const (clickhouse+0x128ce39b) 22 DB::ExternalLoader::LoadingDispatcher::reloadOutdated() obj-x86_64-linux-gnu/../src/Interpreters/ExternalLoader.cpp:660:50 (clickhouse+0x157305f7) 23 DB::ExternalLoader::PeriodicUpdater::doPeriodicUpdates() obj-x86_64-linux-gnu/../src/Interpreters/ExternalLoader.cpp:1248:36 (clickhouse+0x1572fff7) [1]: https://clickhouse-test-reports.s3.yandex.net/29856/42ca2b4bb241827edf69bbd6938d6b19c31935f1/integration_tests_(thread).html#fail1 --- src/Interpreters/ExternalLoader.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Interpreters/ExternalLoader.cpp b/src/Interpreters/ExternalLoader.cpp index e4c8e46980d..dc8466f3c26 100644 --- a/src/Interpreters/ExternalLoader.cpp +++ b/src/Interpreters/ExternalLoader.cpp @@ -1243,8 +1243,10 @@ private: { lock.unlock(); { - std::lock_guard config_lock{config_mutex}; - loading_dispatcher.setConfiguration(config_files_reader.read()); + { + std::lock_guard config_lock{config_mutex}; + loading_dispatcher.setConfiguration(config_files_reader.read()); + } loading_dispatcher.reloadOutdated(); } lock.lock(); From daf4cc6aba1024c591e70e7f939c8802ce9b3885 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Oct 2021 04:09:17 +0300 Subject: [PATCH 127/264] Whitespaces --- cmake/arch.cmake | 1 - cmake/dbms_glob_sources.cmake | 15 ++++----------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/cmake/arch.cmake b/cmake/arch.cmake index 60e0346dbbf..00cc16fbd10 100644 --- a/cmake/arch.cmake +++ b/cmake/arch.cmake @@ -13,7 +13,6 @@ endif () if ((ARCH_ARM AND NOT ARCH_AARCH64) OR ARCH_I386) message (FATAL_ERROR "32bit platforms are not supported") endif () - if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(ppc64le.*|PPC64LE.*)") set (ARCH_PPC64LE 1) endif () diff --git a/cmake/dbms_glob_sources.cmake b/cmake/dbms_glob_sources.cmake index 9c8c53c63b6..0f5c6106b70 100644 --- a/cmake/dbms_glob_sources.cmake +++ b/cmake/dbms_glob_sources.cmake @@ -1,14 +1,7 @@ -if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.12") - macro(add_glob cur_list) - file(GLOB __tmp RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} CONFIGURE_DEPENDS ${ARGN}) - list(APPEND ${cur_list} ${__tmp}) - endmacro() -else () - macro(add_glob cur_list) - file(GLOB __tmp RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${ARGN}) - list(APPEND ${cur_list} ${__tmp}) - endmacro() -endif () +macro(add_glob cur_list) + file(GLOB __tmp RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${ARGN}) + list(APPEND ${cur_list} ${__tmp}) +endmacro() macro(add_headers_and_sources prefix common_path) add_glob(${prefix}_headers ${CMAKE_CURRENT_SOURCE_DIR} ${common_path}/*.h) From 4e6ed5c45c85166dcf7c98d4adaf02873b695183 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Oct 2021 04:10:52 +0300 Subject: [PATCH 128/264] Remove trash from SentryWriter --- base/daemon/SentryWriter.cpp | 40 ++---------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/base/daemon/SentryWriter.cpp b/base/daemon/SentryWriter.cpp index ad914ff8cf4..efd915b1e5b 100644 --- a/base/daemon/SentryWriter.cpp +++ b/base/daemon/SentryWriter.cpp @@ -64,41 +64,6 @@ void setExtras() sentry_set_extra("disk_free_space", sentry_value_new_string(formatReadableSizeWithBinarySuffix(fs::space(server_data_path).free).c_str())); } -void sentry_logger(sentry_level_e level, const char * message, va_list args, void *) -{ - auto * logger = &Poco::Logger::get("SentryWriter"); - size_t size = 1024; - char buffer[size]; -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wformat-nonliteral" -#endif - if (vsnprintf(buffer, size, message, args) >= 0) - { -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - switch (level) - { - case SENTRY_LEVEL_DEBUG: - logger->debug(buffer); - break; - case SENTRY_LEVEL_INFO: - logger->information(buffer); - break; - case SENTRY_LEVEL_WARNING: - logger->warning(buffer); - break; - case SENTRY_LEVEL_ERROR: - logger->error(buffer); - break; - case SENTRY_LEVEL_FATAL: - logger->fatal(buffer); - break; - } - } -} - } @@ -107,13 +72,13 @@ void SentryWriter::initialize(Poco::Util::LayeredConfiguration & config) bool enabled = false; bool debug = config.getBool("send_crash_reports.debug", false); auto * logger = &Poco::Logger::get("SentryWriter"); + if (config.getBool("send_crash_reports.enabled", false)) { if (debug || (strlen(VERSION_OFFICIAL) > 0)) //-V560 - { enabled = true; - } } + if (enabled) { server_data_path = config.getString("path", ""); @@ -126,7 +91,6 @@ void SentryWriter::initialize(Poco::Util::LayeredConfiguration & config) sentry_options_t * options = sentry_options_new(); /// will be freed by sentry_init or sentry_shutdown sentry_options_set_release(options, VERSION_STRING_SHORT); - sentry_options_set_logger(options, &sentry_logger, nullptr); if (debug) { sentry_options_set_debug(options, 1); From 2a20bf4909e38fae7acc1fd97646af10ba150696 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Oct 2021 04:16:32 +0300 Subject: [PATCH 129/264] Remove function bayesAB #26233 --- src/Functions/abtesting.cpp | 315 ------------------ src/Functions/abtesting.h | 35 -- src/Functions/registerFunctions.cpp | 7 - .../01411_bayesian_ab_testing.reference | 4 - .../0_stateless/01411_bayesian_ab_testing.sql | 6 - 5 files changed, 367 deletions(-) delete mode 100644 src/Functions/abtesting.cpp delete mode 100644 src/Functions/abtesting.h delete mode 100644 tests/queries/0_stateless/01411_bayesian_ab_testing.reference delete mode 100644 tests/queries/0_stateless/01411_bayesian_ab_testing.sql diff --git a/src/Functions/abtesting.cpp b/src/Functions/abtesting.cpp deleted file mode 100644 index 312fdf6fb48..00000000000 --- a/src/Functions/abtesting.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include - -#if !defined(ARCADIA_BUILD) && USE_STATS - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define STATS_ENABLE_STDVEC_WRAPPERS -#include - -namespace DB -{ - -namespace ErrorCodes -{ - extern const int ILLEGAL_TYPE_OF_ARGUMENT; - extern const int BAD_ARGUMENTS; -} - -static const String BETA = "beta"; -static const String GAMMA = "gamma"; - -template -Variants bayesian_ab_test(String distribution, PODArray & xs, PODArray & ys) -{ - const size_t r = 1000, c = 100; - - Variants variants(xs.size(), {0.0, 0.0, 0.0, 0.0}); - std::vector> samples_matrix; - - for (size_t i = 0; i < xs.size(); ++i) - { - variants[i].x = xs[i]; - variants[i].y = ys[i]; - } - - if (distribution == BETA) - { - Float64 alpha, beta; - - for (size_t i = 0; i < xs.size(); ++i) - if (xs[i] < ys[i]) - throw Exception("Conversions cannot be larger than trials", ErrorCodes::BAD_ARGUMENTS); - - for (size_t i = 0; i < xs.size(); ++i) - { - alpha = 1.0 + ys[i]; - beta = 1.0 + xs[i] - ys[i]; - - samples_matrix.emplace_back(stats::rbeta>(r, c, alpha, beta)); - } - } - else if (distribution == GAMMA) - { - Float64 shape, scale; - - for (size_t i = 0; i < xs.size(); ++i) - { - shape = 1.0 + xs[i]; - scale = 250.0 / (1 + 250.0 * ys[i]); - - std::vector samples = stats::rgamma>(r, c, shape, scale); - for (auto & sample : samples) - sample = 1 / sample; - samples_matrix.emplace_back(std::move(samples)); - } - } - - PODArray means; - for (auto & samples : samples_matrix) - { - Float64 total = 0.0; - for (auto sample : samples) - total += sample; - means.push_back(total / samples.size()); - } - - // Beats control - for (size_t i = 1; i < xs.size(); ++i) - { - for (size_t n = 0; n < r * c; ++n) - { - if (higher_is_better) - { - if (samples_matrix[i][n] > samples_matrix[0][n]) - ++variants[i].beats_control; - } - else - { - if (samples_matrix[i][n] < samples_matrix[0][n]) - ++variants[i].beats_control; - } - } - } - - for (auto & variant : variants) - variant.beats_control = static_cast(variant.beats_control) / r / c; - - // To be best - PODArray count_m(xs.size(), 0); - PODArray row(xs.size(), 0); - - for (size_t n = 0; n < r * c; ++n) - { - for (size_t i = 0; i < xs.size(); ++i) - row[i] = samples_matrix[i][n]; - - Float64 m; - if (higher_is_better) - m = *std::max_element(row.begin(), row.end()); - else - m = *std::min_element(row.begin(), row.end()); - - for (size_t i = 0; i < xs.size(); ++i) - { - if (m == samples_matrix[i][n]) - { - ++variants[i].best; - break; - } - } - } - - for (auto & variant : variants) - variant.best = static_cast(variant.best) / r / c; - - return variants; -} - -String convertToJson(const PODArray & variant_names, const Variants & variants) -{ - FormatSettings settings; - - WriteBufferFromOwnString buf; - - writeCString("{\"data\":[", buf); - for (size_t i = 0; i < variants.size(); ++i) - { - writeCString("{\"variant_name\":", buf); - writeJSONString(variant_names[i], buf, settings); - writeCString(",\"x\":", buf); - writeText(variants[i].x, buf); - writeCString(",\"y\":", buf); - writeText(variants[i].y, buf); - writeCString(",\"beats_control\":", buf); - writeText(variants[i].beats_control, buf); - writeCString(",\"to_be_best\":", buf); - writeText(variants[i].best, buf); - writeCString("}", buf); - if (i != variant_names.size() -1) - writeCString(",", buf); - } - writeCString("]}", buf); - - return buf.str(); -} - -class FunctionBayesAB : public IFunction -{ -public: - static constexpr auto name = "bayesAB"; - - static FunctionPtr create(ContextPtr) - { - return std::make_shared(); - } - - String getName() const override - { - return name; - } - - bool isDeterministic() const override { return false; } - bool isDeterministicInScopeOfQuery() const override { return false; } - bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; } - - size_t getNumberOfArguments() const override { return 5; } - - DataTypePtr getReturnTypeImpl(const DataTypes &) const override - { - return std::make_shared(); - } - - static bool toFloat64(const ColumnConst * col_const_arr, PODArray & output) - { - Array src_arr = col_const_arr->getValue(); - - for (size_t i = 0, size = src_arr.size(); i < size; ++i) - { - switch (src_arr[i].getType()) - { - case Field::Types::Int64: - output.push_back(static_cast(src_arr[i].get())); - break; - case Field::Types::UInt64: - output.push_back(static_cast(src_arr[i].get())); - break; - case Field::Types::Float64: - output.push_back(src_arr[i].get()); - break; - default: - return false; - } - } - - return true; - } - - ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override - { - if (input_rows_count == 0) - return ColumnString::create(); - - PODArray xs, ys; - PODArray variant_names; - String dist; - bool higher_is_better; - - if (const ColumnConst * col_dist = checkAndGetColumnConst(arguments[0].column.get())) - { - dist = col_dist->getDataAt(0).data; - dist = Poco::toLower(dist); - if (dist != BETA && dist != GAMMA) - throw Exception("First argument for function " + getName() + " cannot be " + dist, ErrorCodes::BAD_ARGUMENTS); - } - else - throw Exception("First argument for function " + getName() + " must be Constant string", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - if (const ColumnConst * col_higher_is_better = checkAndGetColumnConst(arguments[1].column.get())) - higher_is_better = col_higher_is_better->getBool(0); - else - throw Exception("Second argument for function " + getName() + " must be Constant boolean", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - if (const ColumnConst * col_const_arr = checkAndGetColumnConst(arguments[2].column.get())) - { - Array src_arr = col_const_arr->getValue(); - - for (size_t i = 0; i < src_arr.size(); ++i) - { - if (src_arr[i].getType() != Field::Types::String) - throw Exception("Third argument for function " + getName() + " must be Array of constant strings", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - variant_names.push_back(src_arr[i].get()); - } - } - else - throw Exception("Third argument for function " + getName() + " must be Array of constant strings", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - if (const ColumnConst * col_const_arr = checkAndGetColumnConst(arguments[3].column.get())) - { - if (!toFloat64(col_const_arr, xs)) - throw Exception("Forth and fifth Argument for function " + getName() + " must be Array of constant Numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - } - else - throw Exception("Forth argument for function " + getName() + " must be Array of constant numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - if (const ColumnConst * col_const_arr = checkAndGetColumnConst(arguments[4].column.get())) - { - if (!toFloat64(col_const_arr, ys)) - throw Exception("Fifth Argument for function " + getName() + " must be Array of constant Numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - } - else - throw Exception("Fifth argument for function " + getName() + " must be Array of constant numbers", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); - - if (variant_names.size() != xs.size() || xs.size() != ys.size()) - throw Exception(ErrorCodes::BAD_ARGUMENTS, "Sizes of arguments doesn't match: variant_names: {}, xs: {}, ys: {}", variant_names.size(), xs.size(), ys.size()); - - if (variant_names.size() < 2) - throw Exception(ErrorCodes::BAD_ARGUMENTS, "Sizes of arguments must be larger than 1. variant_names: {}, xs: {}, ys: {}", variant_names.size(), xs.size(), ys.size()); - - if (std::count_if(xs.begin(), xs.end(), [](Float64 v) { return v < 0; }) > 0 || - std::count_if(ys.begin(), ys.end(), [](Float64 v) { return v < 0; }) > 0) - throw Exception("Negative values don't allowed", ErrorCodes::BAD_ARGUMENTS); - - Variants variants; - if (higher_is_better) - variants = bayesian_ab_test(dist, xs, ys); - else - variants = bayesian_ab_test(dist, xs, ys); - - auto dst = ColumnString::create(); - std::string result_str = convertToJson(variant_names, variants); - dst->insertData(result_str.c_str(), result_str.length()); - return dst; - } -}; - -void registerFunctionBayesAB(FunctionFactory & factory) -{ - factory.registerFunction(); -} - -} - -#else - -namespace DB -{ - -class FunctionFactory; - -void registerFunctionBayesAB(FunctionFactory & /* factory */) -{ -} - -} - -#endif diff --git a/src/Functions/abtesting.h b/src/Functions/abtesting.h deleted file mode 100644 index b1f12e79437..00000000000 --- a/src/Functions/abtesting.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include - -#if !defined(ARCADIA_BUILD) && USE_STATS - -# include -# include - -# include -# include -# include - - -namespace DB -{ - -struct Variant -{ - Float64 x; - Float64 y; - Float64 beats_control; - Float64 best; -}; - -using Variants = PODArray; - -template -Variants bayesian_ab_test(String distribution, PODArray & xs, PODArray & ys); - -String convertToJson(const PODArray & variant_names, const Variants & variants); - -} - -#endif diff --git a/src/Functions/registerFunctions.cpp b/src/Functions/registerFunctions.cpp index 35193e9be8d..b2f038240aa 100644 --- a/src/Functions/registerFunctions.cpp +++ b/src/Functions/registerFunctions.cpp @@ -54,9 +54,6 @@ void registerFunctionTupleHammingDistance(FunctionFactory & factory); void registerFunctionsStringHash(FunctionFactory & factory); void registerFunctionValidateNestedArraySizes(FunctionFactory & factory); void registerFunctionsSnowflake(FunctionFactory & factory); -#if !defined(ARCADIA_BUILD) -void registerFunctionBayesAB(FunctionFactory &); -#endif void registerFunctionTid(FunctionFactory & factory); void registerFunctionLogTrace(FunctionFactory & factory); @@ -122,10 +119,6 @@ void registerFunctions() registerFunctionValidateNestedArraySizes(factory); registerFunctionsSnowflake(factory); -#if !defined(ARCADIA_BUILD) - registerFunctionBayesAB(factory); -#endif - #if USE_SSL registerFunctionEncrypt(factory); registerFunctionDecrypt(factory); diff --git a/tests/queries/0_stateless/01411_bayesian_ab_testing.reference b/tests/queries/0_stateless/01411_bayesian_ab_testing.reference deleted file mode 100644 index 98fb6a68656..00000000000 --- a/tests/queries/0_stateless/01411_bayesian_ab_testing.reference +++ /dev/null @@ -1,4 +0,0 @@ -1 -1 -1 -1 diff --git a/tests/queries/0_stateless/01411_bayesian_ab_testing.sql b/tests/queries/0_stateless/01411_bayesian_ab_testing.sql deleted file mode 100644 index a4b03d76c51..00000000000 --- a/tests/queries/0_stateless/01411_bayesian_ab_testing.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Tags: no-fasttest - -SELECT count() FROM (SELECT bayesAB('beta', 1, ['Control', 'A', 'B'], [3000.0, 3000.0, 2000.0], [1000.0, 1100.0, 800.0])); -SELECT count() FROM (SELECT bayesAB('gamma', 1, ['Control', 'A', 'B'], [3000.0, 3000.0, 2000.0], [1000.0, 1100.0, 800.0])); -SELECT count() FROM (SELECT bayesAB('beta', 0, ['Control', 'A', 'B'], [3000.0, 3000.0, 2000.0], [1000.0, 1100.0, 800.0])); -SELECT count() FROM (SELECT bayesAB('gamma', 0, ['Control', 'A', 'B'], [3000.0, 3000.0, 2000.0], [1000.0, 1100.0, 800.0])); From 103b3c91ba9d8026e4eb574dd5a11f9b075f0b26 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Oct 2021 04:21:07 +0300 Subject: [PATCH 130/264] Remove 'printf' function usage. --- src/Client/QueryFuzzer.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Client/QueryFuzzer.cpp b/src/Client/QueryFuzzer.cpp index aa9f89e47b5..ec267e44a99 100644 --- a/src/Client/QueryFuzzer.cpp +++ b/src/Client/QueryFuzzer.cpp @@ -144,7 +144,7 @@ Field QueryFuzzer::fuzzField(Field field) { size_t pos = fuzz_rand() % arr.size(); arr.erase(arr.begin() + pos); - fprintf(stderr, "erased\n"); + std::cerr << "erased\n"; } if (fuzz_rand() % 5 == 0) @@ -153,12 +153,12 @@ Field QueryFuzzer::fuzzField(Field field) { size_t pos = fuzz_rand() % arr.size(); arr.insert(arr.begin() + pos, fuzzField(arr[pos])); - fprintf(stderr, "inserted (pos %zd)\n", pos); + std::cerr << fmt::format("inserted (pos {})\n", pos); } else { arr.insert(arr.begin(), getRandomField(0)); - fprintf(stderr, "inserted (0)\n"); + std::cerr << "inserted (0)\n"; } } @@ -278,7 +278,7 @@ void QueryFuzzer::fuzzOrderByList(IAST * ast) } else { - fprintf(stderr, "no random col!\n"); + std::cerr << "No random column.\n"; } } @@ -312,13 +312,9 @@ void QueryFuzzer::fuzzColumnLikeExpressionList(IAST * ast) : impl->children.begin() + fuzz_rand() % impl->children.size(); auto col = getRandomColumnLike(); if (col) - { impl->children.insert(pos, col); - } else - { - fprintf(stderr, "no random col!\n"); - } + std::cerr << "No random column.\n"; } // We don't have to recurse here to fuzz the children, this is handled by From 452b3b443d580112dc2acb49349e2d3acdbd30ff Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 9 Oct 2021 15:31:13 +0300 Subject: [PATCH 131/264] copier: add ability to configure retries and delays between them The following options had been introduced: - max-table-tries - max-shard-partition-tries - max-shard-partition-piece-tries-for-alter - retry-delay-ms --- programs/copier/ClusterCopier.cpp | 22 +++++++++++----------- programs/copier/ClusterCopier.h | 26 +++++++++++++++++++++----- programs/copier/ClusterCopierApp.cpp | 18 +++++++++++++++++- programs/copier/ClusterCopierApp.h | 5 +++++ 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/programs/copier/ClusterCopier.cpp b/programs/copier/ClusterCopier.cpp index 30b99b69351..89ef96e299e 100644 --- a/programs/copier/ClusterCopier.cpp +++ b/programs/copier/ClusterCopier.cpp @@ -87,7 +87,7 @@ decltype(auto) ClusterCopier::retry(T && func, UInt64 max_tries) if (try_number < max_tries) { tryLogCurrentException(log, "Will retry"); - std::this_thread::sleep_for(default_sleep_time); + std::this_thread::sleep_for(retry_delay_ms); } } } @@ -310,7 +310,7 @@ void ClusterCopier::process(const ConnectionTimeouts & timeouts) /// Retry table processing bool table_is_done = false; - for (UInt64 num_table_tries = 0; num_table_tries < max_table_tries; ++num_table_tries) + for (UInt64 num_table_tries = 1; num_table_tries <= max_table_tries; ++num_table_tries) { if (tryProcessTable(timeouts, task_table)) { @@ -341,7 +341,7 @@ zkutil::EphemeralNodeHolder::Ptr ClusterCopier::createTaskWorkerNodeAndWaitIfNee const String & description, bool unprioritized) { - std::chrono::milliseconds current_sleep_time = default_sleep_time; + std::chrono::milliseconds current_sleep_time = retry_delay_ms; static constexpr std::chrono::milliseconds max_sleep_time(30000); // 30 sec if (unprioritized) @@ -367,7 +367,7 @@ zkutil::EphemeralNodeHolder::Ptr ClusterCopier::createTaskWorkerNodeAndWaitIfNee LOG_INFO(log, "Too many workers ({}, maximum {}). Postpone processing {}", stat.numChildren, task_cluster->max_workers, description); if (unprioritized) - current_sleep_time = std::min(max_sleep_time, current_sleep_time + default_sleep_time); + current_sleep_time = std::min(max_sleep_time, current_sleep_time + retry_delay_ms); std::this_thread::sleep_for(current_sleep_time); num_bad_version_errors = 0; @@ -786,7 +786,7 @@ bool ClusterCopier::tryDropPartitionPiece( if (e.code == Coordination::Error::ZNODEEXISTS) { LOG_INFO(log, "Partition {} piece {} is cleaning now by somebody, sleep", task_partition.name, toString(current_piece_number)); - std::this_thread::sleep_for(default_sleep_time); + std::this_thread::sleep_for(retry_delay_ms); return false; } @@ -799,7 +799,7 @@ bool ClusterCopier::tryDropPartitionPiece( if (stat.numChildren != 0) { LOG_INFO(log, "Partition {} contains {} active workers while trying to drop it. Going to sleep.", task_partition.name, stat.numChildren); - std::this_thread::sleep_for(default_sleep_time); + std::this_thread::sleep_for(retry_delay_ms); return false; } else @@ -1006,7 +1006,7 @@ bool ClusterCopier::tryProcessTable(const ConnectionTimeouts & timeouts, TaskTab task_status = TaskStatus::Error; bool was_error = false; has_shard_to_process = true; - for (UInt64 try_num = 0; try_num < max_shard_partition_tries; ++try_num) + for (UInt64 try_num = 1; try_num <= max_shard_partition_tries; ++try_num) { task_status = tryProcessPartitionTask(timeouts, partition, is_unprioritized_task); @@ -1021,7 +1021,7 @@ bool ClusterCopier::tryProcessTable(const ConnectionTimeouts & timeouts, TaskTab break; /// Repeat on errors - std::this_thread::sleep_for(default_sleep_time); + std::this_thread::sleep_for(retry_delay_ms); } if (task_status == TaskStatus::Error) @@ -1069,7 +1069,7 @@ bool ClusterCopier::tryProcessTable(const ConnectionTimeouts & timeouts, TaskTab break; /// Repeat on errors. - std::this_thread::sleep_for(default_sleep_time); + std::this_thread::sleep_for(retry_delay_ms); } catch (...) { @@ -1110,7 +1110,7 @@ bool ClusterCopier::tryProcessTable(const ConnectionTimeouts & timeouts, TaskTab if (!table_is_done) { - LOG_INFO(log, "Table {} is not processed yet.Copied {} of {}, will retry", task_table.table_id, finished_partitions, required_partitions); + LOG_INFO(log, "Table {} is not processed yet. Copied {} of {}, will retry", task_table.table_id, finished_partitions, required_partitions); } else { @@ -1213,7 +1213,7 @@ TaskStatus ClusterCopier::iterateThroughAllPiecesInPartition(const ConnectionTim break; /// Repeat on errors - std::this_thread::sleep_for(default_sleep_time); + std::this_thread::sleep_for(retry_delay_ms); } was_active_pieces = (res == TaskStatus::Active); diff --git a/programs/copier/ClusterCopier.h b/programs/copier/ClusterCopier.h index 387b089724a..b354fc59eee 100644 --- a/programs/copier/ClusterCopier.h +++ b/programs/copier/ClusterCopier.h @@ -65,6 +65,23 @@ public: experimental_use_sample_offset = value; } + void setMaxTableTries(UInt64 tries) + { + max_table_tries = tries; + } + void setMaxShardPartitionTries(UInt64 tries) + { + max_shard_partition_tries = tries; + } + void setMaxShardPartitionPieceTriesForAlter(UInt64 tries) + { + max_shard_partition_piece_tries_for_alter = tries; + } + void setRetryDelayMs(std::chrono::milliseconds ms) + { + retry_delay_ms = ms; + } + protected: String getWorkersPath() const @@ -123,10 +140,6 @@ protected: bool tryDropPartitionPiece(ShardPartition & task_partition, size_t current_piece_number, const zkutil::ZooKeeperPtr & zookeeper, const CleanStateClock & clean_state_clock); - static constexpr UInt64 max_table_tries = 3; - static constexpr UInt64 max_shard_partition_tries = 3; - static constexpr UInt64 max_shard_partition_piece_tries_for_alter = 10; - bool tryProcessTable(const ConnectionTimeouts & timeouts, TaskTable & task_table); TaskStatus tryCreateDestinationTable(const ConnectionTimeouts & timeouts, TaskTable & task_table); @@ -218,6 +231,9 @@ private: Poco::Logger * log; - std::chrono::milliseconds default_sleep_time{1000}; + UInt64 max_table_tries = 3; + UInt64 max_shard_partition_tries = 3; + UInt64 max_shard_partition_piece_tries_for_alter = 10; + std::chrono::milliseconds retry_delay_ms{1000}; }; } diff --git a/programs/copier/ClusterCopierApp.cpp b/programs/copier/ClusterCopierApp.cpp index b8714d0851d..8d7e4abce51 100644 --- a/programs/copier/ClusterCopierApp.cpp +++ b/programs/copier/ClusterCopierApp.cpp @@ -31,6 +31,10 @@ void ClusterCopierApp::initialize(Poco::Util::Application & self) move_fault_probability = std::max(std::min(config().getDouble("move-fault-probability"), 1.0), 0.0); base_dir = (config().has("base-dir")) ? config().getString("base-dir") : fs::current_path().string(); + max_table_tries = std::max(config().getUInt("max-table-tries", 3), 1); + max_shard_partition_tries = std::max(config().getUInt("max-shard-partition-tries", 3), 1); + max_shard_partition_piece_tries_for_alter = std::max(config().getUInt("max-shard-partition-piece-tries-for-alter", 10), 1); + retry_delay_ms = std::chrono::milliseconds(std::max(config().getUInt("retry-delay-ms", 1000), 100)); if (config().has("experimental-use-sample-offset")) experimental_use_sample_offset = config().getBool("experimental-use-sample-offset"); @@ -100,6 +104,15 @@ void ClusterCopierApp::defineOptions(Poco::Util::OptionSet & options) .argument("experimental-use-sample-offset").binding("experimental-use-sample-offset")); options.addOption(Poco::Util::Option("status", "", "Get for status for current execution").binding("status")); + options.addOption(Poco::Util::Option("max-table-tries", "", "Number of tries for the copy table task") + .argument("max-table-tries").binding("max-table-tries")); + options.addOption(Poco::Util::Option("max-shard-partition-tries", "", "Number of tries for the copy one partition task") + .argument("max-shard-partition-tries").binding("max-shard-partition-tries")); + options.addOption(Poco::Util::Option("max-shard-partition-piece-tries-for-alter", "", "Number of tries for final ALTER ATTACH to destination table") + .argument("max-shard-partition-piece-tries-for-alter").binding("max-shard-partition-piece-tries-for-alter")); + options.addOption(Poco::Util::Option("retry-delay-ms", "", "Delay between task retries") + .argument("retry-delay-ms").binding("retry-delay-ms")); + using Me = std::decay_t; options.addOption(Poco::Util::Option("help", "", "produce this help message").binding("help") .callback(Poco::Util::OptionCallback(this, &Me::handleHelp))); @@ -161,7 +174,10 @@ void ClusterCopierApp::mainImpl() copier->setSafeMode(is_safe_mode); copier->setCopyFaultProbability(copy_fault_probability); copier->setMoveFaultProbability(move_fault_probability); - + copier->setMaxTableTries(max_table_tries); + copier->setMaxShardPartitionTries(max_shard_partition_tries); + copier->setMaxShardPartitionPieceTriesForAlter(max_shard_partition_piece_tries_for_alter); + copier->setRetryDelayMs(retry_delay_ms); copier->setExperimentalUseSampleOffset(experimental_use_sample_offset); auto task_file = config().getString("task-file", ""); diff --git a/programs/copier/ClusterCopierApp.h b/programs/copier/ClusterCopierApp.h index cce07e338c0..d447cd96149 100644 --- a/programs/copier/ClusterCopierApp.h +++ b/programs/copier/ClusterCopierApp.h @@ -83,6 +83,11 @@ private: double move_fault_probability = 0.0; bool is_help = false; + UInt64 max_table_tries = 3; + UInt64 max_shard_partition_tries = 3; + UInt64 max_shard_partition_piece_tries_for_alter = 10; + std::chrono::milliseconds retry_delay_ms{1000}; + bool experimental_use_sample_offset{false}; std::string base_dir; From 38de1833793b794f1528f2daff0a0f05363f3303 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 09:33:40 +0300 Subject: [PATCH 132/264] Make 00984_parser_stack_overflow less flaky According to query_log/trace_log the problem is real: 2021.10.10 07:52:37.702364 [ 3736 ] {c6a219f2-3df8-4474-8324-bb307ee7a7a9} executeQuery: (from [::1]:38096) (comment: /usr/share/clickhouse-test/queries/0_stateless/00984_parser_stack_overflow.sh) SELECT [[[... 2021.10.10 07:53:11.407949 [ 3736 ] {c6a219f2-3df8-4474-8324-bb307ee7a7a9} executeQuery: Code: 306. DB::Exception: Maximum parse depth (1000) exceeded. Consider rising max_parser_depth ... From trace_log: 2021-10-10 07:52:37.958938 DB::Dwarf::findDebugInfoOffset 2021-10-10 07:53:12.583248 DB::Dwarf::findDebugInfoOffset CI: https://clickhouse-test-reports.s3.yandex.net/29928/2bab572caf91d2fc8962f409fea34149ecec8c95/functional_stateless_tests_(debug).html#fail1 --- tests/queries/0_stateless/00984_parser_stack_overflow.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/queries/0_stateless/00984_parser_stack_overflow.sh b/tests/queries/0_stateless/00984_parser_stack_overflow.sh index 167678db5ec..329e51e774a 100755 --- a/tests/queries/0_stateless/00984_parser_stack_overflow.sh +++ b/tests/queries/0_stateless/00984_parser_stack_overflow.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash -CLICKHOUSE_CURL_TIMEOUT=30 +# Such a huge timeout mostly for debug build. +CLICKHOUSE_CURL_TIMEOUT=60 CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck source=../shell_config.sh From 0c5d26b647e42b2acedff5f54501a360a05864d2 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 09:53:44 +0300 Subject: [PATCH 133/264] Make 01085_max_distributed_connections less flaky --- .../0_stateless/01085_max_distributed_connections.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/queries/0_stateless/01085_max_distributed_connections.sh b/tests/queries/0_stateless/01085_max_distributed_connections.sh index d8efa792e9d..4ffcd980956 100755 --- a/tests/queries/0_stateless/01085_max_distributed_connections.sh +++ b/tests/queries/0_stateless/01085_max_distributed_connections.sh @@ -10,13 +10,13 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) while true do opts=( - --max_distributed_connections 9 + --max_distributed_connections 20 --max_threads 1 - --query "SELECT sleepEachRow(1) FROM remote('127.{2..10}', system.one)" + --query "SELECT sleepEachRow(1) FROM remote('127.{2..21}', system.one)" --format Null ) - # 5 less then 9 seconds (9 streams), but long enough to cover possible load peaks + # 10 less then 20 seconds (20 streams), but long enough to cover possible load peaks # "$@" left to pass manual options (like --experimental_use_processors 0) during manual testing - timeout 5s ${CLICKHOUSE_CLIENT} "${opts[@]}" "$@" && break + timeout 10s ${CLICKHOUSE_CLIENT} "${opts[@]}" "$@" && break done From 1aeb5d55dd3b4eea4a4aff129a9c35bf1379b101 Mon Sep 17 00:00:00 2001 From: tavplubix Date: Sun, 10 Oct 2021 12:55:37 +0300 Subject: [PATCH 134/264] Grep server log even if it contains binary data (#29903) * grep server log even if it contains binary data * Update cluster.py Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- tests/integration/helpers/cluster.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/integration/helpers/cluster.py b/tests/integration/helpers/cluster.py index 5ba67085d73..51b7bfcbcb8 100644 --- a/tests/integration/helpers/cluster.py +++ b/tests/integration/helpers/cluster.py @@ -2073,11 +2073,11 @@ class ClickHouseInstance: def contains_in_log(self, substring, from_host=False): if from_host: result = subprocess_check_call(["bash", "-c", - f'[ -f {self.logs_dir}/clickhouse-server.log ] && grep "{substring}" {self.logs_dir}/clickhouse-server.log || true' + f'[ -f {self.logs_dir}/clickhouse-server.log ] && grep -a "{substring}" {self.logs_dir}/clickhouse-server.log || true' ]) else: result = self.exec_in_container(["bash", "-c", - f'[ -f /var/log/clickhouse-server/clickhouse-server.log ] && grep "{substring}" /var/log/clickhouse-server/clickhouse-server.log || true' + f'[ -f /var/log/clickhouse-server/clickhouse-server.log ] && grep -a "{substring}" /var/log/clickhouse-server/clickhouse-server.log || true' ]) return len(result) > 0 @@ -2085,18 +2085,18 @@ class ClickHouseInstance: logging.debug(f"grep in log called %s", substring) if from_host: result = subprocess_check_call(["bash", "-c", - f'grep "{substring}" {self.logs_dir}/clickhouse-server.log || true' + f'grep -a "{substring}" {self.logs_dir}/clickhouse-server.log || true' ]) else: result = self.exec_in_container(["bash", "-c", - f'grep "{substring}" /var/log/clickhouse-server/clickhouse-server.log || true' + f'grep -a "{substring}" /var/log/clickhouse-server/clickhouse-server.log || true' ]) logging.debug("grep result %s", result) return result def count_in_log(self, substring): result = self.exec_in_container( - ["bash", "-c", 'grep "{}" /var/log/clickhouse-server/clickhouse-server.log | wc -l'.format(substring)]) + ["bash", "-c", 'grep -a "{}" /var/log/clickhouse-server/clickhouse-server.log | wc -l'.format(substring)]) return result def wait_for_log_line(self, regexp, filename='/var/log/clickhouse-server/clickhouse-server.log', timeout=30, repetitions=1, look_behind_lines=100): From 28459b282de0813c7e4da02d5b64ab8341cd7e2d Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Sun, 10 Oct 2021 13:25:24 +0300 Subject: [PATCH 135/264] Fix shutdown of AccessControlManager. Now there cannot be configuration reloading after AccessControlManager has been destroyed. --- programs/server/Server.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index 4ed5b114082..bfa402a6c21 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -1036,6 +1036,10 @@ if (ThreadFuzzer::instance().isEffective()) server.start(); SCOPE_EXIT({ + /// Stop reloading of the main config. This must be done before `global_context->shutdown()` because + /// otherwise the reloading may pass a changed config to some destroyed parts of ContextSharedPart. + main_config_reloader.reset(); + /** Ask to cancel background jobs all table engines, * and also query_log. * It is important to do early, not in destructor of Context, because @@ -1076,9 +1080,6 @@ if (ThreadFuzzer::instance().isEffective()) /// Wait server pool to avoid use-after-free of destroyed context in the handlers server_pool.joinAll(); - // Uses a raw pointer to global context for getting ZooKeeper. - main_config_reloader.reset(); - /** Explicitly destroy Context. It is more convenient than in destructor of Server, because logger is still available. * At this moment, no one could own shared part of Context. */ From 689c9cdbb9beac89847c722308ad4881d0108129 Mon Sep 17 00:00:00 2001 From: mikael Date: Thu, 22 Jul 2021 14:06:45 +0200 Subject: [PATCH 136/264] Add uc_mcontext for FreeBSD aarch64 --- src/Common/StackTrace.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Common/StackTrace.cpp b/src/Common/StackTrace.cpp index 1406cf03fe4..fc995e435ec 100644 --- a/src/Common/StackTrace.cpp +++ b/src/Common/StackTrace.cpp @@ -186,6 +186,8 @@ static void * getCallerAddress(const ucontext_t & context) #elif defined(__APPLE__) && defined(__aarch64__) return reinterpret_cast(context.uc_mcontext->__ss.__pc); +#elif defined(__FreeBSD__) && defined(__aarch64__) + return reinterpret_cast(context.uc_mcontext.mc_gpregs.gp_elr); #elif defined(__aarch64__) return reinterpret_cast(context.uc_mcontext.pc); #elif defined(__powerpc64__) From 714ac8efc415a413fb437872bb52d0f3280b00b4 Mon Sep 17 00:00:00 2001 From: mikael Date: Thu, 22 Jul 2021 14:07:54 +0200 Subject: [PATCH 137/264] FreeBSD aarch64 doesn't implement sbrk --- .../jemalloc/internal/jemalloc_internal_defs.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/jemalloc-cmake/include_freebsd_aarch64/jemalloc/internal/jemalloc_internal_defs.h.in b/contrib/jemalloc-cmake/include_freebsd_aarch64/jemalloc/internal/jemalloc_internal_defs.h.in index 44c59e1ce7d..3db0e14b268 100644 --- a/contrib/jemalloc-cmake/include_freebsd_aarch64/jemalloc/internal/jemalloc_internal_defs.h.in +++ b/contrib/jemalloc-cmake/include_freebsd_aarch64/jemalloc/internal/jemalloc_internal_defs.h.in @@ -161,7 +161,7 @@ * JEMALLOC_DSS enables use of sbrk(2) to allocate extents from the data storage * segment (DSS). */ -#define JEMALLOC_DSS +/* #undef JEMALLOC_DSS */ /* Support memory filling (junk/zero). */ #define JEMALLOC_FILL From 5bd2fd0ba38dc8f7828045b7035729c7072a2ea6 Mon Sep 17 00:00:00 2001 From: mikael Date: Thu, 22 Jul 2021 14:08:45 +0200 Subject: [PATCH 138/264] Add the missing bits for FreeBSD aarch64 --- cmake/find/ldap.cmake | 1 + .../freebsd_aarch64/include/lber_types.h | 63 + .../freebsd_aarch64/include/ldap_config.h | 74 ++ .../freebsd_aarch64/include/ldap_features.h | 61 + .../freebsd_aarch64/include/portable.h | 1169 +++++++++++++++++ contrib/rocksdb-cmake/CMakeLists.txt | 5 + 6 files changed, 1373 insertions(+) create mode 100644 contrib/openldap-cmake/freebsd_aarch64/include/lber_types.h create mode 100644 contrib/openldap-cmake/freebsd_aarch64/include/ldap_config.h create mode 100644 contrib/openldap-cmake/freebsd_aarch64/include/ldap_features.h create mode 100644 contrib/openldap-cmake/freebsd_aarch64/include/portable.h diff --git a/cmake/find/ldap.cmake b/cmake/find/ldap.cmake index d8baea89429..71222d26c66 100644 --- a/cmake/find/ldap.cmake +++ b/cmake/find/ldap.cmake @@ -64,6 +64,7 @@ if (NOT OPENLDAP_FOUND AND NOT MISSING_INTERNAL_LDAP_LIBRARY) ( "${_system_name}" STREQUAL "linux" AND "${_system_processor}" STREQUAL "aarch64" ) OR ( "${_system_name}" STREQUAL "linux" AND "${_system_processor}" STREQUAL "ppc64le" ) OR ( "${_system_name}" STREQUAL "freebsd" AND "${_system_processor}" STREQUAL "x86_64" ) OR + ( "${_system_name}" STREQUAL "freebsd" AND "${_system_processor}" STREQUAL "aarch64" ) OR ( "${_system_name}" STREQUAL "darwin" AND "${_system_processor}" STREQUAL "x86_64" ) OR ( "${_system_name}" STREQUAL "darwin" AND "${_system_processor}" STREQUAL "aarch64" ) ) diff --git a/contrib/openldap-cmake/freebsd_aarch64/include/lber_types.h b/contrib/openldap-cmake/freebsd_aarch64/include/lber_types.h new file mode 100644 index 00000000000..dbd59430527 --- /dev/null +++ b/contrib/openldap-cmake/freebsd_aarch64/include/lber_types.h @@ -0,0 +1,63 @@ +/* include/lber_types.h. Generated from lber_types.hin by configure. */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2020 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +/* + * LBER types + */ + +#ifndef _LBER_TYPES_H +#define _LBER_TYPES_H + +#include + +LDAP_BEGIN_DECL + +/* LBER boolean, enum, integers (32 bits or larger) */ +#define LBER_INT_T int + +/* LBER tags (32 bits or larger) */ +#define LBER_TAG_T long + +/* LBER socket descriptor */ +#define LBER_SOCKET_T int + +/* LBER lengths (32 bits or larger) */ +#define LBER_LEN_T long + +/* ------------------------------------------------------------ */ + +/* booleans, enumerations, and integers */ +typedef LBER_INT_T ber_int_t; + +/* signed and unsigned versions */ +typedef signed LBER_INT_T ber_sint_t; +typedef unsigned LBER_INT_T ber_uint_t; + +/* tags */ +typedef unsigned LBER_TAG_T ber_tag_t; + +/* "socket" descriptors */ +typedef LBER_SOCKET_T ber_socket_t; + +/* lengths */ +typedef unsigned LBER_LEN_T ber_len_t; + +/* signed lengths */ +typedef signed LBER_LEN_T ber_slen_t; + +LDAP_END_DECL + +#endif /* _LBER_TYPES_H */ diff --git a/contrib/openldap-cmake/freebsd_aarch64/include/ldap_config.h b/contrib/openldap-cmake/freebsd_aarch64/include/ldap_config.h new file mode 100644 index 00000000000..89f7b40b884 --- /dev/null +++ b/contrib/openldap-cmake/freebsd_aarch64/include/ldap_config.h @@ -0,0 +1,74 @@ +/* include/ldap_config.h. Generated from ldap_config.hin by configure. */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2020 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +/* + * This file works in conjunction with OpenLDAP configure system. + * If you do no like the values below, adjust your configure options. + */ + +#ifndef _LDAP_CONFIG_H +#define _LDAP_CONFIG_H + +/* directory separator */ +#ifndef LDAP_DIRSEP +#ifndef _WIN32 +#define LDAP_DIRSEP "/" +#else +#define LDAP_DIRSEP "\\" +#endif +#endif + +/* directory for temporary files */ +#if defined(_WIN32) +# define LDAP_TMPDIR "C:\\." /* we don't have much of a choice */ +#elif defined( _P_tmpdir ) +# define LDAP_TMPDIR _P_tmpdir +#elif defined( P_tmpdir ) +# define LDAP_TMPDIR P_tmpdir +#elif defined( _PATH_TMPDIR ) +# define LDAP_TMPDIR _PATH_TMPDIR +#else +# define LDAP_TMPDIR LDAP_DIRSEP "tmp" +#endif + +/* directories */ +#ifndef LDAP_BINDIR +#define LDAP_BINDIR "/tmp/ldap-prefix/bin" +#endif +#ifndef LDAP_SBINDIR +#define LDAP_SBINDIR "/tmp/ldap-prefix/sbin" +#endif +#ifndef LDAP_DATADIR +#define LDAP_DATADIR "/tmp/ldap-prefix/share/openldap" +#endif +#ifndef LDAP_SYSCONFDIR +#define LDAP_SYSCONFDIR "/tmp/ldap-prefix/etc/openldap" +#endif +#ifndef LDAP_LIBEXECDIR +#define LDAP_LIBEXECDIR "/tmp/ldap-prefix/libexec" +#endif +#ifndef LDAP_MODULEDIR +#define LDAP_MODULEDIR "/tmp/ldap-prefix/libexec/openldap" +#endif +#ifndef LDAP_RUNDIR +#define LDAP_RUNDIR "/tmp/ldap-prefix/var" +#endif +#ifndef LDAP_LOCALEDIR +#define LDAP_LOCALEDIR "" +#endif + + +#endif /* _LDAP_CONFIG_H */ diff --git a/contrib/openldap-cmake/freebsd_aarch64/include/ldap_features.h b/contrib/openldap-cmake/freebsd_aarch64/include/ldap_features.h new file mode 100644 index 00000000000..f0cc7c3626f --- /dev/null +++ b/contrib/openldap-cmake/freebsd_aarch64/include/ldap_features.h @@ -0,0 +1,61 @@ +/* include/ldap_features.h. Generated from ldap_features.hin by configure. */ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2020 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +/* + * LDAP Features + */ + +#ifndef _LDAP_FEATURES_H +#define _LDAP_FEATURES_H 1 + +/* OpenLDAP API version macros */ +#define LDAP_VENDOR_VERSION 20501 +#define LDAP_VENDOR_VERSION_MAJOR 2 +#define LDAP_VENDOR_VERSION_MINOR 5 +#define LDAP_VENDOR_VERSION_PATCH X + +/* +** WORK IN PROGRESS! +** +** OpenLDAP reentrancy/thread-safeness should be dynamically +** checked using ldap_get_option(). +** +** The -lldap implementation is not thread-safe. +** +** The -lldap_r implementation is: +** LDAP_API_FEATURE_THREAD_SAFE (basic thread safety) +** but also be: +** LDAP_API_FEATURE_SESSION_THREAD_SAFE +** LDAP_API_FEATURE_OPERATION_THREAD_SAFE +** +** The preprocessor flag LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE +** can be used to determine if -lldap_r is available at compile +** time. You must define LDAP_THREAD_SAFE if and only if you +** link with -lldap_r. +** +** If you fail to define LDAP_THREAD_SAFE when linking with +** -lldap_r or define LDAP_THREAD_SAFE when linking with -lldap, +** provided header definitions and declarations may be incorrect. +** +*/ + +/* is -lldap_r available or not */ +#define LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 1 + +/* LDAP v2 Referrals */ +/* #undef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ + +#endif /* LDAP_FEATURES */ diff --git a/contrib/openldap-cmake/freebsd_aarch64/include/portable.h b/contrib/openldap-cmake/freebsd_aarch64/include/portable.h new file mode 100644 index 00000000000..10a15fe3ca1 --- /dev/null +++ b/contrib/openldap-cmake/freebsd_aarch64/include/portable.h @@ -0,0 +1,1169 @@ +/* include/portable.h. Generated from portable.hin by configure. */ +/* include/portable.hin. Generated from configure.in by autoheader. */ + + +/* begin of portable.h.pre */ +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2020 The OpenLDAP Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +#ifndef _LDAP_PORTABLE_H +#define _LDAP_PORTABLE_H + +/* define this if needed to get reentrant functions */ +#ifndef REENTRANT +#define REENTRANT 1 +#endif +#ifndef _REENTRANT +#define _REENTRANT 1 +#endif + +/* define this if needed to get threadsafe functions */ +#ifndef THREADSAFE +#define THREADSAFE 1 +#endif +#ifndef _THREADSAFE +#define _THREADSAFE 1 +#endif +#ifndef THREAD_SAFE +#define THREAD_SAFE 1 +#endif +#ifndef _THREAD_SAFE +#define _THREAD_SAFE 1 +#endif + +#ifndef _SGI_MP_SOURCE +#define _SGI_MP_SOURCE 1 +#endif + +/* end of portable.h.pre */ + + +/* Define if building universal (internal helper macro) */ +/* #undef AC_APPLE_UNIVERSAL_BUILD */ + +/* define to use both and */ +/* #undef BOTH_STRINGS_H */ + +/* define if cross compiling */ +/* #undef CROSS_COMPILING */ + +/* set to the number of arguments ctime_r() expects */ +#define CTIME_R_NARGS 2 + +/* define if toupper() requires islower() */ +/* #undef C_UPPER_LOWER */ + +/* define if sys_errlist is not declared in stdio.h or errno.h */ +/* #undef DECL_SYS_ERRLIST */ + +/* define to enable slapi library */ +/* #undef ENABLE_SLAPI */ + +/* defined to be the EXE extension */ +#define EXEEXT "" + +/* set to the number of arguments gethostbyaddr_r() expects */ +#define GETHOSTBYADDR_R_NARGS 8 + +/* set to the number of arguments gethostbyname_r() expects */ +#define GETHOSTBYNAME_R_NARGS 6 + +/* Define to 1 if `TIOCGWINSZ' requires . */ +/* #undef GWINSZ_IN_SYS_IOCTL */ + +/* define if you have AIX security lib */ +/* #undef HAVE_AIX_SECURITY */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `bcopy' function. */ +#define HAVE_BCOPY 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_BITS_TYPES_H */ + +/* Define to 1 if you have the `chroot' function. */ +#define HAVE_CHROOT 1 + +/* Define to 1 if you have the `closesocket' function. */ +/* #undef HAVE_CLOSESOCKET */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CONIO_H */ + +/* define if crypt(3) is available */ +/* #undef HAVE_CRYPT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CRYPT_H */ + +/* define if crypt_r() is also available */ +/* #undef HAVE_CRYPT_R */ + +/* Define to 1 if you have the `ctime_r' function. */ +#define HAVE_CTIME_R 1 + +/* define if you have Cyrus SASL */ +/* #undef HAVE_CYRUS_SASL */ + +/* define if your system supports /dev/poll */ +/* #undef HAVE_DEVPOLL */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DIRECT_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +/* #undef HAVE_DOPRNT */ + +/* define if system uses EBCDIC instead of ASCII */ +/* #undef HAVE_EBCDIC */ + +/* Define to 1 if you have the `endgrent' function. */ +#define HAVE_ENDGRENT 1 + +/* Define to 1 if you have the `endpwent' function. */ +#define HAVE_ENDPWENT 1 + +/* define if your system supports epoll */ +/* #undef HAVE_EPOLL */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `fcntl' function. */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* define if you actually have FreeBSD fetch(3) */ +/* #undef HAVE_FETCH */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_FILIO_H */ + +/* Define to 1 if you have the `flock' function. */ +#define HAVE_FLOCK 1 + +/* Define to 1 if you have the `fstat' function. */ +#define HAVE_FSTAT 1 + +/* Define to 1 if you have the `gai_strerror' function. */ +#define HAVE_GAI_STRERROR 1 + +/* Define to 1 if you have the `getaddrinfo' function. */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `getdtablesize' function. */ +#define HAVE_GETDTABLESIZE 1 + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define to 1 if you have the `getgrgid' function. */ +#define HAVE_GETGRGID 1 + +/* Define to 1 if you have the `gethostbyaddr_r' function. */ +#define HAVE_GETHOSTBYADDR_R 1 + +/* Define to 1 if you have the `gethostbyname_r' function. */ +#define HAVE_GETHOSTBYNAME_R 1 + +/* Define to 1 if you have the `gethostname' function. */ +#define HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have the `getnameinfo' function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define to 1 if you have the `getopt' function. */ +#define HAVE_GETOPT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define to 1 if you have the `getpassphrase' function. */ +/* #undef HAVE_GETPASSPHRASE */ + +/* Define to 1 if you have the `getpeereid' function. */ +#define HAVE_GETPEEREID 1 + +/* Define to 1 if you have the `getpeerucred' function. */ +/* #undef HAVE_GETPEERUCRED */ + +/* Define to 1 if you have the `getpwnam' function. */ +#define HAVE_GETPWNAM 1 + +/* Define to 1 if you have the `getpwuid' function. */ +#define HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getspnam' function. */ +/* #undef HAVE_GETSPNAM */ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GMP_H */ + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* define if you have GNUtls */ +/* #undef HAVE_GNUTLS */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GNUTLS_GNUTLS_H */ + +/* if you have GNU Pth */ +/* #undef HAVE_GNU_PTH */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GRP_H 1 + +/* Define to 1 if you have the `hstrerror' function. */ +#define HAVE_HSTRERROR 1 + +/* define to you inet_aton(3) is available */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the `inet_ntoa_b' function. */ +/* #undef HAVE_INET_NTOA_B */ + +/* Define to 1 if you have the `inet_ntop' function. */ +#define HAVE_INET_NTOP 1 + +/* Define to 1 if you have the `initgroups' function. */ +#define HAVE_INITGROUPS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `ioctl' function. */ +#define HAVE_IOCTL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_IO_H */ + +/* define if your system supports kqueue */ +#define HAVE_KQUEUE 1 + +/* Define to 1 if you have the `gen' library (-lgen). */ +/* #undef HAVE_LIBGEN */ + +/* Define to 1 if you have the `gmp' library (-lgmp). */ +/* #undef HAVE_LIBGMP */ + +/* Define to 1 if you have the `inet' library (-linet). */ +/* #undef HAVE_LIBINET */ + +/* define if you have libtool -ltdl */ +/* #undef HAVE_LIBLTDL */ + +/* Define to 1 if you have the `net' library (-lnet). */ +/* #undef HAVE_LIBNET */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `nsl_s' library (-lnsl_s). */ +/* #undef HAVE_LIBNSL_S */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBUTIL_H 1 + +/* Define to 1 if you have the `V3' library (-lV3). */ +/* #undef HAVE_LIBV3 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* if you have LinuxThreads */ +/* #undef HAVE_LINUX_THREADS */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if you have the `lockf' function. */ +#define HAVE_LOCKF 1 + +/* Define to 1 if the system has the type `long long'. */ +#define HAVE_LONG_LONG 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LTDL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MALLOC_H */ + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memrchr' function. */ +#define HAVE_MEMRCHR 1 + +/* Define to 1 if you have the `mkstemp' function. */ +#define HAVE_MKSTEMP 1 + +/* Define to 1 if you have the `mktemp' function. */ +#define HAVE_MKTEMP 1 + +/* define this if you have mkversion */ +#define HAVE_MKVERSION 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* define if strerror_r returns char* instead of int */ +/* #undef HAVE_NONPOSIX_STRERROR_R */ + +/* if you have NT Event Log */ +/* #undef HAVE_NT_EVENT_LOG */ + +/* if you have NT Service Manager */ +/* #undef HAVE_NT_SERVICE_MANAGER */ + +/* if you have NT Threads */ +/* #undef HAVE_NT_THREADS */ + +/* define if you have OpenSSL */ +#define HAVE_OPENSSL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_BN_H 1 + +/* define if you have OpenSSL with CRL checking capability */ +#define HAVE_OPENSSL_CRL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_CRYPTO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_OPENSSL_SSL_H 1 + +/* Define to 1 if you have the `pipe' function. */ +#define HAVE_PIPE 1 + +/* Define to 1 if you have the `poll' function. */ +#define HAVE_POLL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PROCESS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PSAP_H */ + +/* define to pthreads API spec revision */ +#define HAVE_PTHREADS 10 + +/* define if you have pthread_detach function */ +#define HAVE_PTHREAD_DETACH 1 + +/* Define to 1 if you have the `pthread_getconcurrency' function. */ +#define HAVE_PTHREAD_GETCONCURRENCY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the `pthread_kill' function. */ +#define HAVE_PTHREAD_KILL 1 + +/* Define to 1 if you have the `pthread_kill_other_threads_np' function. */ +/* #undef HAVE_PTHREAD_KILL_OTHER_THREADS_NP */ + +/* define if you have pthread_rwlock_destroy function */ +#define HAVE_PTHREAD_RWLOCK_DESTROY 1 + +/* Define to 1 if you have the `pthread_setconcurrency' function. */ +#define HAVE_PTHREAD_SETCONCURRENCY 1 + +/* Define to 1 if you have the `pthread_yield' function. */ +#define HAVE_PTHREAD_YIELD 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PTH_H */ + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#define HAVE_PTRDIFF_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define to 1 if you have the `read' function. */ +#define HAVE_READ 1 + +/* Define to 1 if you have the `recv' function. */ +#define HAVE_RECV 1 + +/* Define to 1 if you have the `recvfrom' function. */ +#define HAVE_RECVFROM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_RESOLV_H */ + +/* define if you have res_query() */ +/* #undef HAVE_RES_QUERY */ + +/* define if OpenSSL needs RSAref */ +/* #undef HAVE_RSAREF */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SASL_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SASL_SASL_H */ + +/* define if your SASL library has sasl_version() */ +/* #undef HAVE_SASL_VERSION */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SCHED_H 1 + +/* Define to 1 if you have the `sched_yield' function. */ +#define HAVE_SCHED_YIELD 1 + +/* Define to 1 if you have the `send' function. */ +#define HAVE_SEND 1 + +/* Define to 1 if you have the `sendmsg' function. */ +#define HAVE_SENDMSG 1 + +/* Define to 1 if you have the `sendto' function. */ +#define HAVE_SENDTO 1 + +/* Define to 1 if you have the `setegid' function. */ +#define HAVE_SETEGID 1 + +/* Define to 1 if you have the `seteuid' function. */ +#define HAVE_SETEUID 1 + +/* Define to 1 if you have the `setgid' function. */ +#define HAVE_SETGID 1 + +/* Define to 1 if you have the `setpwfile' function. */ +/* #undef HAVE_SETPWFILE */ + +/* Define to 1 if you have the `setsid' function. */ +#define HAVE_SETSID 1 + +/* Define to 1 if you have the `setuid' function. */ +#define HAVE_SETUID 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SGTTY_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SHADOW_H */ + +/* Define to 1 if you have the `sigaction' function. */ +#define HAVE_SIGACTION 1 + +/* Define to 1 if you have the `signal' function. */ +#define HAVE_SIGNAL 1 + +/* Define to 1 if you have the `sigset' function. */ +#define HAVE_SIGSET 1 + +/* define if you have -lslp */ +/* #undef HAVE_SLP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SLP_H */ + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* if you have spawnlp() */ +/* #undef HAVE_SPAWNLP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SQLEXT_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SQL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strpbrk' function. */ +#define HAVE_STRPBRK 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strsep' function. */ +#define HAVE_STRSEP 1 + +/* Define to 1 if you have the `strspn' function. */ +#define HAVE_STRSPN 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* Define to 1 if you have the `strtoq' function. */ +#define HAVE_STRTOQ 1 + +/* Define to 1 if you have the `strtoul' function. */ +#define HAVE_STRTOUL 1 + +/* Define to 1 if you have the `strtoull' function. */ +#define HAVE_STRTOULL 1 + +/* Define to 1 if you have the `strtouq' function. */ +#define HAVE_STRTOUQ 1 + +/* Define to 1 if `msg_accrightslen' is a member of `struct msghdr'. */ +/* #undef HAVE_STRUCT_MSGHDR_MSG_ACCRIGHTSLEN */ + +/* Define to 1 if `msg_control' is a member of `struct msghdr'. */ +/* #undef HAVE_STRUCT_MSGHDR_MSG_CONTROL */ + +/* Define to 1 if `pw_gecos' is a member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_GECOS 1 + +/* Define to 1 if `pw_passwd' is a member of `struct passwd'. */ +#define HAVE_STRUCT_PASSWD_PW_PASSWD 1 + +/* Define to 1 if `st_blksize' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 + +/* Define to 1 if `st_fstype' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_FSTYPE */ + +/* define to 1 if st_fstype is char * */ +/* #undef HAVE_STRUCT_STAT_ST_FSTYPE_CHAR */ + +/* define to 1 if st_fstype is int */ +/* #undef HAVE_STRUCT_STAT_ST_FSTYPE_INT */ + +/* Define to 1 if `st_vfstype' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_VFSTYPE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYNCH_H */ + +/* Define to 1 if you have the `sysconf' function. */ +#define HAVE_SYSCONF 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSEXITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_DEVPOLL_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_EPOLL_H */ + +/* define if you actually have sys_errlist in your libs */ +#define HAVE_SYS_ERRLIST 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_ERRNO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_EVENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILIO_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_FSTYP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_POLL_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_PRIVGRP_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_RESOURCE_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UCRED_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UN_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_UUID_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_VMOUNT_H */ + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* define if you have -lwrap */ +/* #undef HAVE_TCPD */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_TCPD_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMIOS_H 1 + +/* if you have Solaris LWP (thr) package */ +/* #undef HAVE_THR */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_THREAD_H */ + +/* Define to 1 if you have the `thr_getconcurrency' function. */ +/* #undef HAVE_THR_GETCONCURRENCY */ + +/* Define to 1 if you have the `thr_setconcurrency' function. */ +/* #undef HAVE_THR_SETCONCURRENCY */ + +/* Define to 1 if you have the `thr_yield' function. */ +/* #undef HAVE_THR_YIELD */ + +/* define if you have TLS */ +#define HAVE_TLS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UTIME_H 1 + +/* define if you have uuid_generate() */ +/* #undef HAVE_UUID_GENERATE */ + +/* define if you have uuid_to_str() */ +/* #undef HAVE_UUID_TO_STR */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UUID_UUID_H */ + +/* Define to 1 if you have the `vprintf' function. */ +#define HAVE_VPRINTF 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `wait4' function. */ +#define HAVE_WAIT4 1 + +/* Define to 1 if you have the `waitpid' function. */ +#define HAVE_WAITPID 1 + +/* define if you have winsock */ +/* #undef HAVE_WINSOCK */ + +/* define if you have winsock2 */ +/* #undef HAVE_WINSOCK2 */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WIREDTIGER_H */ + +/* Define to 1 if you have the `write' function. */ +#define HAVE_WRITE 1 + +/* define if select implicitly yields */ +#define HAVE_YIELDING_SELECT 1 + +/* Define to 1 if you have the `_vsnprintf' function. */ +/* #undef HAVE__VSNPRINTF */ + +/* define to 32-bit or greater integer type */ +#define LBER_INT_T int + +/* define to large integer type */ +#define LBER_LEN_T long + +/* define to socket descriptor type */ +#define LBER_SOCKET_T int + +/* define to large integer type */ +#define LBER_TAG_T long + +/* define to 1 if library is thread safe */ +#define LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE 1 + +/* define to LDAP VENDOR VERSION */ +/* #undef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ + +/* define this to add debugging code */ +/* #undef LDAP_DEBUG */ + +/* define if LDAP libs are dynamic */ +/* #undef LDAP_LIBS_DYNAMIC */ + +/* define to support PF_INET6 */ +#define LDAP_PF_INET6 1 + +/* define to support PF_LOCAL */ +#define LDAP_PF_LOCAL 1 + +/* define this to add SLAPI code */ +/* #undef LDAP_SLAPI */ + +/* define this to add syslog code */ +/* #undef LDAP_SYSLOG */ + +/* Version */ +#define LDAP_VENDOR_VERSION 20501 + +/* Major */ +#define LDAP_VENDOR_VERSION_MAJOR 2 + +/* Minor */ +#define LDAP_VENDOR_VERSION_MINOR 5 + +/* Patch */ +#define LDAP_VENDOR_VERSION_PATCH X + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* define if memcmp is not 8-bit clean or is otherwise broken */ +/* #undef NEED_MEMCMP_REPLACEMENT */ + +/* define if you have (or want) no threads */ +/* #undef NO_THREADS */ + +/* define to use the original debug style */ +/* #undef OLD_DEBUG */ + +/* Package */ +#define OPENLDAP_PACKAGE "OpenLDAP" + +/* Version */ +#define OPENLDAP_VERSION "2.5.X" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* define if sched_yield yields the entire process */ +/* #undef REPLACE_BROKEN_YIELD */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to the type of arg 1 for `select'. */ +#define SELECT_TYPE_ARG1 int + +/* Define to the type of args 2, 3 and 4 for `select'. */ +#define SELECT_TYPE_ARG234 (fd_set *) + +/* Define to the type of arg 5 for `select'. */ +#define SELECT_TYPE_ARG5 (struct timeval *) + +/* The size of `int', as computed by sizeof. */ +#define SIZEOF_INT 4 + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* The size of `long long', as computed by sizeof. */ +#define SIZEOF_LONG_LONG 8 + +/* The size of `short', as computed by sizeof. */ +#define SIZEOF_SHORT 2 + +/* The size of `wchar_t', as computed by sizeof. */ +#define SIZEOF_WCHAR_T 4 + +/* define to support per-object ACIs */ +/* #undef SLAPD_ACI_ENABLED */ + +/* define to support LDAP Async Metadirectory backend */ +/* #undef SLAPD_ASYNCMETA */ + +/* define to support cleartext passwords */ +/* #undef SLAPD_CLEARTEXT */ + +/* define to support crypt(3) passwords */ +/* #undef SLAPD_CRYPT */ + +/* define to support DNS SRV backend */ +/* #undef SLAPD_DNSSRV */ + +/* define to support LDAP backend */ +/* #undef SLAPD_LDAP */ + +/* define to support MDB backend */ +/* #undef SLAPD_MDB */ + +/* define to support LDAP Metadirectory backend */ +/* #undef SLAPD_META */ + +/* define to support modules */ +/* #undef SLAPD_MODULES */ + +/* dynamically linked module */ +#define SLAPD_MOD_DYNAMIC 2 + +/* statically linked module */ +#define SLAPD_MOD_STATIC 1 + +/* define to support cn=Monitor backend */ +/* #undef SLAPD_MONITOR */ + +/* define to support NDB backend */ +/* #undef SLAPD_NDB */ + +/* define to support NULL backend */ +/* #undef SLAPD_NULL */ + +/* define for In-Directory Access Logging overlay */ +/* #undef SLAPD_OVER_ACCESSLOG */ + +/* define for Audit Logging overlay */ +/* #undef SLAPD_OVER_AUDITLOG */ + +/* define for Automatic Certificate Authority overlay */ +/* #undef SLAPD_OVER_AUTOCA */ + +/* define for Collect overlay */ +/* #undef SLAPD_OVER_COLLECT */ + +/* define for Attribute Constraint overlay */ +/* #undef SLAPD_OVER_CONSTRAINT */ + +/* define for Dynamic Directory Services overlay */ +/* #undef SLAPD_OVER_DDS */ + +/* define for Dynamic Directory Services overlay */ +/* #undef SLAPD_OVER_DEREF */ + +/* define for Dynamic Group overlay */ +/* #undef SLAPD_OVER_DYNGROUP */ + +/* define for Dynamic List overlay */ +/* #undef SLAPD_OVER_DYNLIST */ + +/* define for Reverse Group Membership overlay */ +/* #undef SLAPD_OVER_MEMBEROF */ + +/* define for Password Policy overlay */ +/* #undef SLAPD_OVER_PPOLICY */ + +/* define for Proxy Cache overlay */ +/* #undef SLAPD_OVER_PROXYCACHE */ + +/* define for Referential Integrity overlay */ +/* #undef SLAPD_OVER_REFINT */ + +/* define for Return Code overlay */ +/* #undef SLAPD_OVER_RETCODE */ + +/* define for Rewrite/Remap overlay */ +/* #undef SLAPD_OVER_RWM */ + +/* define for Sequential Modify overlay */ +/* #undef SLAPD_OVER_SEQMOD */ + +/* define for ServerSideSort/VLV overlay */ +/* #undef SLAPD_OVER_SSSVLV */ + +/* define for Syncrepl Provider overlay */ +/* #undef SLAPD_OVER_SYNCPROV */ + +/* define for Translucent Proxy overlay */ +/* #undef SLAPD_OVER_TRANSLUCENT */ + +/* define for Attribute Uniqueness overlay */ +/* #undef SLAPD_OVER_UNIQUE */ + +/* define for Value Sorting overlay */ +/* #undef SLAPD_OVER_VALSORT */ + +/* define to support PASSWD backend */ +/* #undef SLAPD_PASSWD */ + +/* define to support PERL backend */ +/* #undef SLAPD_PERL */ + +/* define to support relay backend */ +/* #undef SLAPD_RELAY */ + +/* define to support reverse lookups */ +/* #undef SLAPD_RLOOKUPS */ + +/* define to support SHELL backend */ +/* #undef SLAPD_SHELL */ + +/* define to support SOCK backend */ +/* #undef SLAPD_SOCK */ + +/* define to support SASL passwords */ +/* #undef SLAPD_SPASSWD */ + +/* define to support SQL backend */ +/* #undef SLAPD_SQL */ + +/* define to support WiredTiger backend */ +/* #undef SLAPD_WT */ + +/* define to support run-time loadable ACL */ +/* #undef SLAP_DYNACL */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* set to urandom device */ +#define URANDOM_DEVICE "/dev/urandom" + +/* define to use OpenSSL BIGNUM for MP */ +/* #undef USE_MP_BIGNUM */ + +/* define to use GMP for MP */ +/* #undef USE_MP_GMP */ + +/* define to use 'long' for MP */ +/* #undef USE_MP_LONG */ + +/* define to use 'long long' for MP */ +/* #undef USE_MP_LONG_LONG */ + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to the type of arg 3 for `accept'. */ +#define ber_socklen_t socklen_t + +/* Define to `char *' if does not define. */ +/* #undef caddr_t */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `int' if does not define. */ +/* #undef mode_t */ + +/* Define to `long' if does not define. */ +/* #undef off_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to `int' if does not define. */ +/* #undef sig_atomic_t */ + +/* Define to `unsigned' if does not define. */ +/* #undef size_t */ + +/* define to snprintf routine */ +/* #undef snprintf */ + +/* Define like ber_socklen_t if does not define. */ +/* #undef socklen_t */ + +/* Define to `signed int' if does not define. */ +/* #undef ssize_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* define as empty if volatile is not supported */ +/* #undef volatile */ + +/* define to snprintf routine */ +/* #undef vsnprintf */ + + +/* begin of portable.h.post */ + +#ifdef _WIN32 +/* don't suck in all of the win32 api */ +# define WIN32_LEAN_AND_MEAN 1 +#endif + +#ifndef LDAP_NEEDS_PROTOTYPES +/* force LDAP_P to always include prototypes */ +#define LDAP_NEEDS_PROTOTYPES 1 +#endif + +#ifndef LDAP_REL_ENG +#if (LDAP_VENDOR_VERSION == 000000) && !defined(LDAP_DEVEL) +#define LDAP_DEVEL +#endif +#if defined(LDAP_DEVEL) && !defined(LDAP_TEST) +#define LDAP_TEST +#endif +#endif + +#ifdef HAVE_STDDEF_H +# include +#endif + +#ifdef HAVE_EBCDIC +/* ASCII/EBCDIC converting replacements for stdio funcs + * vsnprintf and snprintf are used too, but they are already + * checked by the configure script + */ +#define fputs ber_pvt_fputs +#define fgets ber_pvt_fgets +#define printf ber_pvt_printf +#define fprintf ber_pvt_fprintf +#define vfprintf ber_pvt_vfprintf +#define vsprintf ber_pvt_vsprintf +#endif + +#include "ac/fdset.h" + +#include "ldap_cdefs.h" +#include "ldap_features.h" + +#include "ac/assert.h" +#include "ac/localize.h" + +#endif /* _LDAP_PORTABLE_H */ +/* end of portable.h.post */ + diff --git a/contrib/rocksdb-cmake/CMakeLists.txt b/contrib/rocksdb-cmake/CMakeLists.txt index e7ff1f548e3..e7fd7533fff 100644 --- a/contrib/rocksdb-cmake/CMakeLists.txt +++ b/contrib/rocksdb-cmake/CMakeLists.txt @@ -228,6 +228,11 @@ if(HAVE_AUXV_GETAUXVAL) add_definitions(-DROCKSDB_AUXV_GETAUXVAL_PRESENT) endif() +check_cxx_symbol_exists(elf_aux_info sys/auxv.h HAVE_ELF_AUX_INFO) +if(HAVE_ELF_AUX_INFO) + add_definitions(-DROCKSDB_AUXV_GETAUXVAL_PRESENT) +endif() + include_directories(${ROCKSDB_SOURCE_DIR}) include_directories("${ROCKSDB_SOURCE_DIR}/include") if(WITH_FOLLY_DISTRIBUTED_MUTEX) From 1dda59668918e894b773a6595b9738ab326a1b99 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Sun, 10 Oct 2021 17:32:01 +0300 Subject: [PATCH 139/264] Fix releasing query ID and session ID at the end of query processing. --- src/Interpreters/Session.cpp | 9 +++++++++ src/Interpreters/Session.h | 3 +++ src/Server/GRPCServer.cpp | 17 ++++++++++++++++- tests/integration/test_grpc_protocol/test.py | 2 +- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/Interpreters/Session.cpp b/src/Interpreters/Session.cpp index 128df040c7a..5f1b43fe1e8 100644 --- a/src/Interpreters/Session.cpp +++ b/src/Interpreters/Session.cpp @@ -481,5 +481,14 @@ ContextMutablePtr Session::makeQueryContextImpl(const ClientInfo * client_info_t return query_context; } + +void Session::releaseSessionID() +{ + if (!named_session) + return; + named_session->release(); + named_session = nullptr; +} + } diff --git a/src/Interpreters/Session.h b/src/Interpreters/Session.h index 772ccba7766..ab269bb619c 100644 --- a/src/Interpreters/Session.h +++ b/src/Interpreters/Session.h @@ -68,6 +68,9 @@ public: ContextMutablePtr makeQueryContext(const ClientInfo & query_client_info) const; ContextMutablePtr makeQueryContext(ClientInfo && query_client_info) const; + /// Releases the currently used session ID so it becomes available for reuse by another session. + void releaseSessionID(); + private: std::shared_ptr getSessionLog() const; ContextMutablePtr makeQueryContextImpl(const ClientInfo * client_info_to_copy, ClientInfo * client_info_to_move) const; diff --git a/src/Server/GRPCServer.cpp b/src/Server/GRPCServer.cpp index 0fb9d82aca6..7aa1ca06990 100644 --- a/src/Server/GRPCServer.cpp +++ b/src/Server/GRPCServer.cpp @@ -584,6 +584,7 @@ namespace void finishQuery(); void onException(const Exception & exception); void onFatalError(); + void releaseQueryIDAndSessionID(); void close(); void readQueryInfo(); @@ -1175,6 +1176,7 @@ namespace addProgressToResult(); query_scope->logPeakMemoryUsage(); addLogsToResult(); + releaseQueryIDAndSessionID(); sendResult(); close(); @@ -1205,6 +1207,8 @@ namespace LOG_WARNING(log, "Couldn't send logs to client"); } + releaseQueryIDAndSessionID(); + try { sendException(exception); @@ -1224,7 +1228,7 @@ namespace { try { - finalize = true; + result.mutable_exception()->set_name("FatalError"); addLogsToResult(); sendResult(); } @@ -1234,6 +1238,17 @@ namespace } } + void Call::releaseQueryIDAndSessionID() + { + /// releaseQueryIDAndSessionID() should be called before sending the final result to the client + /// because the client may decide to send another query with the same query ID or session ID + /// immediately after it receives our final result, and it's prohibited to have + /// two queries executed at the same time with the same query ID or session ID. + io.process_list_entry.reset(); + if (session) + session->releaseSessionID(); + } + void Call::close() { responder.reset(); diff --git a/tests/integration/test_grpc_protocol/test.py b/tests/integration/test_grpc_protocol/test.py index 79879c13c9d..7b2cdee8d76 100644 --- a/tests/integration/test_grpc_protocol/test.py +++ b/tests/integration/test_grpc_protocol/test.py @@ -211,7 +211,7 @@ def test_errors_handling(): assert "Table default.t already exists" in e.display_text def test_authentication(): - query("CREATE USER john IDENTIFIED BY 'qwe123'") + query("CREATE USER OR REPLACE john IDENTIFIED BY 'qwe123'") assert query("SELECT currentUser()", user_name="john", password="qwe123") == "john\n" def test_logs(): From 934b72ddd14dd4e3f01f126c452af238fba33d48 Mon Sep 17 00:00:00 2001 From: mikael Date: Sun, 10 Oct 2021 18:54:38 +0200 Subject: [PATCH 140/264] Add FreeBSD aarch64 bits for cross-builds for CI. --- cmake/freebsd/toolchain-aarch64.cmake | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 cmake/freebsd/toolchain-aarch64.cmake diff --git a/cmake/freebsd/toolchain-aarch64.cmake b/cmake/freebsd/toolchain-aarch64.cmake new file mode 100644 index 00000000000..b8fdb4bbb7c --- /dev/null +++ b/cmake/freebsd/toolchain-aarch64.cmake @@ -0,0 +1,22 @@ +set (CMAKE_SYSTEM_NAME "FreeBSD") +set (CMAKE_SYSTEM_PROCESSOR "aarch64") +set (CMAKE_C_COMPILER_TARGET "aarch64-unknown-freebsd12") +set (CMAKE_CXX_COMPILER_TARGET "aarch64-unknown-freebsd12") +set (CMAKE_ASM_COMPILER_TARGET "aarch64-unknown-freebsd12") +set (CMAKE_SYSROOT "${CMAKE_CURRENT_LIST_DIR}/../toolchain/freebsd-aarch64") + +set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) # disable linkage check - it doesn't work in CMake + +set (CMAKE_AR "/usr/bin/ar" CACHE FILEPATH "" FORCE) +set (CMAKE_RANLIB "/usr/bin/ranlib" CACHE FILEPATH "" FORCE) + +set (LINKER_NAME "ld.lld" CACHE STRING "" FORCE) + +set (CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld") +set (CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld") + +set (HAS_PRE_1970_EXITCODE "0" CACHE STRING "Result from TRY_RUN" FORCE) +set (HAS_PRE_1970_EXITCODE__TRYRUN_OUTPUT "" CACHE STRING "Output from TRY_RUN" FORCE) + +set (HAS_POST_2038_EXITCODE "0" CACHE STRING "Result from TRY_RUN" FORCE) +set (HAS_POST_2038_EXITCODE__TRYRUN_OUTPUT "" CACHE STRING "Output from TRY_RUN" FORCE) From af4066c255149d1ab1cef9b7fba0c9c47d1bb265 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 10 Oct 2021 21:54:15 +0300 Subject: [PATCH 141/264] Remove printf --- base/daemon/SentryWriter.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/base/daemon/SentryWriter.cpp b/base/daemon/SentryWriter.cpp index efd915b1e5b..ac771b9bf47 100644 --- a/base/daemon/SentryWriter.cpp +++ b/base/daemon/SentryWriter.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #if !defined(ARCADIA_BUILD) # include "Common/config_version.h" @@ -163,34 +164,34 @@ void SentryWriter::onFault(int sig, const std::string & error_message, const Sta if (stack_size > 0) { ssize_t offset = stack_trace.getOffset(); - char instruction_addr[100]; + + char instruction_addr[19] + { + '0', 'x', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', + '\0' + }; + StackTrace::Frames frames; StackTrace::symbolize(stack_trace.getFramePointers(), offset, stack_size, frames); + for (ssize_t i = stack_size - 1; i >= offset; --i) { const StackTrace::Frame & current_frame = frames[i]; sentry_value_t sentry_frame = sentry_value_new_object(); UInt64 frame_ptr = reinterpret_cast(current_frame.virtual_addr); - if (std::snprintf(instruction_addr, sizeof(instruction_addr), "0x%" PRIx64, frame_ptr) >= 0) - { - sentry_value_set_by_key(sentry_frame, "instruction_addr", sentry_value_new_string(instruction_addr)); - } + writeHexUIntLowercase(frame_ptr, instruction_addr + 2); + sentry_value_set_by_key(sentry_frame, "instruction_addr", sentry_value_new_string(instruction_addr)); if (current_frame.symbol.has_value()) - { sentry_value_set_by_key(sentry_frame, "function", sentry_value_new_string(current_frame.symbol.value().c_str())); - } if (current_frame.file.has_value()) - { sentry_value_set_by_key(sentry_frame, "filename", sentry_value_new_string(current_frame.file.value().c_str())); - } if (current_frame.line.has_value()) - { sentry_value_set_by_key(sentry_frame, "lineno", sentry_value_new_int32(current_frame.line.value())); - } sentry_value_append(sentry_frames, sentry_frame); } From 6c33eaee325e71bcf582f255321aafc7d2a7aa76 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 22:23:05 +0300 Subject: [PATCH 142/264] Fix filtering by tuple (some conditions was lost during analyzing) Fixes: #29281 Fixes: test_cluster_copier/test_three_nodes.py::test --- src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp | 2 +- tests/queries/0_stateless/02030_tuple_filter.reference | 1 - tests/queries/0_stateless/02030_tuple_filter.sql | 7 ++++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp b/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp index b0071d481d6..a32eecd4a49 100644 --- a/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp +++ b/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp @@ -158,7 +158,7 @@ bool MergeTreeWhereOptimizer::tryAnalyzeTuple(Conditions & res, const ASTFunctio else if (const auto * child_ident = child->as()) fetch_sign_column = std::make_shared(child_ident->name()); else - continue; + return false; ASTPtr fetch_sign_value = std::make_shared(tuple_lit.at(i)); ASTPtr func_node = makeASTFunction("equals", fetch_sign_column, fetch_sign_value); diff --git a/tests/queries/0_stateless/02030_tuple_filter.reference b/tests/queries/0_stateless/02030_tuple_filter.reference index b7bd4c157f0..a2e1290c0e1 100644 --- a/tests/queries/0_stateless/02030_tuple_filter.reference +++ b/tests/queries/0_stateless/02030_tuple_filter.reference @@ -6,4 +6,3 @@ 1 A 2021-01-01 1 A 2021-01-01 1 A 2021-01-01 -1 A 2021-01-01 diff --git a/tests/queries/0_stateless/02030_tuple_filter.sql b/tests/queries/0_stateless/02030_tuple_filter.sql index 606955adcb7..5efedeb8c0d 100644 --- a/tests/queries/0_stateless/02030_tuple_filter.sql +++ b/tests/queries/0_stateless/02030_tuple_filter.sql @@ -11,7 +11,12 @@ SELECT * FROM test_tuple_filter WHERE (1, 'A') = (id, value); SELECT * FROM test_tuple_filter WHERE (id, value) = (1, 'A') AND (id, log_date) = (1, '2021-01-01'); SELECT * FROM test_tuple_filter WHERE ((id, value), id * 2) = ((1, 'A'), 2); SELECT * FROM test_tuple_filter WHERE ((id, value), log_date) = ((1, 'A'), '2021-01-01'); -SELECT * FROM test_tuple_filter WHERE (1, (1, (1, (1, (id, value))))) = (1, (1, (1, (1, (1, 'A'))))); + +-- not supported functions (concat) do not lost +SELECT * FROM test_tuple_filter WHERE (id, value, value||'foo') = ('1', 'A', 'A'); + +-- Condition fully moved to PREWHERE and such conditions does not supported yet. +SELECT * FROM test_tuple_filter WHERE (1, (1, (1, (1, (id, value))))) = (1, (1, (1, (1, (1, 'A'))))); -- { serverError INDEX_NOT_USED } -- not implemented yet SELECT * FROM test_tuple_filter WHERE (1, value) = (id, 'A'); -- { serverError INDEX_NOT_USED } From b83655b348f93cc4f720f61921d57d59f19f0dc8 Mon Sep 17 00:00:00 2001 From: Alexey Date: Sun, 10 Oct 2021 19:38:53 +0000 Subject: [PATCH 143/264] ru translation --- .../functions/other-functions.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index 31e81b04330..c91d5caef8d 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -2313,3 +2313,65 @@ SELECT count(DISTINCT t) FROM (SELECT initialQueryID() AS t FROM remote('127.0.0 └─────────┘ ``` +## shardNum {#shard-num} + +Возвращает индекс шарда, который обрабатывает часть данных распределенного запроса. Индексы начинаются с `1`. +Если запрос не распределенный, то возвращается константное значение `0`. + +**Синтаксис** + +``` sql +shardNum() +``` + +**Возвращаемое значение** + +- индекс шарда или константа `0`. + +Тип: [UInt32](../../sql-reference/data-types/int-uint.md). + +**Пример** + +В примере ниже используется конфигурация с двумя шардами. На каждом шарде выполняется запрос к таблице [system.one](../../operations/system-tables/one.md). + +Запрос: + +``` sql +CREATE TABLE shard_num_example (dummy UInt8) + ENGINE=Distributed(test_cluster_two_shards_localhost, system, one, dummy); +SELECT dummy, shardNum(), shardCount() FROM shard_num_example; +``` + +Результат: + +``` text +┌─dummy─┬─shardNum()─┬─shardCount()─┐ +│ 0 │ 2 │ 2 │ +│ 0 │ 1 │ 2 │ +└───────┴────────────┴──────────────┘ +``` + +**См. также** + +- [Distributed Table Engine](../../engines/table-engines/special/distributed.md) + +## shardCount {#shard-count} + +Возвращает общее количество шардов для распределенного запроса. +Если запрос не распределенный, то возвращается константное значение `0`. + +**Синтаксис** + +``` sql +shardCount() +``` + +**Возвращаемое значение** + +- Общее количество шардов или `0`. + +Тип: [UInt32](../../sql-reference/data-types/int-uint.md). + +**См. также** + +- Пример использования функции [shardNum()](#shard-num) также содержит вызов `shardCount()`. From e229847862dfa708a9dd2f06fc3c10372a684681 Mon Sep 17 00:00:00 2001 From: Thom O'Connor Date: Sun, 10 Oct 2021 14:42:06 -0600 Subject: [PATCH 144/264] Documentation correction for units for block size, plus some additional context for storage system recommendations --- docs/en/operations/tips.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/operations/tips.md b/docs/en/operations/tips.md index f7199372c80..27fc7d47a76 100644 --- a/docs/en/operations/tips.md +++ b/docs/en/operations/tips.md @@ -60,7 +60,7 @@ $ echo 4096 | sudo tee /sys/block/md2/md/stripe_cache_size Calculate the exact number from the number of devices and the block size, using the formula: `2 * num_devices * chunk_size_in_bytes / 4096`. -A block size of 1024 KB is sufficient for all RAID configurations. +A block size of 1024 bytes (1KB) is sufficient for most RAID configurations. A block size range of 1KB to 16KB is common across many storage system vendors or DBMS. Never set the block size too small or too large. You can use RAID-0 on SSD. From f37dac03f46790317e4ea5957ff64056ea189beb Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 10 Oct 2021 01:00:47 +0300 Subject: [PATCH 145/264] Fix lock-order-inversion between DROP TABLE for DatabaseMemory and LiveView CI stress founds [1], TSan report: WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock) (pid=509) Cycle in lock order graph: M71436201 (0x7b5800a91308) => M237700395169415472 (0x000000000000) => M71436201 Mutex M237700395169415472 acquired here while holding mutex M71436201 in thread T723: 3 std::__1::lock_guard::lock_guard(std::__1::mutex&) obj-x86_64-linux-gnu/../contrib/libcxx/include/__mutex_base:91:27 (clickhouse+0x154b0db9) 4 DB::DatabaseWithOwnTablesBase::tryGetTable() const obj-x86_64-linux-gnu/../src/Databases/DatabasesCommon.cpp:37:21 (clickhouse+0x154b0db9) 5 DB::DatabaseMemory::tryGetTableUUID() const obj-x86_64-linux-gnu/../src/Databases/DatabaseMemory.cpp:95:22 (clickhouse+0x15466bb5) 6 DB::Context::resolveStorageID() const obj-x86_64-linux-gnu/../src/Interpreters/Context.cpp:2672:90 (clickhouse+0x155e6aa1) 7 DB::JoinedTables::getLeftTableStorage() obj-x86_64-linux-gnu/../src/Interpreters/JoinedTables.cpp:200:29 (clickhouse+0x15eee962) 8 DB::InterpreterSelectQuery::InterpreterSelectQuery() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:321:33 (clickhouse+0x15b792be) 9 DB::InterpreterSelectQuery::InterpreterSelectQuery() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterSelectQuery.cpp:160:7 (clickhouse+0x15b78160) 10 DB::StorageLiveView::collectMergeableBlocks() obj-x86_64-linux-gnu/../src/Storages/LiveView/StorageLiveView.cpp:113:28 (clickhouse+0x16aae192) 11 DB::StorageLiveView::getNewBlocks() obj-x86_64-linux-gnu/../src/Storages/LiveView/StorageLiveView.cpp:384:33 (clickhouse+0x16ab393a) 12 DB::StorageLiveView::refresh(bool) obj-x86_64-linux-gnu/../src/Storages/LiveView/StorageLiveView.cpp:528:13 (clickhouse+0x16ab6395) 13 DB::StorageLiveView::read() obj-x86_64-linux-gnu/../src/Storages/LiveView/StorageLiveView.cpp:545:9 (clickhouse+0x16ab6395) 21 DB::executeQuery(std::__1::basic_string, std::__1::allocator > const&, std::__1::shared_ptr, bool, DB::QueryProcessingStage::Enum) obj-x86_64-linux-gnu/../src/Interpreters/executeQuery.cpp:950:30 (clickhouse+0x16101441) Hint: use TSAN_OPTIONS=second_deadlock_stack=1 to get more informative warning message Mutex M71436201 acquired here while holding mutex M237700395169415472 in thread T723: 3 std::__1::lock_guard::lock_guard(std::__1::mutex&) obj-x86_64-linux-gnu/../contrib/libcxx/include/__mutex_base:91:27 (clickhouse+0x16ab5c29) 4 DB::StorageLiveView::drop() obj-x86_64-linux-gnu/../src/Storages/LiveView/StorageLiveView.cpp:477:21 (clickhouse+0x16ab5c29) 5 DB::DatabaseMemory::dropTable() obj-x86_64-linux-gnu/../src/Databases/DatabaseMemory.cpp:44:16 (clickhouse+0x15465cd6) 8 DB::InterpreterDropQuery::execute() obj-x86_64-linux-gnu/../src/Interpreters/InterpreterDropQuery.cpp:62:16 (clickhouse+0x15afa679) [1]: https://clickhouse-test-reports.s3.yandex.net/29856/42ca2b4bb241827edf69bbd6938d6b19c31935f1/stress_test_(thread).html#fail1 v2: fix attachTableUnlocked() (as pointed by @tavplubix) v3: use SCOPE_EXIT() and so avoid holding a lock during removing from fs --- src/Databases/DatabaseMemory.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Databases/DatabaseMemory.cpp b/src/Databases/DatabaseMemory.cpp index 8f909d280c5..ff4021cf6d2 100644 --- a/src/Databases/DatabaseMemory.cpp +++ b/src/Databases/DatabaseMemory.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -41,7 +42,14 @@ void DatabaseMemory::dropTable( auto table = detachTableUnlocked(table_name, lock); try { + /// Remove table w/o lock since: + /// - it does not require it + /// - it may cause lock-order-inversion if underlying storage need to + /// resolve tables (like StorageLiveView) + SCOPE_EXIT(lock.lock()); + lock.unlock(); table->drop(); + if (table->storesDataOnDisk()) { assert(database_name != DatabaseCatalog::TEMPORARY_DATABASE); From 07aea95a755ab5c5fdfe9123f56f2e1bdd435b87 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Mon, 11 Oct 2021 00:00:12 +0300 Subject: [PATCH 146/264] Fix rabbitmq tests. --- .../integration/test_storage_rabbitmq/test.py | 55 +------------------ 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/tests/integration/test_storage_rabbitmq/test.py b/tests/integration/test_storage_rabbitmq/test.py index 696294f4bde..36d63588386 100644 --- a/tests/integration/test_storage_rabbitmq/test.py +++ b/tests/integration/test_storage_rabbitmq/test.py @@ -65,7 +65,8 @@ def rabbitmq_cluster(): def rabbitmq_setup_teardown(): print("RabbitMQ is available - running test") yield # run test - instance.query('DROP TABLE IF EXISTS test.rabbitmq') + for table_name in ['view', 'consumer', 'rabbitmq']: + instance.query(f'DROP TABLE IF EXISTS test.{table_name}') # Tests @@ -195,8 +196,6 @@ def test_rabbitmq_csv_with_delimiter(rabbitmq_cluster): def test_rabbitmq_tsv_with_delimiter(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.rabbitmq (key UInt64, value UInt64) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -266,8 +265,6 @@ def test_rabbitmq_macros(rabbitmq_cluster): def test_rabbitmq_materialized_view(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.rabbitmq (key UInt64, value UInt64) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -297,19 +294,12 @@ def test_rabbitmq_materialized_view(rabbitmq_cluster): if (rabbitmq_check_result(result)): break - instance.query(''' - DROP TABLE test.consumer; - DROP TABLE test.view; - ''') - connection.close() rabbitmq_check_result(result, True) def test_rabbitmq_materialized_view_with_subquery(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.rabbitmq (key UInt64, value UInt64) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -339,11 +329,6 @@ def test_rabbitmq_materialized_view_with_subquery(rabbitmq_cluster): if rabbitmq_check_result(result): break - instance.query(''' - DROP TABLE test.consumer; - DROP TABLE test.view; - ''') - connection.close() rabbitmq_check_result(result, True) @@ -404,8 +389,6 @@ def test_rabbitmq_many_materialized_views(rabbitmq_cluster): @pytest.mark.skip(reason="clichouse_path with rabbitmq.proto fails to be exported") def test_rabbitmq_protobuf(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.rabbitmq (key UInt64, value String) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -457,11 +440,6 @@ def test_rabbitmq_protobuf(rabbitmq_cluster): if rabbitmq_check_result(result): break - instance.query(''' - DROP TABLE test.consumer; - DROP TABLE test.view; - ''') - rabbitmq_check_result(result, True) @@ -477,8 +455,6 @@ def test_rabbitmq_big_message(rabbitmq_cluster): channel = connection.channel() instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.rabbitmq (key UInt64, value String) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -500,10 +476,6 @@ def test_rabbitmq_big_message(rabbitmq_cluster): break connection.close() - instance.query(''' - DROP TABLE test.consumer; - DROP TABLE test.view; - ''') assert int(result) == rabbitmq_messages * batch_messages, 'ClickHouse lost some messages: {}'.format(result) @@ -521,8 +493,6 @@ def test_rabbitmq_sharding_between_queues_publish(rabbitmq_cluster): rabbitmq_num_consumers = 10, rabbitmq_format = 'JSONEachRow', rabbitmq_row_delimiter = '\\n'; - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view (key UInt64, value UInt64, channel_id String) ENGINE = MergeTree ORDER BY key @@ -1398,7 +1368,6 @@ def test_rabbitmq_headers_exchange(rabbitmq_cluster): def test_rabbitmq_virtual_columns(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; CREATE TABLE test.rabbitmq_virtuals (key UInt64, value UInt64) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -1459,8 +1428,6 @@ def test_rabbitmq_virtual_columns(rabbitmq_cluster): def test_rabbitmq_virtual_columns_with_materialized_view(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.rabbitmq_virtuals_mv (key UInt64, value UInt64) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -1606,8 +1573,6 @@ def test_rabbitmq_many_consumers_to_each_queue(rabbitmq_cluster): def test_rabbitmq_restore_failed_connection_without_losses_1(rabbitmq_cluster): instance.query(''' DROP TABLE IF EXISTS test.consume; - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view (key UInt64, value UInt64) ENGINE = MergeTree ORDER BY key; @@ -1665,8 +1630,6 @@ def test_rabbitmq_restore_failed_connection_without_losses_1(rabbitmq_cluster): break instance.query(''' - DROP TABLE test.consumer; - DROP TABLE test.view; DROP TABLE test.consume; DROP TABLE test.producer_reconnect; ''') @@ -1703,8 +1666,6 @@ def test_rabbitmq_restore_failed_connection_without_losses_2(rabbitmq_cluster): properties=pika.BasicProperties(delivery_mode=2, message_id=str(msg_id))) connection.close() instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view (key UInt64, value UInt64) ENGINE = MergeTree ORDER BY key; @@ -1743,9 +1704,6 @@ def test_rabbitmq_restore_failed_connection_without_losses_2(rabbitmq_cluster): def test_rabbitmq_commit_on_block_write(rabbitmq_cluster): instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; - DROP TABLE IF EXISTS test.rabbitmq; CREATE TABLE test.rabbitmq (key UInt64, value UInt64) ENGINE = RabbitMQ SETTINGS rabbitmq_host_port = 'rabbitmq1:5672', @@ -1834,8 +1792,6 @@ def test_rabbitmq_no_connection_at_startup_2(rabbitmq_cluster): rabbitmq_format = 'JSONEachRow', rabbitmq_num_consumers = '5', rabbitmq_row_delimiter = '\\n'; - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view (key UInt64, value UInt64) ENGINE = MergeTree ORDER BY key; @@ -1899,8 +1855,6 @@ def test_rabbitmq_format_factory_settings(rabbitmq_cluster): break; instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view ( id String, date DateTime ) ENGINE = MergeTree ORDER BY id; @@ -2002,8 +1956,6 @@ def test_rabbitmq_queue_settings(rabbitmq_cluster): connection.close() instance.query(''' - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view (key UInt64, value UInt64) ENGINE = MergeTree ORDER BY key; CREATE MATERIALIZED VIEW test.consumer TO test.view AS @@ -2056,9 +2008,6 @@ def test_rabbitmq_queue_consume(rabbitmq_cluster): rabbitmq_format = 'JSONEachRow', rabbitmq_queue_base = 'rabbit_queue', rabbitmq_queue_consume = 1; - - DROP TABLE IF EXISTS test.view; - DROP TABLE IF EXISTS test.consumer; CREATE TABLE test.view (key UInt64, value UInt64) ENGINE = MergeTree ORDER BY key; CREATE MATERIALIZED VIEW test.consumer TO test.view AS From 341eb1f9bfb1a60e19f1159b9e7f1822ed7010c4 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 11 Oct 2021 00:05:53 +0300 Subject: [PATCH 147/264] Update adopters.md --- docs/en/introduction/adopters.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/introduction/adopters.md b/docs/en/introduction/adopters.md index 20bf9a10986..a6df18b323c 100644 --- a/docs/en/introduction/adopters.md +++ b/docs/en/introduction/adopters.md @@ -162,5 +162,6 @@ toc_title: Adopters | Zagrava Trading | — | — | — | — | [Job offer, May 2021](https://twitter.com/datastackjobs/status/1394707267082063874) | | Beeline | Telecom | Data Platform | — | — | [Blog post, July 2021](https://habr.com/en/company/beeline/blog/567508/) | | Ecommpay | Payment Processing | Logs | — | — | [Video, Nov 2019](https://www.youtube.com/watch?v=d3GdZTOWGLk) | +| Omnicomm | Transportation Monitoring | — | — | — | [Facebook post, Oct 2021](https://www.facebook.com/OmnicommTeam/posts/2824479777774500) | [Original article](https://clickhouse.com/docs/en/introduction/adopters/) From cb8a66e5155b0e4c1be0a037db8c54f48d47372c Mon Sep 17 00:00:00 2001 From: olgarev Date: Sun, 10 Oct 2021 23:34:26 +0000 Subject: [PATCH 148/264] Settings and links --- docs/en/operations/settings/settings.md | 38 ++++++++++++++++++- .../statements/select/prewhere.md | 10 +++-- docs/ru/operations/settings/settings.md | 38 ++++++++++++++++++- .../statements/select/prewhere.md | 12 +++--- 4 files changed, 87 insertions(+), 11 deletions(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index f78fbc8a2bc..0491674b701 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -3783,4 +3783,40 @@ Result: │ 20 │ 20 │ 10 │ │ 10 │ 20 │ 30 │ └─────┴─────┴───────┘ -``` \ No newline at end of file +``` + +## optimize_move_to_prewhere {#optimize_move_to_prewhere} + +Enables or disables automatic [PREWHERE](../../sql-reference/statements/select/prewhere.md) optimization in [SELECT](../../sql-reference/statements/select/index.md) queries. + +Works only for [*MergeTree](../../engines/table-engines/mergetree-family/index.md) tables. + +Possible values: + +- 0 — Automatic `PREWHERE` optimization is disabled. +- 1 — Automatic `PREWHERE` optimization is enabled. + +Default value: `1`. + +**See Also** + +- [PREWHERE](../../sql-reference/statements/select/prewhere.md) clause in `SELECT` queries + +## optimize_move_to_prewhere_if_final {#optimize_move_to_prewhere_if_final} + +Enables or disables automatic [PREWHERE](../../sql-reference/statements/select/prewhere.md) optimization in [SELECT](../../sql-reference/statements/select/index.md) queries with [FINAL](../../sql-reference/statements/select/from.md#select-from-final) modifier. + +Works only for [*MergeTree](../../engines/table-engines/mergetree-family/index.md) tables. + +Possible values: + +- 0 — Automatic `PREWHERE` optimization in `SELECT` queries with `FINAL` modifier is disabled. +- 1 — Automatic `PREWHERE` optimization in `SELECT` queries with `FINAL` modifier is enabled. + +Default value: `0`. + +**See Also** + +- [PREWHERE](../../sql-reference/statements/select/prewhere.md) clause in `SELECT` queries +- [FINAL](../../sql-reference/statements/select/from.md#select-from-final) modifier in `SELECT` queries +- [optimize_move_to_prewhere](#optimize_move_to_prewhere) setting \ No newline at end of file diff --git a/docs/en/sql-reference/statements/select/prewhere.md b/docs/en/sql-reference/statements/select/prewhere.md index ada8fff7012..646bb83e692 100644 --- a/docs/en/sql-reference/statements/select/prewhere.md +++ b/docs/en/sql-reference/statements/select/prewhere.md @@ -6,7 +6,7 @@ toc_title: PREWHERE Prewhere is an optimization to apply filtering more efficiently. It is enabled by default even if `PREWHERE` clause is not specified explicitly. It works by automatically moving part of [WHERE](../../../sql-reference/statements/select/where.md) condition to prewhere stage. The role of `PREWHERE` clause is only to control this optimization if you think that you know how to do it better than it happens by default. -With prewhere optimization, at first only the columns necessary for executing prewhere expression are read. Then the other columns are read that are needed for running the rest of the query, but only those blocks where the prewhere expression is “true” at least for some rows. If there are a lot of blocks where prewhere expression is “false” for all rows and prewhere needs less columns than other parts of query, this often allows to read a lot less data from disk for query execution. +With prewhere optimization, at first only the columns necessary for executing prewhere expression are read. Then the other columns are read that are needed for running the rest of the query, but only those blocks where the prewhere expression is `true` at least for some rows. If there are a lot of blocks where prewhere expression is `false` for all rows and prewhere needs less columns than other parts of query, this often allows to read a lot less data from disk for query execution. ## Controlling Prewhere Manually {#controlling-prewhere-manually} @@ -14,11 +14,13 @@ The clause has the same meaning as the `WHERE` clause. The difference is in whic A query may simultaneously specify `PREWHERE` and `WHERE`. In this case, `PREWHERE` precedes `WHERE`. -If the `optimize_move_to_prewhere` setting is set to 0, heuristics to automatically move parts of expressions from `WHERE` to `PREWHERE` are disabled. +If the [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) setting is set to 0, heuristics to automatically move parts of expressions from `WHERE` to `PREWHERE` are disabled. + +If query has [FINAL](from.md#select-from-final) modifier, the `PREWHERE` optimization is not always correct. It is enabled only if both settings [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) and [optimize_move_to_prewhere_if_final](../../../operations/settings/settings.md#optimize_move_to_prewhere_if_final) are turned on. !!! note "Attention" - The `PREWHERE` section is executed before` FINAL`, so the results of `FROM FINAL` queries may be skewed when using` PREWHERE` with fields not in the `ORDER BY` section of a table. + The `PREWHERE` section is executed before `FINAL`, so the results of `FROM ... FINAL` queries may be skewed when using `PREWHERE` with fields not in the `ORDER BY` section of a table. ## Limitations {#limitations} -`PREWHERE` is only supported by tables from the `*MergeTree` family. +`PREWHERE` is only supported by tables from the [*MergeTree](../../../engines/table-engines/mergetree-family/index.md) family. diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 500485aea2f..887c59c3b09 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -3572,4 +3572,40 @@ SELECT * FROM positional_arguments ORDER BY 2,3; │ 20 │ 20 │ 10 │ │ 10 │ 20 │ 30 │ └─────┴─────┴───────┘ -``` \ No newline at end of file +``` + +## optimize_move_to_prewhere {#optimize_move_to_prewhere} + +Включает или отключает автоматическую оптимизацию [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах [SELECT](../../sql-reference/statements/select/index.md). + +Работает только с таблицами семейства [*MergeTree](../../engines/table-engines/mergetree-family/index.md). + +Возможные значения: + +- 0 — автоматическая оптимизация `PREWHERE` отключена. +- 1 — автоматическая оптимизация `PREWHERE` включена. + +Значение по умолчанию: `1`. + +**См. также** + +- секция [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах `SELECT` + +## optimize_move_to_prewhere_if_final {#optimize_move_to_prewhere_if_final} + +Включает или отключает автоматическую оптимизацию [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах [SELECT](../../sql-reference/statements/select/index.md) с модификатором [FINAL](../../sql-reference/statements/select/from.md#select-from-final). + +Работает только с таблицами семейства [*MergeTree](../../engines/table-engines/mergetree-family/index.md). + +Возможные значения: + +- 0 — автоматическая оптимизация `PREWHERE` в запросах `SELECT` с модификатором `FINAL` отключена. +- 1 — автоматическая оптимизация `PREWHERE` в запросах `SELECT` с модификатором `FINAL` включена. + +Значение по умолчанию: `0`. + +**См. также** + +- секция [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах `SELECT` +- модификатор [FINAL](../../sql-reference/statements/select/from.md#select-from-final) в запросах `SELECT` +- настройка [optimize_move_to_prewhere](#optimize_move_to_prewhere) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/select/prewhere.md b/docs/ru/sql-reference/statements/select/prewhere.md index 5ba25e6fa6e..84f8869b41e 100644 --- a/docs/ru/sql-reference/statements/select/prewhere.md +++ b/docs/ru/sql-reference/statements/select/prewhere.md @@ -8,17 +8,19 @@ Prewhere — это оптимизация для более эффективн При оптимизации prewhere сначала читываются только те столбцы, которые необходимы для выполнения выражения prewhere. Затем читаются другие столбцы, необходимые для выполнения остальной части запроса, но только те блоки, в которых находится выражение prewhere «верно» по крайней мере для некоторых рядов. Если есть много блоков, где выражение prewhere «ложно» для всех строк и для выражения prewhere требуется меньше столбцов, чем для других частей запроса, это часто позволяет считывать гораздо меньше данных с диска для выполнения запроса. -## Управление prewhere вручную {#controlling-prewhere-manually} +## Управление PREWHERE вручную {#controlling-prewhere-manually} `PREWHERE` имеет смысл использовать, если есть условия фильтрации, которые использует меньшинство столбцов из тех, что есть в запросе, но достаточно сильно фильтрует данные. Таким образом, сокращается количество читаемых данных. -В запрос может быть одновременно указано и `PREWHERE` и `WHERE`. В этом случае, `PREWHERE` предшествует `WHERE`. +В запросе может быть одновременно указаны и `PREWHERE`, и `WHERE`. В этом случае `PREWHERE` предшествует `WHERE`. -Если значение параметра `optimize_move_to_prewhere` равно 0, эвристика по автоматическому перемещнию части выражений из `WHERE` к `PREWHERE` отключается. +Если значение параметра [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) равно 0, эвристика по автоматическому перемещнию части выражений из `WHERE` к `PREWHERE` отключается. + +Если в запросе есть модификатор [FINAL](from.md#select-from-final), оптимизация `PREWHERE` не всегда корректна. Она действует только если включены обе настройки [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) и [optimize_move_to_prewhere_if_final](../../../operations/settings/settings.md#optimize_move_to_prewhere_if_final). !!! note "Внимание" - Секция `PREWHERE` выполняется до `FINAL`, поэтому результаты запросов `FROM FINAL` могут исказится при использовании `PREWHERE` с полями не входящями в `ORDER BY` таблицы. + Секция `PREWHERE` выполняется до `FINAL`, поэтому результаты запросов `FROM ... FINAL` могут исказиться при использовании `PREWHERE` с полями, не входящями в `ORDER BY` таблицы. ## Ограничения {#limitations} -`PREWHERE` поддерживается только табличными движками из семейства `*MergeTree`. +`PREWHERE` поддерживается только табличными движками из семейства [*MergeTree](../../../engines/table-engines/mergetree-family/index.md). From fa3c13cf81a314158c2fa292f09749b1f6c9dec5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 04:37:04 +0300 Subject: [PATCH 149/264] Experiment with minimized toolchain --- .gitmodules | 3 +++ cmake/linux/toolchain-aarch64.cmake | 18 +++++++++++------- contrib/sysroot | 1 + 3 files changed, 15 insertions(+), 7 deletions(-) create mode 160000 contrib/sysroot diff --git a/.gitmodules b/.gitmodules index 74d1049ce01..696676200fe 100644 --- a/.gitmodules +++ b/.gitmodules @@ -249,3 +249,6 @@ [submodule "contrib/magic_enum"] path = contrib/magic_enum url = https://github.com/Neargye/magic_enum +[submodule "contrib/sysroot"] + path = contrib/sysroot + url = https://github.com/ClickHouse-Extras/sysroot.git diff --git a/cmake/linux/toolchain-aarch64.cmake b/cmake/linux/toolchain-aarch64.cmake index b4dc6e45cbb..94e81d13c2e 100644 --- a/cmake/linux/toolchain-aarch64.cmake +++ b/cmake/linux/toolchain-aarch64.cmake @@ -1,17 +1,21 @@ +set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + set (CMAKE_SYSTEM_NAME "Linux") set (CMAKE_SYSTEM_PROCESSOR "aarch64") set (CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") set (CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") set (CMAKE_ASM_COMPILER_TARGET "aarch64-linux-gnu") -set (CMAKE_SYSROOT "${CMAKE_CURRENT_LIST_DIR}/../toolchain/linux-aarch64/aarch64-linux-gnu/libc") -# We don't use compiler from toolchain because it's gcc-8, and we provide support only for gcc-9. -set (CMAKE_AR "${CMAKE_CURRENT_LIST_DIR}/../toolchain/linux-aarch64/bin/aarch64-linux-gnu-ar" CACHE FILEPATH "" FORCE) -set (CMAKE_RANLIB "${CMAKE_CURRENT_LIST_DIR}/../toolchain/linux-aarch64/bin/aarch64-linux-gnu-ranlib" CACHE FILEPATH "" FORCE) +set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-aarch64") -set (CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS} --gcc-toolchain=${CMAKE_CURRENT_LIST_DIR}/../toolchain/linux-aarch64") -set (CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS} --gcc-toolchain=${CMAKE_CURRENT_LIST_DIR}/../toolchain/linux-aarch64") -set (CMAKE_ASM_FLAGS_INIT "${CMAKE_ASM_FLAGS} --gcc-toolchain=${CMAKE_CURRENT_LIST_DIR}/../toolchain/linux-aarch64") +set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/aarch64-linux-gnu/libc") + +set (CMAKE_AR "llvm-ar" CACHE FILEPATH "" FORCE) +set (CMAKE_RANLIB "llvm-ranlib" CACHE FILEPATH "" FORCE) + +set (CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") +set (CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") +set (CMAKE_ASM_FLAGS_INIT "${CMAKE_ASM_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") set (LINKER_NAME "ld.lld" CACHE STRING "" FORCE) diff --git a/contrib/sysroot b/contrib/sysroot new file mode 160000 index 00000000000..ae9209a6433 --- /dev/null +++ b/contrib/sysroot @@ -0,0 +1 @@ +Subproject commit ae9209a643374c830a509ca75fd41d89ae189213 From aabe52e3e95b6ad99ca28de4081e2820c249bb5a Mon Sep 17 00:00:00 2001 From: hexiaoting Date: Mon, 11 Oct 2021 10:39:55 +0800 Subject: [PATCH 150/264] Fix bug for quantile fusion --- src/Interpreters/GatherFunctionQuantileVisitor.cpp | 2 +- .../0_stateless/01956_fuse_quantile_optimization.reference | 1 + tests/queries/0_stateless/01956_fuse_quantile_optimization.sql | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Interpreters/GatherFunctionQuantileVisitor.cpp b/src/Interpreters/GatherFunctionQuantileVisitor.cpp index ec3866ba0c0..3eb474c271c 100644 --- a/src/Interpreters/GatherFunctionQuantileVisitor.cpp +++ b/src/Interpreters/GatherFunctionQuantileVisitor.cpp @@ -47,7 +47,7 @@ void GatherFunctionQuantileData::visit(ASTFunction & function, ASTPtr & ast) void GatherFunctionQuantileData::FuseQuantileAggregatesData::addFuncNode(ASTPtr & ast) { const auto * func = ast->as(); - if (!func) + if (!func || func->parameters == nullptr) return; const auto & arguments = func->arguments->children; diff --git a/tests/queries/0_stateless/01956_fuse_quantile_optimization.reference b/tests/queries/0_stateless/01956_fuse_quantile_optimization.reference index defad422cad..d4cb1477ed6 100644 --- a/tests/queries/0_stateless/01956_fuse_quantile_optimization.reference +++ b/tests/queries/0_stateless/01956_fuse_quantile_optimization.reference @@ -95,3 +95,4 @@ FROM FROM numbers(10) ) GROUP BY b +1 1 1 diff --git a/tests/queries/0_stateless/01956_fuse_quantile_optimization.sql b/tests/queries/0_stateless/01956_fuse_quantile_optimization.sql index 2a97c60882c..a4729e89755 100644 --- a/tests/queries/0_stateless/01956_fuse_quantile_optimization.sql +++ b/tests/queries/0_stateless/01956_fuse_quantile_optimization.sql @@ -71,3 +71,6 @@ SELECT quantileTimingWeighted([[[[['-214748364.8'], NULL]], [[[quantileTimingWei SELECT quantileTimingWeighted([quantileTimingWeighted(0.5)(1, 1)])(1, 1); -- { serverError ILLEGAL_AGGREGATION } DROP TABLE datetime; + +SET optimize_syntax_fuse_functions = 1; +SELECT quantile(1 AS a), quantile(a AS b), quantile(b AS c); From 7597763d6d260a36f082026fc0ba50b1d2c26f2e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 06:55:00 +0300 Subject: [PATCH 151/264] Improve search for ar and ranlib --- cmake/linux/toolchain-aarch64.cmake | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmake/linux/toolchain-aarch64.cmake b/cmake/linux/toolchain-aarch64.cmake index 94e81d13c2e..d414c2da823 100644 --- a/cmake/linux/toolchain-aarch64.cmake +++ b/cmake/linux/toolchain-aarch64.cmake @@ -10,8 +10,11 @@ set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-aarch set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/aarch64-linux-gnu/libc") -set (CMAKE_AR "llvm-ar" CACHE FILEPATH "" FORCE) -set (CMAKE_RANLIB "llvm-ranlib" CACHE FILEPATH "" FORCE) +find_program (LLVM_AR_PATH NAMES "llvm-ar" "llvm-ar-13" "llvm-ar-12" "llvm-ar-11" "llvm-ar-10" "llvm-ar-9" "llvm-ar-8") +find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9" + +set (CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "" FORCE) +set (CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "" FORCE) set (CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") set (CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") From 8196f89481ba14b08d02debca3daf5eec6c56514 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 06:58:08 +0300 Subject: [PATCH 152/264] Remove trash from CMake --- base/glibc-compatibility/memcpy/memcpy.h | 2 +- cmake/linux/toolchain-x86_64.cmake | 29 ++++ cmake/tools.cmake | 1 - contrib/CMakeLists.txt | 3 +- contrib/arrow-cmake/CMakeLists.txt | 11 +- contrib/arrow-cmake/orc_check.cmake | 138 ++---------------- .../grpc-cmake/protobuf_generate_grpc.cmake | 4 +- contrib/krb5-cmake/CMakeLists.txt | 2 +- .../CMake/CMakeTestCompileNestedException.cpp | 10 -- .../CMake/CMakeTestCompileSteadyClock.cpp | 7 - ...trerror.cpp => CMakeTestCompileStrerror.c} | 0 contrib/libhdfs3-cmake/CMake/Options.cmake | 25 +--- .../protobuf-cmake/protobuf_generate.cmake | 4 +- contrib/rocksdb-cmake/CMakeLists.txt | 34 +---- contrib/snappy-cmake/CMakeLists.txt | 42 ++++++ 15 files changed, 111 insertions(+), 201 deletions(-) create mode 100644 cmake/linux/toolchain-x86_64.cmake delete mode 100644 contrib/libhdfs3-cmake/CMake/CMakeTestCompileNestedException.cpp delete mode 100644 contrib/libhdfs3-cmake/CMake/CMakeTestCompileSteadyClock.cpp rename contrib/libhdfs3-cmake/CMake/{CMakeTestCompileStrerror.cpp => CMakeTestCompileStrerror.c} (100%) create mode 100644 contrib/snappy-cmake/CMakeLists.txt diff --git a/base/glibc-compatibility/memcpy/memcpy.h b/base/glibc-compatibility/memcpy/memcpy.h index 211d144cecb..9bee26a3722 100644 --- a/base/glibc-compatibility/memcpy/memcpy.h +++ b/base/glibc-compatibility/memcpy/memcpy.h @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/cmake/linux/toolchain-x86_64.cmake b/cmake/linux/toolchain-x86_64.cmake new file mode 100644 index 00000000000..6773bdbd64d --- /dev/null +++ b/cmake/linux/toolchain-x86_64.cmake @@ -0,0 +1,29 @@ +set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set (CMAKE_SYSTEM_NAME "Linux") +set (CMAKE_SYSTEM_PROCESSOR "x86_64") +set (CMAKE_C_COMPILER_TARGET "x86_64-linux-gnu") +set (CMAKE_CXX_COMPILER_TARGET "x86_64-linux-gnu") +set (CMAKE_ASM_COMPILER_TARGET "x86_64-linux-gnu") + +set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-x86_64") + +set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/x86_64-linux-gnu/libc") + +set (CMAKE_AR "llvm-ar" CACHE FILEPATH "" FORCE) +set (CMAKE_RANLIB "llvm-ranlib" CACHE FILEPATH "" FORCE) + +set (CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") +set (CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") +set (CMAKE_ASM_FLAGS_INIT "${CMAKE_ASM_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") + +set (LINKER_NAME "ld.lld" CACHE STRING "" FORCE) + +set (CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld") +set (CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld") + +set (HAS_PRE_1970_EXITCODE "0" CACHE STRING "Result from TRY_RUN" FORCE) +set (HAS_PRE_1970_EXITCODE__TRYRUN_OUTPUT "" CACHE STRING "Output from TRY_RUN" FORCE) + +set (HAS_POST_2038_EXITCODE "0" CACHE STRING "Result from TRY_RUN" FORCE) +set (HAS_POST_2038_EXITCODE__TRYRUN_OUTPUT "" CACHE STRING "Output from TRY_RUN" FORCE) diff --git a/cmake/tools.cmake b/cmake/tools.cmake index f94f4b289a3..4b2db0dedab 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -89,4 +89,3 @@ if (LINKER_NAME) message(STATUS "Using custom linker by name: ${LINKER_NAME}") endif () - diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 140cc0846ec..4d817c4c6e2 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -163,7 +163,7 @@ endif () if(USE_INTERNAL_SNAPPY_LIBRARY) set(SNAPPY_BUILD_TESTS 0 CACHE INTERNAL "") - add_subdirectory(snappy) + add_subdirectory(snappy-cmake) set (SNAPPY_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/snappy") endif() @@ -215,6 +215,7 @@ function(add_llvm) # Do not adjust RPATH in llvm, since then it will not be able to find libcxx/libcxxabi/libunwind set (CMAKE_INSTALL_RPATH "ON") + set (LLVM_COMPILER_CHECKED 1 CACHE INTERNAL "") set (LLVM_ENABLE_EH 1 CACHE INTERNAL "") set (LLVM_ENABLE_RTTI 1 CACHE INTERNAL "") set (LLVM_ENABLE_PIC 0 CACHE INTERNAL "") diff --git a/contrib/arrow-cmake/CMakeLists.txt b/contrib/arrow-cmake/CMakeLists.txt index 427379dc9b2..841c280d192 100644 --- a/contrib/arrow-cmake/CMakeLists.txt +++ b/contrib/arrow-cmake/CMakeLists.txt @@ -54,7 +54,7 @@ target_link_libraries (${THRIFT_LIBRARY} PRIVATE boost::headers_only) set(ORC_SOURCE_DIR "${ClickHouse_SOURCE_DIR}/contrib/orc/c++") set(ORC_INCLUDE_DIR "${ORC_SOURCE_DIR}/include") set(ORC_SOURCE_SRC_DIR "${ORC_SOURCE_DIR}/src") -set(ORC_SOURCE_WRAP_DIR "${ORC_SOURCE_DIR}/wrap") +# set(ORC_SOURCE_WRAP_DIR "${ORC_SOURCE_DIR}/wrap") set(ORC_BUILD_SRC_DIR "${CMAKE_CURRENT_BINARY_DIR}/../orc/c++/src") set(ORC_BUILD_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/../orc/c++/include") @@ -101,7 +101,14 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") set(CXX11_FLAGS "-std=c++0x") endif () -include("${ClickHouse_SOURCE_DIR}/contrib/orc/cmake_modules/CheckSourceCompiles.cmake") +set (ORC_CXX_HAS_INITIALIZER_LIST 1) +set (ORC_CXX_HAS_NOEXCEPT 1) +set (ORC_CXX_HAS_NULLPTR 1) +set (ORC_CXX_HAS_OVERRIDE 1) +set (ORC_CXX_HAS_UNIQUE_PTR 1) +set (ORC_CXX_HAS_CSTDINT 1) +set (ORC_CXX_HAS_THREAD_LOCAL 1) + include(orc_check.cmake) configure_file("${ORC_INCLUDE_DIR}/orc/orc-config.hh.in" "${ORC_BUILD_INCLUDE_DIR}/orc/orc-config.hh") configure_file("${ORC_SOURCE_SRC_DIR}/Adaptor.hh.in" "${ORC_BUILD_INCLUDE_DIR}/Adaptor.hh") diff --git a/contrib/arrow-cmake/orc_check.cmake b/contrib/arrow-cmake/orc_check.cmake index ad3b72e44cf..523e1cf1d86 100644 --- a/contrib/arrow-cmake/orc_check.cmake +++ b/contrib/arrow-cmake/orc_check.cmake @@ -1,130 +1,14 @@ -# Not changed part of contrib/orc/c++/src/CMakeLists.txt +set (HAS_PREAD 1) +set (HAS_STRPTIME 1) +set (HAS_STOLL 1) +set (INT64_IS_LL 1) +set (HAS_DIAGNOSTIC_PUSH 1) +set (HAS_STD_ISNAN 1) +set (HAS_STD_MUTEX 1) +set (NEEDS_REDUNDANT_MOVE 1) +set (HAS_PRE_1970 1) +set (HAS_POST_2038 1) +set (NEEDS_Z_PREFIX 0) -INCLUDE(CheckCXXSourceCompiles) - -CHECK_CXX_SOURCE_COMPILES(" - #include - #include - int main(int,char*[]){ - int f = open(\"/x/y\", O_RDONLY); - char buf[100]; - return pread(f, buf, 100, 1000) == 0; - }" - HAS_PREAD -) - -CHECK_CXX_SOURCE_COMPILES(" - #include - int main(int,char*[]){ - struct tm time2020; - return !strptime(\"2020-02-02 12:34:56\", \"%Y-%m-%d %H:%M:%S\", &time2020); - }" - HAS_STRPTIME -) - -CHECK_CXX_SOURCE_COMPILES(" - #include - int main(int,char* argv[]){ - return static_cast(std::stoll(argv[0])); - }" - HAS_STOLL -) - -CHECK_CXX_SOURCE_COMPILES(" - #include - #include - int main(int,char*[]){ - int64_t x = 1; printf(\"%lld\",x); - }" - INT64_IS_LL -) - -CHECK_CXX_SOURCE_COMPILES(" - #ifdef __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored \"-Wdeprecated\" - #pragma clang diagnostic pop - #elif defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored \"-Wdeprecated\" - #pragma GCC diagnostic pop - #elif defined(_MSC_VER) - #pragma warning( push ) - #pragma warning( disable : 4996 ) - #pragma warning( pop ) - #else - unknownCompiler! - #endif - int main(int, char *[]) {}" - HAS_DIAGNOSTIC_PUSH -) - -CHECK_CXX_SOURCE_COMPILES(" - #include - int main(int, char *[]) { - return std::isnan(1.0f); - }" - HAS_STD_ISNAN -) - -CHECK_CXX_SOURCE_COMPILES(" - #include - int main(int, char *[]) { - std::mutex test_mutex; - std::lock_guard lock_mutex(test_mutex); - }" - HAS_STD_MUTEX -) - -CHECK_CXX_SOURCE_COMPILES(" - #include - std::string func() { - std::string var = \"test\"; - return std::move(var); - } - int main(int, char *[]) {}" - NEEDS_REDUNDANT_MOVE -) - -INCLUDE(CheckCXXSourceRuns) - -CHECK_CXX_SOURCE_RUNS(" - #include - int main(int, char *[]) { - time_t t = -14210715; // 1969-07-20 12:34:45 - struct tm *ptm = gmtime(&t); - return !(ptm && ptm->tm_year == 69); - }" - HAS_PRE_1970 -) - -CHECK_CXX_SOURCE_RUNS(" - #include - #include - int main(int, char *[]) { - setenv(\"TZ\", \"America/Los_Angeles\", 1); - tzset(); - struct tm time2037; - struct tm time2038; - strptime(\"2037-05-05 12:34:56\", \"%Y-%m-%d %H:%M:%S\", &time2037); - strptime(\"2038-05-05 12:34:56\", \"%Y-%m-%d %H:%M:%S\", &time2038); - return mktime(&time2038) - mktime(&time2037) != 31536000; - }" - HAS_POST_2038 -) - -set(CMAKE_REQUIRED_INCLUDES ${ZLIB_INCLUDE_DIR}) -set(CMAKE_REQUIRED_LIBRARIES zlib) -CHECK_CXX_SOURCE_COMPILES(" - #define Z_PREFIX - #include - z_stream strm; - int main(int, char *[]) { - deflateReset(&strm); - }" - NEEDS_Z_PREFIX -) - -# See https://cmake.org/cmake/help/v3.14/policy/CMP0075.html. Without unsetting it breaks thrift. set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) diff --git a/contrib/grpc-cmake/protobuf_generate_grpc.cmake b/contrib/grpc-cmake/protobuf_generate_grpc.cmake index 08d2976c26a..726428a7597 100644 --- a/contrib/grpc-cmake/protobuf_generate_grpc.cmake +++ b/contrib/grpc-cmake/protobuf_generate_grpc.cmake @@ -187,7 +187,7 @@ function(protobuf_generate_grpc) add_custom_command( OUTPUT ${_generated_srcs} - COMMAND protobuf::protoc + COMMAND $ ARGS --${protobuf_generate_grpc_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_grpc_PROTOC_OUT_DIR} --grpc_out ${_dll_export_decl}${protobuf_generate_grpc_PROTOC_OUT_DIR} --plugin=protoc-gen-grpc=$ @@ -204,4 +204,4 @@ function(protobuf_generate_grpc) if(protobuf_generate_grpc_TARGET) target_sources(${protobuf_generate_grpc_TARGET} PRIVATE ${_generated_srcs_all}) endif() -endfunction() \ No newline at end of file +endfunction() diff --git a/contrib/krb5-cmake/CMakeLists.txt b/contrib/krb5-cmake/CMakeLists.txt index 7c750ca12b6..d6c3c23b14e 100644 --- a/contrib/krb5-cmake/CMakeLists.txt +++ b/contrib/krb5-cmake/CMakeLists.txt @@ -1,6 +1,6 @@ find_program(AWK_PROGRAM awk) if(NOT AWK_PROGRAM) - message(FATAL_ERROR "You need the awk program to build ClickHouse with krb5 enabled.") + message(FATAL_ERROR "You need the awk program to build ClickHouse with krb5 enabled.") endif() set(KRB5_SOURCE_DIR "${ClickHouse_SOURCE_DIR}/contrib/krb5/src") diff --git a/contrib/libhdfs3-cmake/CMake/CMakeTestCompileNestedException.cpp b/contrib/libhdfs3-cmake/CMake/CMakeTestCompileNestedException.cpp deleted file mode 100644 index 66918ca516e..00000000000 --- a/contrib/libhdfs3-cmake/CMake/CMakeTestCompileNestedException.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - -int main() { - try { - throw 2; - } catch (int) { - std::throw_with_nested(std::runtime_error("test")); - } -} diff --git a/contrib/libhdfs3-cmake/CMake/CMakeTestCompileSteadyClock.cpp b/contrib/libhdfs3-cmake/CMake/CMakeTestCompileSteadyClock.cpp deleted file mode 100644 index afcbe1b83b2..00000000000 --- a/contrib/libhdfs3-cmake/CMake/CMakeTestCompileSteadyClock.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -using std::chrono::steady_clock; - -void foo(const steady_clock &clock) { - return; -} diff --git a/contrib/libhdfs3-cmake/CMake/CMakeTestCompileStrerror.cpp b/contrib/libhdfs3-cmake/CMake/CMakeTestCompileStrerror.c similarity index 100% rename from contrib/libhdfs3-cmake/CMake/CMakeTestCompileStrerror.cpp rename to contrib/libhdfs3-cmake/CMake/CMakeTestCompileStrerror.c diff --git a/contrib/libhdfs3-cmake/CMake/Options.cmake b/contrib/libhdfs3-cmake/CMake/Options.cmake index 04ab823eedc..402aceac2fa 100644 --- a/contrib/libhdfs3-cmake/CMake/Options.cmake +++ b/contrib/libhdfs3-cmake/CMake/Options.cmake @@ -1,4 +1,4 @@ -OPTION(ENABLE_SSE "enable SSE4.2 buildin function" ON) +OPTION(ENABLE_SSE "enable SSE4.2 builtin function" ON) INCLUDE (CheckFunctionExists) CHECK_FUNCTION_EXISTS(dladdr HAVE_DLADDR) @@ -21,30 +21,21 @@ ADD_DEFINITIONS(-D_GNU_SOURCE) ADD_DEFINITIONS(-D_GLIBCXX_USE_NANOSLEEP) TRY_COMPILE(STRERROR_R_RETURN_INT - ${CMAKE_CURRENT_BINARY_DIR} - "${HDFS3_ROOT_DIR}/CMake/CMakeTestCompileStrerror.cpp" + ${CMAKE_CURRENT_BINARY_DIR} + "${CMAKE_CURRENT_SOURCE_DIR}/CMake/CMakeTestCompileStrerror.c" CMAKE_FLAGS "-DCMAKE_CXX_LINK_EXECUTABLE='echo not linking now...'" - OUTPUT_VARIABLE OUTPUT) + OUTPUT_VARIABLE OUTPUT) MESSAGE(STATUS "Checking whether strerror_r returns an int") IF(STRERROR_R_RETURN_INT) - MESSAGE(STATUS "Checking whether strerror_r returns an int -- yes") + MESSAGE(STATUS "Checking whether strerror_r returns an int -- yes") ELSE(STRERROR_R_RETURN_INT) - MESSAGE(STATUS "Checking whether strerror_r returns an int -- no") + MESSAGE(STATUS "Checking whether strerror_r returns an int -- no") ENDIF(STRERROR_R_RETURN_INT) -TRY_COMPILE(HAVE_STEADY_CLOCK - ${CMAKE_CURRENT_BINARY_DIR} - "${HDFS3_ROOT_DIR}/CMake/CMakeTestCompileSteadyClock.cpp" - CMAKE_FLAGS "-DCMAKE_CXX_LINK_EXECUTABLE='echo not linking now...'" - OUTPUT_VARIABLE OUTPUT) - -TRY_COMPILE(HAVE_NESTED_EXCEPTION - ${CMAKE_CURRENT_BINARY_DIR} - "${HDFS3_ROOT_DIR}/CMake/CMakeTestCompileNestedException.cpp" - CMAKE_FLAGS "-DCMAKE_CXX_LINK_EXECUTABLE='echo not linking now...'" - OUTPUT_VARIABLE OUTPUT) +set(HAVE_STEADY_CLOCK 1) +set(HAVE_NESTED_EXCEPTION 1) SET(HAVE_BOOST_CHRONO 0) SET(HAVE_BOOST_ATOMIC 0) diff --git a/contrib/protobuf-cmake/protobuf_generate.cmake b/contrib/protobuf-cmake/protobuf_generate.cmake index fc1dfd9cc11..c444162dd1e 100644 --- a/contrib/protobuf-cmake/protobuf_generate.cmake +++ b/contrib/protobuf-cmake/protobuf_generate.cmake @@ -181,11 +181,11 @@ function(protobuf_generate) add_custom_command( OUTPUT ${_generated_srcs} - COMMAND protobuf::protoc + COMMAND $ ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file} DEPENDS ${_abs_file} protobuf::protoc COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" - VERBATIM ) + VERBATIM) endforeach() set_source_files_properties(${_generated_srcs_all} PROPERTIES GENERATED TRUE) diff --git a/contrib/rocksdb-cmake/CMakeLists.txt b/contrib/rocksdb-cmake/CMakeLists.txt index e7ff1f548e3..6ccbd12516e 100644 --- a/contrib/rocksdb-cmake/CMakeLists.txt +++ b/contrib/rocksdb-cmake/CMakeLists.txt @@ -106,18 +106,6 @@ if(NOT MSVC) set(CMAKE_REQUIRED_FLAGS "-msse4.2 -mpclmul") endif() -CHECK_CXX_SOURCE_COMPILES(" -#include -#include -#include -int main() { - volatile uint32_t x = _mm_crc32_u32(0, 0); - const auto a = _mm_set_epi64x(0, 0); - const auto b = _mm_set_epi64x(0, 0); - const auto c = _mm_clmulepi64_si128(a, b, 0x00); - auto d = _mm_cvtsi128_si64(c); -} -" HAVE_SSE42) unset(CMAKE_REQUIRED_FLAGS) if(HAVE_SSE42) add_definitions(-DHAVE_SSE42) @@ -126,14 +114,7 @@ elseif(FORCE_SSE42) message(FATAL_ERROR "FORCE_SSE42=ON but unable to compile with SSE4.2 enabled") endif() -CHECK_CXX_SOURCE_COMPILES(" -#if defined(_MSC_VER) && !defined(__thread) -#define __thread __declspec(thread) -#endif -int main() { - static __thread int tls; -} -" HAVE_THREAD_LOCAL) +set (HAVE_THREAD_LOCAL 1) if(HAVE_THREAD_LOCAL) add_definitions(-DROCKSDB_SUPPORT_THREAD_LOCAL) endif() @@ -174,20 +155,13 @@ endif() option(WITH_FALLOCATE "build with fallocate" ON) if(WITH_FALLOCATE) - CHECK_CXX_SOURCE_COMPILES(" -#include -#include -int main() { - int fd = open(\"/dev/null\", 0); - fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1024); -} -" HAVE_FALLOCATE) + set (HAVE_FALLOCATE 1) if(HAVE_FALLOCATE) add_definitions(-DROCKSDB_FALLOCATE_PRESENT) endif() endif() -CHECK_CXX_SOURCE_COMPILES(" +CHECK_C_SOURCE_COMPILES(" #include int main() { int fd = open(\"/dev/null\", 0); @@ -198,7 +172,7 @@ if(HAVE_SYNC_FILE_RANGE_WRITE) add_definitions(-DROCKSDB_RANGESYNC_PRESENT) endif() -CHECK_CXX_SOURCE_COMPILES(" +CHECK_C_SOURCE_COMPILES(" #include int main() { (void) PTHREAD_MUTEX_ADAPTIVE_NP; diff --git a/contrib/snappy-cmake/CMakeLists.txt b/contrib/snappy-cmake/CMakeLists.txt new file mode 100644 index 00000000000..3f12d875d6b --- /dev/null +++ b/contrib/snappy-cmake/CMakeLists.txt @@ -0,0 +1,42 @@ +set (SOURCE_DIR "${CMAKE_SOURCE_DIR}/contrib/snappy") + +set(SNAPPY_IS_BIG_ENDIAN 0) + +include(CheckIncludeFile) +check_include_file("byteswap.h" HAVE_BYTESWAP_H) +check_include_file("sys/endian.h" HAVE_SYS_ENDIAN_H) +check_include_file("sys/mman.h" HAVE_SYS_MMAN_H) +check_include_file("sys/resource.h" HAVE_SYS_RESOURCE_H) +check_include_file("sys/time.h" HAVE_SYS_TIME_H) +check_include_file("sys/uio.h" HAVE_SYS_UIO_H) +check_include_file("unistd.h" HAVE_UNISTD_H) +check_include_file("windows.h" HAVE_WINDOWS_H) + +set (HAVE_BUILTIN_EXPECT 1) +set (HAVE_BUILTIN_CTZ 1) +set (SNAPPY_HAVE_SSSE3 HAVE_SSSE3) +set (HAVE_FUNC_MMAP 1) +set (HAVE_FUNC_SYSCONF 1) + +configure_file( + "${SOURCE_DIR}/cmake/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h") + +set(HAVE_SYS_UIO_H_01 1) + +configure_file( + "${SOURCE_DIR}/snappy-stubs-public.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/snappy-stubs-public.h") + +add_library(snappy "") +target_sources(snappy + PRIVATE + "${SOURCE_DIR}/snappy-internal.h" + "${SOURCE_DIR}/snappy-stubs-internal.h" + "${SOURCE_DIR}/snappy-c.cc" + "${SOURCE_DIR}/snappy-sinksource.cc" + "${SOURCE_DIR}/snappy-stubs-internal.cc" + "${SOURCE_DIR}/snappy.cc") + +target_include_directories(snappy PUBLIC ${SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) +target_compile_definitions(snappy PRIVATE -DHAVE_CONFIG_H) From 0dbe7c4036a03401b8ec89cfafc393bf9e6129ee Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:02:19 +0300 Subject: [PATCH 153/264] Remove old toolchain --- cmake/toolchain/linux-aarch64/README.txt | 2 -- docker/packager/binary/Dockerfile | 4 ---- docker/packager/binary/build.sh | 3 --- 3 files changed, 9 deletions(-) delete mode 100644 cmake/toolchain/linux-aarch64/README.txt diff --git a/cmake/toolchain/linux-aarch64/README.txt b/cmake/toolchain/linux-aarch64/README.txt deleted file mode 100644 index 3183d30b70d..00000000000 --- a/cmake/toolchain/linux-aarch64/README.txt +++ /dev/null @@ -1,2 +0,0 @@ -wget 'https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz?revision=2e88a73f-d233-4f96-b1f4-d8b36e9bb0b9&la=en' -O gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz -tar xJf gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz --strip-components=1 diff --git a/docker/packager/binary/Dockerfile b/docker/packager/binary/Dockerfile index 23012a38f9d..51d29b822e8 100644 --- a/docker/packager/binary/Dockerfile +++ b/docker/packager/binary/Dockerfile @@ -93,10 +93,6 @@ RUN git clone https://github.com/tpoechtrager/cctools-port.git \ # Download toolchain and SDK for Darwin RUN wget -nv https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.0.sdk.tar.xz -# Download toolchain for ARM -# It contains all required headers and libraries. Note that it's named as "gcc" but actually we are using clang for cross compiling. -RUN wget -nv "https://developer.arm.com/-/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz?revision=2e88a73f-d233-4f96-b1f4-d8b36e9bb0b9&la=en" -O gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz - # Download toolchain for FreeBSD 11.3 RUN wget -nv https://clickhouse-datasets.s3.yandex.net/toolchains/toolchains/freebsd-11.3-toolchain.tar.xz diff --git a/docker/packager/binary/build.sh b/docker/packager/binary/build.sh index 71402a2fd66..f78af924b66 100755 --- a/docker/packager/binary/build.sh +++ b/docker/packager/binary/build.sh @@ -6,9 +6,6 @@ mkdir -p build/cmake/toolchain/darwin-x86_64 tar xJf MacOSX11.0.sdk.tar.xz -C build/cmake/toolchain/darwin-x86_64 --strip-components=1 ln -sf darwin-x86_64 build/cmake/toolchain/darwin-aarch64 -mkdir -p build/cmake/toolchain/linux-aarch64 -tar xJf gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz -C build/cmake/toolchain/linux-aarch64 --strip-components=1 - mkdir -p build/cmake/toolchain/freebsd-x86_64 tar xJf freebsd-11.3-toolchain.tar.xz -C build/cmake/toolchain/freebsd-x86_64 --strip-components=1 From 778793267b65500819156850768d970ef643a98f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:02:48 +0300 Subject: [PATCH 154/264] Add toolchain for linux-x86_64 --- cmake/linux/toolchain-x86_64.cmake | 7 +++++-- contrib/sysroot | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cmake/linux/toolchain-x86_64.cmake b/cmake/linux/toolchain-x86_64.cmake index 6773bdbd64d..5b23a4f6ebd 100644 --- a/cmake/linux/toolchain-x86_64.cmake +++ b/cmake/linux/toolchain-x86_64.cmake @@ -10,8 +10,11 @@ set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-x86_6 set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/x86_64-linux-gnu/libc") -set (CMAKE_AR "llvm-ar" CACHE FILEPATH "" FORCE) -set (CMAKE_RANLIB "llvm-ranlib" CACHE FILEPATH "" FORCE) +find_program (LLVM_AR_PATH NAMES "llvm-ar" "llvm-ar-13" "llvm-ar-12" "llvm-ar-11" "llvm-ar-10" "llvm-ar-9" "llvm-ar-8") +find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9" + +set (CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "" FORCE) +set (CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "" FORCE) set (CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") set (CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") diff --git a/contrib/sysroot b/contrib/sysroot index ae9209a6433..68bdc5b31a9 160000 --- a/contrib/sysroot +++ b/contrib/sysroot @@ -1 +1 @@ -Subproject commit ae9209a643374c830a509ca75fd41d89ae189213 +Subproject commit 68bdc5b31a99a5291660bb9f6257071b75baf367 From 1df4792a453b9adb680984611b4a74cd97af35a6 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:07:58 +0300 Subject: [PATCH 155/264] Fix error --- cmake/linux/toolchain-aarch64.cmake | 2 +- cmake/linux/toolchain-x86_64.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/linux/toolchain-aarch64.cmake b/cmake/linux/toolchain-aarch64.cmake index d414c2da823..fa814d8d59b 100644 --- a/cmake/linux/toolchain-aarch64.cmake +++ b/cmake/linux/toolchain-aarch64.cmake @@ -11,7 +11,7 @@ set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-aarch set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/aarch64-linux-gnu/libc") find_program (LLVM_AR_PATH NAMES "llvm-ar" "llvm-ar-13" "llvm-ar-12" "llvm-ar-11" "llvm-ar-10" "llvm-ar-9" "llvm-ar-8") -find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9" +find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9") set (CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "" FORCE) set (CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "" FORCE) diff --git a/cmake/linux/toolchain-x86_64.cmake b/cmake/linux/toolchain-x86_64.cmake index 5b23a4f6ebd..1e139cec062 100644 --- a/cmake/linux/toolchain-x86_64.cmake +++ b/cmake/linux/toolchain-x86_64.cmake @@ -11,7 +11,7 @@ set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-x86_6 set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/x86_64-linux-gnu/libc") find_program (LLVM_AR_PATH NAMES "llvm-ar" "llvm-ar-13" "llvm-ar-12" "llvm-ar-11" "llvm-ar-10" "llvm-ar-9" "llvm-ar-8") -find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9" +find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9") set (CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "" FORCE) set (CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "" FORCE) From 1338f3daf8671248f85c44d6d96e097d674ed411 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:44:12 +0300 Subject: [PATCH 156/264] Add missing files to libc-headers. --- contrib/libc-headers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libc-headers b/contrib/libc-headers index a720b7105a6..aa5429bf67a 160000 --- a/contrib/libc-headers +++ b/contrib/libc-headers @@ -1 +1 @@ -Subproject commit a720b7105a610acbd7427eea475a5b6810c151eb +Subproject commit aa5429bf67a346e48ad60efd88bcefc286644bf3 From c581a40a366fbd49c30aec6665fa5a970d02be1b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:46:08 +0300 Subject: [PATCH 157/264] Update sysroot --- contrib/sysroot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/sysroot b/contrib/sysroot index 68bdc5b31a9..bb46f9d9237 160000 --- a/contrib/sysroot +++ b/contrib/sysroot @@ -1 +1 @@ -Subproject commit 68bdc5b31a99a5291660bb9f6257071b75baf367 +Subproject commit bb46f9d92379def88cb1376ee3852ee60913ef83 From 0ec1f3bd3fa8a963c0472f4baa7202677dde36d1 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:48:41 +0300 Subject: [PATCH 158/264] Fix error --- contrib/snappy-cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/snappy-cmake/CMakeLists.txt b/contrib/snappy-cmake/CMakeLists.txt index 3f12d875d6b..57f79e42452 100644 --- a/contrib/snappy-cmake/CMakeLists.txt +++ b/contrib/snappy-cmake/CMakeLists.txt @@ -14,7 +14,7 @@ check_include_file("windows.h" HAVE_WINDOWS_H) set (HAVE_BUILTIN_EXPECT 1) set (HAVE_BUILTIN_CTZ 1) -set (SNAPPY_HAVE_SSSE3 HAVE_SSSE3) +set (SNAPPY_HAVE_SSSE3 ENABLE_SSSE3) set (HAVE_FUNC_MMAP 1) set (HAVE_FUNC_SYSCONF 1) From 31e9214e430751d738cd5962e0e239a4f31cecf2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 07:52:05 +0300 Subject: [PATCH 159/264] Fix error --- contrib/rocksdb-cmake/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contrib/rocksdb-cmake/CMakeLists.txt b/contrib/rocksdb-cmake/CMakeLists.txt index 6ccbd12516e..19cb0bf2aa6 100644 --- a/contrib/rocksdb-cmake/CMakeLists.txt +++ b/contrib/rocksdb-cmake/CMakeLists.txt @@ -155,7 +155,14 @@ endif() option(WITH_FALLOCATE "build with fallocate" ON) if(WITH_FALLOCATE) - set (HAVE_FALLOCATE 1) + CHECK_C_SOURCE_COMPILES(" +#include +#include +int main() { + int fd = open(\"/dev/null\", 0); + fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, 1024); +} +" HAVE_FALLOCATE) if(HAVE_FALLOCATE) add_definitions(-DROCKSDB_FALLOCATE_PRESENT) endif() From 264b278e1ea2b66c31f4ede47bbe8f5d074aa47f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 08:29:50 +0300 Subject: [PATCH 160/264] Fix error --- contrib/snappy-cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/snappy-cmake/CMakeLists.txt b/contrib/snappy-cmake/CMakeLists.txt index 57f79e42452..efa93d1064a 100644 --- a/contrib/snappy-cmake/CMakeLists.txt +++ b/contrib/snappy-cmake/CMakeLists.txt @@ -14,7 +14,7 @@ check_include_file("windows.h" HAVE_WINDOWS_H) set (HAVE_BUILTIN_EXPECT 1) set (HAVE_BUILTIN_CTZ 1) -set (SNAPPY_HAVE_SSSE3 ENABLE_SSSE3) +set (SNAPPY_HAVE_SSSE3 ${ENABLE_SSSE3}) set (HAVE_FUNC_MMAP 1) set (HAVE_FUNC_SYSCONF 1) From e7d3ead754728e3d70c8ef05b7225dd50ce84284 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 08:52:41 +0300 Subject: [PATCH 161/264] Fix error --- contrib/snappy-cmake/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contrib/snappy-cmake/CMakeLists.txt b/contrib/snappy-cmake/CMakeLists.txt index efa93d1064a..0407e8bb30d 100644 --- a/contrib/snappy-cmake/CMakeLists.txt +++ b/contrib/snappy-cmake/CMakeLists.txt @@ -14,10 +14,15 @@ check_include_file("windows.h" HAVE_WINDOWS_H) set (HAVE_BUILTIN_EXPECT 1) set (HAVE_BUILTIN_CTZ 1) -set (SNAPPY_HAVE_SSSE3 ${ENABLE_SSSE3}) set (HAVE_FUNC_MMAP 1) set (HAVE_FUNC_SYSCONF 1) +if (ARCH_AMD64 AND ENABLE_SSSE3) + set (SNAPPY_HAVE_SSSE3 1) +else () + set (SNAPPY_HAVE_SSSE3 0) +endif () + configure_file( "${SOURCE_DIR}/cmake/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h") From 284e547bc3fae8dafe2bf7c021aade39673ab472 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 09:01:23 +0300 Subject: [PATCH 162/264] Fix error --- src/Interpreters/JIT/CHJIT.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interpreters/JIT/CHJIT.cpp b/src/Interpreters/JIT/CHJIT.cpp index 83b0430a07d..9eec82b4179 100644 --- a/src/Interpreters/JIT/CHJIT.cpp +++ b/src/Interpreters/JIT/CHJIT.cpp @@ -156,7 +156,7 @@ public: throwFromErrno("Cannot mprotect memory region", ErrorCodes::CANNOT_MPROTECT); llvm::sys::Memory::InvalidateInstructionCache(block.base(), block.blockSize()); - InvalidateCache = false; + invalidate_cache = false; } # endif int res = mprotect(block.base(), block.blockSize(), protection_flags); From 3386e3a34962645fd4f4626e00ddd7cadf750625 Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:24:27 +0300 Subject: [PATCH 163/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index c91d5caef8d..b05c236feac 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -2353,7 +2353,7 @@ SELECT dummy, shardNum(), shardCount() FROM shard_num_example; **См. также** -- [Distributed Table Engine](../../engines/table-engines/special/distributed.md) +- Табличный движок [Distributed](../../engines/table-engines/special/distributed.md) ## shardCount {#shard-count} From dc01e86fb9798b867598c51fbc287df162bee015 Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:24:46 +0300 Subject: [PATCH 164/264] Update docs/ru/engines/table-engines/special/distributed.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/engines/table-engines/special/distributed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/engines/table-engines/special/distributed.md b/docs/ru/engines/table-engines/special/distributed.md index ff1dc7c4057..3d7b8cf32d3 100644 --- a/docs/ru/engines/table-engines/special/distributed.md +++ b/docs/ru/engines/table-engines/special/distributed.md @@ -143,7 +143,7 @@ logs - имя кластера в конфигурационном файле с !!! note "Примечание" Так как табличные функции [remote](../../../sql-reference/table-functions/remote.md) и [cluster](../../../sql-reference/table-functions/cluster.md) создают временную таблицу на движке `Distributed`, то в ней также доступен столбец `_shard_num`. -**Смотрите также** +**См. также** - общее описание [виртуальных столбцов](../../../engines/table-engines/index.md#table_engines-virtual_columns) - настройка [background_distributed_schedule_pool_size](../../../operations/settings/settings.md#background_distributed_schedule_pool_size) From b6cb640572f870642d1386465c0ecbe6297ca2ad Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:25:03 +0300 Subject: [PATCH 165/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index b05c236feac..029e53237a8 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -2358,7 +2358,7 @@ SELECT dummy, shardNum(), shardCount() FROM shard_num_example; ## shardCount {#shard-count} Возвращает общее количество шардов для распределенного запроса. -Если запрос не распределенный, то возвращается константное значение `0`. +Если запрос не распределенный, то возвращается значение `0`. **Синтаксис** From d530a2d17b8e9742596fe9cd62795fcd0dc51a9c Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:25:19 +0300 Subject: [PATCH 166/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index 029e53237a8..ca73ee75f50 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -2316,7 +2316,7 @@ SELECT count(DISTINCT t) FROM (SELECT initialQueryID() AS t FROM remote('127.0.0 ## shardNum {#shard-num} Возвращает индекс шарда, который обрабатывает часть данных распределенного запроса. Индексы начинаются с `1`. -Если запрос не распределенный, то возвращается константное значение `0`. +Если запрос не распределенный, то возвращается значение `0`. **Синтаксис** From dccfd8d2623007a7a2edc9455c260376e506a7c3 Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:26:24 +0300 Subject: [PATCH 167/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index ca73ee75f50..001f704c219 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -653,8 +653,8 @@ SELECT ## buildId() {#buildid} -Возвращает ID сборки, сгенерированный компилятором для запущенного сервера ClickHouse. -Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. +Возвращает ID сборки, сгенерированный компилятором для данного сервера ClickHouse. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями, актуальными для каждого шарда. Иначе возвращается константа. ## rowNumberInBlock {#function-rownumberinblock} From 32a4c9b69cd9ee516cb2e796045af94790831cf1 Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:43:10 +0300 Subject: [PATCH 168/264] Update docs/ru/sql-reference/functions/date-time-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/date-time-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/date-time-functions.md b/docs/ru/sql-reference/functions/date-time-functions.md index d4777faf354..924dd559cbe 100644 --- a/docs/ru/sql-reference/functions/date-time-functions.md +++ b/docs/ru/sql-reference/functions/date-time-functions.md @@ -26,7 +26,7 @@ SELECT ## timeZone {#timezone} Возвращает часовой пояс сервера. -Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями, актуальными для каждого шарда. Иначе возвращается константа. **Синтаксис** From 294b8c01f8134592d12ff33e6a63650c6c1718b8 Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:43:23 +0300 Subject: [PATCH 169/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index 001f704c219..3ad9192d9a1 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -8,7 +8,7 @@ toc_title: "Прочие функции" ## hostName() {#hostname} Возвращает строку - имя хоста, на котором эта функция была выполнена. При распределённой обработке запроса, это будет имя хоста удалённого сервера, если функция выполняется на удалённом сервере. -Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями, актуальными для каждого шарда. Иначе возвращается константа. ## getMacro {#getmacro} From 0d357f34842ef9cb5a2c6aadd4b83d2a022a9ee0 Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:43:34 +0300 Subject: [PATCH 170/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index 3ad9192d9a1..7134a19864e 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -649,7 +649,7 @@ SELECT ## version() {#version} Возвращает версию сервера в виде строки. -Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями, актуальными для каждого шарда. Иначе возвращается константа. ## buildId() {#buildid} From e9bb7dd08ce9c45d1a430f323acf8ba38dbee3be Mon Sep 17 00:00:00 2001 From: lehasm Date: Mon, 11 Oct 2021 09:43:51 +0300 Subject: [PATCH 171/264] Update docs/ru/sql-reference/functions/other-functions.md Co-authored-by: olgarev <56617294+olgarev@users.noreply.github.com> --- docs/ru/sql-reference/functions/other-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/functions/other-functions.md b/docs/ru/sql-reference/functions/other-functions.md index 7134a19864e..925aac56968 100644 --- a/docs/ru/sql-reference/functions/other-functions.md +++ b/docs/ru/sql-reference/functions/other-functions.md @@ -644,7 +644,7 @@ SELECT ## uptime() {#uptime} Возвращает аптайм сервера в секундах. -Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями актуальными для каждого шарда. Иначе возвращается константа. +Если функция вызывается в контексте распределенной таблицы, то она генерирует обычный столбец со значениями, актуальными для каждого шарда. Иначе возвращается константа. ## version() {#version} From 063f9cffabf0365a21787aea7c70b8f8da3397c8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 11 Oct 2021 10:03:35 +0300 Subject: [PATCH 172/264] Allow memory profiler under sanitizers Only query profiler cannot work reliably with sanitizers (due to unwinding from signal handler), but memory profiler should be fine. Plus sometimes the problem appears only on build with sanitizers, so it will be useful to have memory related profiling in trace_log. Also there is a flaky check for stateless tests, that uses build with ASan, and now trace_log there is empty, which sometimes does not allow to debug further. --- programs/server/Server.cpp | 15 ++------------- src/Common/QueryProfiler.cpp | 23 +++++++++++++++-------- src/Core/Defines.h | 15 +++++++++++++++ src/Core/Settings.h | 4 ++-- src/Core/SettingsQuirks.cpp | 28 ++++++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 23 deletions(-) diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index bfa402a6c21..902865c6de5 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -1139,18 +1139,7 @@ if (ThreadFuzzer::instance().isEffective()) /// Init trace collector only after trace_log system table was created /// Disable it if we collect test coverage information, because it will work extremely slow. - /// - /// It also cannot work with sanitizers. - /// Sanitizers are using quick "frame walking" stack unwinding (this implies -fno-omit-frame-pointer) - /// And they do unwinding frequently (on every malloc/free, thread/mutex operations, etc). - /// They change %rbp during unwinding and it confuses libunwind if signal comes during sanitizer unwinding - /// and query profiler decide to unwind stack with libunwind at this moment. - /// - /// Symptoms: you'll get silent Segmentation Fault - without sanitizer message and without usual ClickHouse diagnostics. - /// - /// Look at compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h - /// -#if USE_UNWIND && !WITH_COVERAGE && !defined(SANITIZER) && defined(__x86_64__) +#if USE_UNWIND && !WITH_COVERAGE && defined(__x86_64__) /// Profilers cannot work reliably with any other libunwind or without PHDR cache. if (hasPHDRCache()) { @@ -1182,7 +1171,7 @@ if (ThreadFuzzer::instance().isEffective()) #endif #if defined(SANITIZER) - LOG_INFO(log, "Query Profiler and TraceCollector are disabled because they cannot work under sanitizers" + LOG_INFO(log, "Query Profiler disabled because they cannot work under sanitizers" " when two different stack unwinding methods will interfere with each other."); #endif diff --git a/src/Common/QueryProfiler.cpp b/src/Common/QueryProfiler.cpp index 983ae864575..7b905937e11 100644 --- a/src/Common/QueryProfiler.cpp +++ b/src/Common/QueryProfiler.cpp @@ -82,7 +82,21 @@ QueryProfilerBase::QueryProfilerBase(const UInt64 thread_id, const : log(&Poco::Logger::get("QueryProfiler")) , pause_signal(pause_signal_) { -#if USE_UNWIND +#if defined(SANITIZER) + UNUSED(thread_id); + UNUSED(clock_type); + UNUSED(period); + UNUSED(pause_signal); + + throw Exception("QueryProfiler disabled because they cannot work under sanitizers", ErrorCodes::NOT_IMPLEMENTED); +#elif !USE_UNWIND + UNUSED(thread_id); + UNUSED(clock_type); + UNUSED(period); + UNUSED(pause_signal); + + throw Exception("QueryProfiler cannot work with stock libunwind", ErrorCodes::NOT_IMPLEMENTED); +#else /// Sanity check. if (!hasPHDRCache()) throw Exception("QueryProfiler cannot be used without PHDR cache, that is not available for TSan build", ErrorCodes::NOT_IMPLEMENTED); @@ -144,13 +158,6 @@ QueryProfilerBase::QueryProfilerBase(const UInt64 thread_id, const tryCleanup(); throw; } -#else - UNUSED(thread_id); - UNUSED(clock_type); - UNUSED(period); - UNUSED(pause_signal); - - throw Exception("QueryProfiler cannot work with stock libunwind", ErrorCodes::NOT_IMPLEMENTED); #endif } diff --git a/src/Core/Defines.h b/src/Core/Defines.h index 660ae187627..215bf6780d9 100644 --- a/src/Core/Defines.h +++ b/src/Core/Defines.h @@ -64,3 +64,18 @@ /// Max depth of hierarchical dictionary #define DBMS_HIERARCHICAL_DICTIONARY_MAX_DEPTH 1000 + +/// Query profiler cannot work with sanitizers. +/// Sanitizers are using quick "frame walking" stack unwinding (this implies -fno-omit-frame-pointer) +/// And they do unwinding frequently (on every malloc/free, thread/mutex operations, etc). +/// They change %rbp during unwinding and it confuses libunwind if signal comes during sanitizer unwinding +/// and query profiler decide to unwind stack with libunwind at this moment. +/// +/// Symptoms: you'll get silent Segmentation Fault - without sanitizer message and without usual ClickHouse diagnostics. +/// +/// Look at compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +#if !defined(SANITIZER) +#define QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS 1000000000 +#else +#define QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS 0 +#endif diff --git a/src/Core/Settings.h b/src/Core/Settings.h index f55f10c0267..6dcbf663dd5 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -265,8 +265,8 @@ class IColumn; M(Bool, allow_suspicious_codecs, false, "If it is set to true, allow to specify meaningless compression codecs.", 0) \ M(Bool, allow_experimental_codecs, false, "If it is set to true, allow to specify experimental compression codecs (but we don't have those yet and this option does nothing).", 0) \ M(UInt64, odbc_max_field_size, 1024, "Max size of filed can be read from ODBC dictionary. Long strings are truncated.", 0) \ - M(UInt64, query_profiler_real_time_period_ns, 1000000000, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off the real clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \ - M(UInt64, query_profiler_cpu_time_period_ns, 1000000000, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off the CPU clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \ + M(UInt64, query_profiler_real_time_period_ns, QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS, "Period for real clock timer of query profiler (in nanoseconds). Set 0 value to turn off the real clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \ + M(UInt64, query_profiler_cpu_time_period_ns, QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS, "Period for CPU clock timer of query profiler (in nanoseconds). Set 0 value to turn off the CPU clock query profiler. Recommended value is at least 10000000 (100 times a second) for single queries or 1000000000 (once a second) for cluster-wide profiling.", 0) \ M(Bool, metrics_perf_events_enabled, false, "If enabled, some of the perf events will be measured throughout queries' execution.", 0) \ M(String, metrics_perf_events_list, "", "Comma separated list of perf metrics that will be measured throughout queries' execution. Empty means all events. See PerfEventInfo in sources for the available events.", 0) \ M(Float, opentelemetry_start_trace_probability, 0., "Probability to start an OpenTelemetry trace for an incoming query.", 0) \ diff --git a/src/Core/SettingsQuirks.cpp b/src/Core/SettingsQuirks.cpp index 94bd2e166b2..9b5644b75e1 100644 --- a/src/Core/SettingsQuirks.cpp +++ b/src/Core/SettingsQuirks.cpp @@ -6,6 +6,9 @@ #include #include +namespace +{ + /// Detect does epoll_wait with nested epoll fds works correctly. /// Polling nested epoll fds from epoll_wait is required for async_socket_for_remote and use_hedged_requests. /// @@ -31,6 +34,15 @@ bool nestedEpollWorks(Poco::Logger * log) return true; } +/// See also QUERY_PROFILER_DEFAULT_SAMPLE_RATE_NS in Core/Defines.h +#if !defined(SANITIZER) +bool queryProfilerWorks() { return true; } +#else +bool queryProfilerWorks() { return false; } +#endif + +} + namespace DB { @@ -52,6 +64,22 @@ void applySettingsQuirks(Settings & settings, Poco::Logger * log) LOG_WARNING(log, "use_hedged_requests has been disabled (you can explicitly enable it still)"); } } + + if (!queryProfilerWorks()) + { + if (settings.query_profiler_real_time_period_ns) + { + settings.query_profiler_real_time_period_ns = 0; + if (log) + LOG_WARNING(log, "query_profiler_real_time_period_ns has been disabled (due to server had been compiled with sanitizers)"); + } + if (settings.query_profiler_cpu_time_period_ns) + { + settings.query_profiler_cpu_time_period_ns = 0; + if (log) + LOG_WARNING(log, "query_profiler_cpu_time_period_ns has been disabled (due to server had been compiled with sanitizers)"); + } + } } } From ebfb013ea1577aa601a0caad45af60e12ba851b8 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Fri, 8 Oct 2021 11:40:29 +0800 Subject: [PATCH 173/264] Fix potential leak of query_id_holder --- src/Processors/QueryPlan/QueryIdHolder.cpp | 1 + src/Processors/QueryPlan/QueryIdHolder.h | 5 +- .../QueryPlan/ReadFromMergeTree.cpp | 2 +- src/Storages/MergeTree/MergeTreeData.cpp | 19 ++++-- src/Storages/MergeTree/MergeTreeData.h | 7 ++- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 63 ++++++++++--------- .../MergeTree/MergeTreeDataSelectExecutor.h | 2 +- .../01666_merge_tree_max_query_limit.sh | 8 +++ 8 files changed, 66 insertions(+), 41 deletions(-) diff --git a/src/Processors/QueryPlan/QueryIdHolder.cpp b/src/Processors/QueryPlan/QueryIdHolder.cpp index 87f6f892cd1..6ff238e017c 100644 --- a/src/Processors/QueryPlan/QueryIdHolder.cpp +++ b/src/Processors/QueryPlan/QueryIdHolder.cpp @@ -3,6 +3,7 @@ namespace DB { + QueryIdHolder::QueryIdHolder(const String & query_id_, const MergeTreeData & data_) : query_id(query_id_), data(data_) { } diff --git a/src/Processors/QueryPlan/QueryIdHolder.h b/src/Processors/QueryPlan/QueryIdHolder.h index ed8f9ec1d6b..1e1ee1af0a1 100644 --- a/src/Processors/QueryPlan/QueryIdHolder.h +++ b/src/Processors/QueryPlan/QueryIdHolder.h @@ -2,13 +2,16 @@ #include +#include + namespace DB { + class MergeTreeData; /// Holds the current query id and do something meaningful in destructor. /// Currently it's used for cleaning query id in the MergeTreeData query set. -struct QueryIdHolder +struct QueryIdHolder : private boost::noncopyable { QueryIdHolder(const std::string & query_id_, const MergeTreeData & data_); diff --git a/src/Processors/QueryPlan/ReadFromMergeTree.cpp b/src/Processors/QueryPlan/ReadFromMergeTree.cpp index a48adc2d645..8d3005e725f 100644 --- a/src/Processors/QueryPlan/ReadFromMergeTree.cpp +++ b/src/Processors/QueryPlan/ReadFromMergeTree.cpp @@ -945,7 +945,7 @@ void ReadFromMergeTree::initializePipeline(QueryPipelineBuilder & pipeline, cons ProfileEvents::increment(ProfileEvents::SelectedRanges, result.selected_ranges); ProfileEvents::increment(ProfileEvents::SelectedMarks, result.selected_marks); - auto query_id_holder = MergeTreeDataSelectExecutor::checkLimits(data, result.parts_with_ranges, context); + auto query_id_holder = MergeTreeDataSelectExecutor::checkLimits(data, result, context); if (result.parts_with_ranges.empty()) { diff --git a/src/Storages/MergeTree/MergeTreeData.cpp b/src/Storages/MergeTree/MergeTreeData.cpp index c04e0d2e38f..646737b11ae 100644 --- a/src/Storages/MergeTree/MergeTreeData.cpp +++ b/src/Storages/MergeTree/MergeTreeData.cpp @@ -5321,26 +5321,33 @@ void MergeTreeData::setDataVolume(size_t bytes, size_t rows, size_t parts) total_active_size_parts.store(parts, std::memory_order_release); } -void MergeTreeData::insertQueryIdOrThrow(const String & query_id, size_t max_queries) const +bool MergeTreeData::insertQueryIdOrThrow(const String & query_id, size_t max_queries) const { std::lock_guard lock(query_id_set_mutex); + return insertQueryIdOrThrowNoLock(query_id, max_queries, lock); +} + +bool MergeTreeData::insertQueryIdOrThrowNoLock(const String & query_id, size_t max_queries, const std::lock_guard &) const +{ if (query_id_set.find(query_id) != query_id_set.end()) - return; + return false; if (query_id_set.size() >= max_queries) throw Exception( ErrorCodes::TOO_MANY_SIMULTANEOUS_QUERIES, "Too many simultaneous queries for table {}. Maximum is: {}", log_name, max_queries); query_id_set.insert(query_id); + return true; } void MergeTreeData::removeQueryId(const String & query_id) const { std::lock_guard lock(query_id_set_mutex); + removeQueryIdNoLock(query_id, lock); +} + +void MergeTreeData::removeQueryIdNoLock(const String & query_id, const std::lock_guard &) const +{ if (query_id_set.find(query_id) == query_id_set.end()) - { - /// Do not throw exception, because this method is used in destructor. LOG_WARNING(log, "We have query_id removed but it's not recorded. This is a bug"); - assert(false); - } else query_id_set.erase(query_id); } diff --git a/src/Storages/MergeTree/MergeTreeData.h b/src/Storages/MergeTree/MergeTreeData.h index bdebd5e9187..e33e6aa0ef4 100644 --- a/src/Storages/MergeTree/MergeTreeData.h +++ b/src/Storages/MergeTree/MergeTreeData.h @@ -794,11 +794,16 @@ public: /// section from config.xml. CompressionCodecPtr getCompressionCodecForPart(size_t part_size_compressed, const IMergeTreeDataPart::TTLInfos & ttl_infos, time_t current_time) const; + std::lock_guard getQueryIdSetLock() const { return std::lock_guard(query_id_set_mutex); } + /// Record current query id where querying the table. Throw if there are already `max_queries` queries accessing the same table. - void insertQueryIdOrThrow(const String & query_id, size_t max_queries) const; + /// Returns false if the `query_id` already exists in the running set, otherwise return true. + bool insertQueryIdOrThrow(const String & query_id, size_t max_queries) const; + bool insertQueryIdOrThrowNoLock(const String & query_id, size_t max_queries, const std::lock_guard &) const; /// Remove current query id after query finished. void removeQueryId(const String & query_id) const; + void removeQueryIdNoLock(const String & query_id, const std::lock_guard &) const; /// Return the partition expression types as a Tuple type. Return DataTypeUInt8 if partition expression is empty. DataTypePtr getPartitionValueType() const; diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 03d76a7f79b..44b913ea81a 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -993,47 +993,48 @@ RangesInDataParts MergeTreeDataSelectExecutor::filterPartsByPrimaryKeyAndSkipInd std::shared_ptr MergeTreeDataSelectExecutor::checkLimits( const MergeTreeData & data, - const RangesInDataParts & parts_with_ranges, + const ReadFromMergeTree::AnalysisResult & result, const ContextPtr & context) { const auto & settings = context->getSettingsRef(); - // Check limitations. query_id is used as the quota RAII's resource key. - String query_id; + const auto data_settings = data.getSettings(); + auto max_partitions_to_read + = settings.max_partitions_to_read.changed ? settings.max_partitions_to_read : data_settings->max_partitions_to_read; + if (max_partitions_to_read > 0) { - const auto data_settings = data.getSettings(); - auto max_partitions_to_read - = settings.max_partitions_to_read.changed ? settings.max_partitions_to_read : data_settings->max_partitions_to_read; - if (max_partitions_to_read > 0) - { - std::set partitions; - for (const auto & part_with_ranges : parts_with_ranges) - partitions.insert(part_with_ranges.data_part->info.partition_id); - if (partitions.size() > size_t(max_partitions_to_read)) - throw Exception( - ErrorCodes::TOO_MANY_PARTITIONS, - "Too many partitions to read. Current {}, max {}", - partitions.size(), - max_partitions_to_read); - } + std::set partitions; + for (const auto & part_with_ranges : result.parts_with_ranges) + partitions.insert(part_with_ranges.data_part->info.partition_id); + if (partitions.size() > size_t(max_partitions_to_read)) + throw Exception( + ErrorCodes::TOO_MANY_PARTITIONS, + "Too many partitions to read. Current {}, max {}", + partitions.size(), + max_partitions_to_read); + } - if (data_settings->max_concurrent_queries > 0 && data_settings->min_marks_to_honor_max_concurrent_queries > 0) + if (data_settings->max_concurrent_queries > 0 && data_settings->min_marks_to_honor_max_concurrent_queries > 0 + && result.selected_marks >= data_settings->min_marks_to_honor_max_concurrent_queries) + { + auto query_id = context->getCurrentQueryId(); + if (!query_id.empty()) { - size_t sum_marks = 0; - for (const auto & part : parts_with_ranges) - sum_marks += part.getMarksCount(); - - if (sum_marks >= data_settings->min_marks_to_honor_max_concurrent_queries) + auto lock = data.getQueryIdSetLock(); + if (data.insertQueryIdOrThrowNoLock(query_id, data_settings->max_concurrent_queries, lock)) { - query_id = context->getCurrentQueryId(); - if (!query_id.empty()) - data.insertQueryIdOrThrow(query_id, data_settings->max_concurrent_queries); + try + { + return std::make_shared(query_id, data); + } + catch (...) + { + /// If we fail to construct the holder, remove query_id explicitly to avoid leak. + data.removeQueryIdNoLock(query_id, lock); + throw; + } } } } - - if (!query_id.empty()) - return std::make_shared(query_id, data); - return nullptr; } diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h index 92c4382dc90..3cc5033c9f1 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.h @@ -197,7 +197,7 @@ public: /// Also, return QueryIdHolder. If not null, we should keep it until query finishes. static std::shared_ptr checkLimits( const MergeTreeData & data, - const RangesInDataParts & parts_with_ranges, + const ReadFromMergeTree::AnalysisResult & result, const ContextPtr & context); }; diff --git a/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh b/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh index c5fbb35a9cd..6fb337f2ca5 100755 --- a/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh +++ b/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh @@ -66,6 +66,14 @@ echo "yes" ${CLICKHOUSE_CLIENT} --query "KILL QUERY WHERE query_id = '$query_id' SYNC FORMAT Null" wait +# Check correctness of multiple subqueries +query_id=max_concurrent_queries_$RANDOM +${CLICKHOUSE_CLIENT} --query_id "$query_id" --query "select i from simple where j in (select i from simple where i < 10)" + +# We have to grep the server's error log because the following warning message +# is generated during pipeline destruction and thus is not sent to the client. +grep -E -q "{$query_id} .*We have query_id removed but it's not recorded. This is a bug" /var/log/clickhouse-server/clickhouse-server.err.log && exit 1 + ${CLICKHOUSE_CLIENT} --multiline --multiquery --query " drop table simple " From e05d04153790b9ed5aac4382f1d83f428eb94d2e Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Mon, 11 Oct 2021 11:34:58 +0300 Subject: [PATCH 174/264] Tests naming fix --- ...default.reference => 02026_accurate_cast_or_default.reference} | 0 ...ate_cast_or_default.sql => 02026_accurate_cast_or_default.sql} | 0 .../0_stateless/{2027_ngrams.reference => 02027_ngrams.reference} | 0 tests/queries/0_stateless/{2027_ngrams.sql => 02027_ngrams.sql} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/queries/0_stateless/{2026_accurate_cast_or_default.reference => 02026_accurate_cast_or_default.reference} (100%) rename tests/queries/0_stateless/{2026_accurate_cast_or_default.sql => 02026_accurate_cast_or_default.sql} (100%) rename tests/queries/0_stateless/{2027_ngrams.reference => 02027_ngrams.reference} (100%) rename tests/queries/0_stateless/{2027_ngrams.sql => 02027_ngrams.sql} (100%) diff --git a/tests/queries/0_stateless/2026_accurate_cast_or_default.reference b/tests/queries/0_stateless/02026_accurate_cast_or_default.reference similarity index 100% rename from tests/queries/0_stateless/2026_accurate_cast_or_default.reference rename to tests/queries/0_stateless/02026_accurate_cast_or_default.reference diff --git a/tests/queries/0_stateless/2026_accurate_cast_or_default.sql b/tests/queries/0_stateless/02026_accurate_cast_or_default.sql similarity index 100% rename from tests/queries/0_stateless/2026_accurate_cast_or_default.sql rename to tests/queries/0_stateless/02026_accurate_cast_or_default.sql diff --git a/tests/queries/0_stateless/2027_ngrams.reference b/tests/queries/0_stateless/02027_ngrams.reference similarity index 100% rename from tests/queries/0_stateless/2027_ngrams.reference rename to tests/queries/0_stateless/02027_ngrams.reference diff --git a/tests/queries/0_stateless/2027_ngrams.sql b/tests/queries/0_stateless/02027_ngrams.sql similarity index 100% rename from tests/queries/0_stateless/2027_ngrams.sql rename to tests/queries/0_stateless/02027_ngrams.sql From 2d069acc220347942ac3716168ded3dc7f9ded12 Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Fri, 8 Oct 2021 16:13:56 +0300 Subject: [PATCH 175/264] System table data skipping indices added size --- .../system-tables/data_skipping_indices.md | 9 +++ docs/en/operations/system-tables/parts.md | 9 +++ src/Storages/IStorage.h | 7 ++ src/Storages/MergeTree/IMergeTreeDataPart.cpp | 50 +++++++++++++- src/Storages/MergeTree/IMergeTreeDataPart.h | 21 +++++- src/Storages/MergeTree/MergeTreeData.cpp | 68 ++++++++++++++----- src/Storages/MergeTree/MergeTreeData.h | 20 ++++-- .../MergeTree/MergedBlockOutputStream.cpp | 3 +- src/Storages/MergeTree/MutateTask.cpp | 2 +- .../StorageSystemDataSkippingIndices.cpp | 19 ++++++ src/Storages/System/StorageSystemParts.cpp | 10 +++ 11 files changed, 192 insertions(+), 26 deletions(-) diff --git a/docs/en/operations/system-tables/data_skipping_indices.md b/docs/en/operations/system-tables/data_skipping_indices.md index 683666e1f77..add89ae9144 100644 --- a/docs/en/operations/system-tables/data_skipping_indices.md +++ b/docs/en/operations/system-tables/data_skipping_indices.md @@ -10,6 +10,9 @@ Columns: - `type` ([String](../../sql-reference/data-types/string.md)) — Index type. - `expr` ([String](../../sql-reference/data-types/string.md)) — Expression for the index calculation. - `granularity` ([UInt64](../../sql-reference/data-types/int-uint.md)) — The number of granules in the block. +- `data_compressed_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) — The size of compressed data, in bytes. +- `data_uncompressed_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) — The size of decompressed data, in bytes. +- `marks_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) — The size of marks, in bytes. **Example** @@ -26,6 +29,9 @@ name: clicks_idx type: minmax expr: clicks granularity: 1 +data_compressed_bytes: 58 +data_uncompressed_bytes: 6 +marks: 48 Row 2: ────── @@ -35,4 +41,7 @@ name: contacts_null_idx type: minmax expr: assumeNotNull(contacts_null) granularity: 1 +data_compressed_bytes: 58 +data_uncompressed_bytes: 6 +marks: 48 ``` diff --git a/docs/en/operations/system-tables/parts.md b/docs/en/operations/system-tables/parts.md index 51a0a1180f3..45fdcc40451 100644 --- a/docs/en/operations/system-tables/parts.md +++ b/docs/en/operations/system-tables/parts.md @@ -38,6 +38,12 @@ Columns: - `marks_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) – The size of the file with marks. +- `secondary_indices_compressed_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) – Total size of compressed data for secondary indices in the data part. All the auxiliary files (for example, files with marks) are not included. + +- `secondary_indices_uncompressed_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) – Total size of uncompressed data for secondary indices in the data part. All the auxiliary files (for example, files with marks) are not included. + +- `secondary_indices_marks_bytes` ([UInt64](../../sql-reference/data-types/int-uint.md)) – The size of the file with marks for secondary indices. + - `modification_time` ([DateTime](../../sql-reference/data-types/datetime.md)) – The time the directory with the data part was modified. This usually corresponds to the time of data part creation. - `remove_time` ([DateTime](../../sql-reference/data-types/datetime.md)) – The time when the data part became inactive. @@ -119,6 +125,9 @@ rows: 6 bytes_on_disk: 310 data_compressed_bytes: 157 data_uncompressed_bytes: 91 +secondary_indices_compressed_bytes: 58 +secondary_indices_uncompressed_bytes: 6 +secondary_indices_marks_bytes: 48 marks_bytes: 144 modification_time: 2020-06-18 13:01:49 remove_time: 1970-01-01 00:00:00 diff --git a/src/Storages/IStorage.h b/src/Storages/IStorage.h index 6ce17552ba1..0a9d1113601 100644 --- a/src/Storages/IStorage.h +++ b/src/Storages/IStorage.h @@ -87,6 +87,8 @@ struct ColumnSize } }; +using IndexSize = ColumnSize; + /** Storage. Describes the table. Responsible for * - storage of the table data; * - the definition in which files (or not in files) the data is stored; @@ -163,6 +165,11 @@ public: using ColumnSizeByName = std::unordered_map; virtual ColumnSizeByName getColumnSizes() const { return {}; } + /// Optional size information of each secondary index. + /// Valid only for MergeTree family. + using IndexSizeByName = std::unordered_map; + virtual IndexSizeByName getSecondaryIndexSizes() const { return {}; } + /// Get mutable version (snapshot) of storage metadata. Metadata object is /// multiversion, so it can be concurrently changed, but returned copy can be /// used without any locks. diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.cpp b/src/Storages/MergeTree/IMergeTreeDataPart.cpp index dc2c5f8185d..1a6290580a0 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.cpp +++ b/src/Storages/MergeTree/IMergeTreeDataPart.cpp @@ -584,7 +584,7 @@ void IMergeTreeDataPart::loadColumnsChecksumsIndexes(bool require_columns_checks loadColumns(require_columns_checksums); loadChecksums(require_columns_checksums); loadIndexGranularity(); - calculateColumnsSizesOnDisk(); + calculateColumnsAndSecondaryIndicesSizesOnDisk(); loadIndex(); /// Must be called after loadIndexGranularity as it uses the value of `index_granularity` loadRowsCount(); /// Must be called after loadIndexGranularity() as it uses the value of `index_granularity`. loadPartitionAndMinMaxIndex(); @@ -1420,6 +1420,11 @@ void IMergeTreeDataPart::checkConsistency(bool /* require_part_metadata */) cons throw Exception("Method 'checkConsistency' is not implemented for part with type " + getType().toString(), ErrorCodes::NOT_IMPLEMENTED); } +void IMergeTreeDataPart::calculateColumnsAndSecondaryIndicesSizesOnDisk() +{ + calculateColumnsSizesOnDisk(); + calculateSecondaryIndicesSizesOnDisk(); +} void IMergeTreeDataPart::calculateColumnsSizesOnDisk() { @@ -1429,6 +1434,40 @@ void IMergeTreeDataPart::calculateColumnsSizesOnDisk() calculateEachColumnSizes(columns_sizes, total_columns_size); } +void IMergeTreeDataPart::calculateSecondaryIndicesSizesOnDisk() +{ + if (checksums.empty()) + throw Exception("Cannot calculate secondary indexes sizes when columns or checksums are not initialized", ErrorCodes::LOGICAL_ERROR); + + auto secondary_indices_descriptions = storage.getInMemoryMetadataPtr()->secondary_indices; + + for (auto & index_description : secondary_indices_descriptions) + { + ColumnSize index_size; + + auto index_ptr = MergeTreeIndexFactory::instance().get(index_description); + auto index_name = index_ptr->getFileName(); + auto index_name_escaped = escapeForFileName(index_name); + + auto index_file_name = index_name_escaped + index_ptr->getSerializedFileExtension(); + auto index_marks_file_name = index_name_escaped + index_granularity_info.marks_file_extension; + + auto bin_checksum = checksums.files.find(index_file_name); + if (bin_checksum != checksums.files.end()) + { + index_size.data_compressed = bin_checksum->second.file_size; + index_size.data_uncompressed = bin_checksum->second.uncompressed_size; + } + + auto mrk_checksum = checksums.files.find(index_marks_file_name); + if (mrk_checksum != checksums.files.end()) + index_size.marks = mrk_checksum->second.file_size; + + total_secondary_indices_size.add(index_size); + secondary_index_sizes[index_description.name] = index_size; + } +} + ColumnSize IMergeTreeDataPart::getColumnSize(const String & column_name, const IDataType & /* type */) const { /// For some types of parts columns_size maybe not calculated @@ -1439,6 +1478,15 @@ ColumnSize IMergeTreeDataPart::getColumnSize(const String & column_name, const I return ColumnSize{}; } +IndexSize IMergeTreeDataPart::getSecondaryIndexSize(const String & secondary_index_name) const +{ + auto it = secondary_index_sizes.find(secondary_index_name); + if (it != secondary_index_sizes.end()) + return it->second; + + return ColumnSize{}; +} + void IMergeTreeDataPart::accumulateColumnSizes(ColumnToSize & column_to_size) const { for (const auto & [column_name, size] : columns_sizes) diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.h b/src/Storages/MergeTree/IMergeTreeDataPart.h index be48aed5c8b..ceb3ed64170 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.h +++ b/src/Storages/MergeTree/IMergeTreeDataPart.h @@ -55,6 +55,8 @@ public: using ColumnSizeByName = std::unordered_map; using NameToNumber = std::unordered_map; + using IndexSizeByName = std::unordered_map; + using Type = MergeTreeDataPartType; @@ -101,9 +103,16 @@ public: /// Otherwise return information about column size on disk. ColumnSize getColumnSize(const String & column_name, const IDataType & /* type */) const; + /// NOTE: Returns zeros if secondary indexes are not found in checksums. + /// Otherwise return information about secondary index size on disk. + IndexSize getSecondaryIndexSize(const String & secondary_index_name) const; + /// Return information about column size on disk for all columns in part ColumnSize getTotalColumnsSize() const { return total_columns_size; } + /// Return information about secondary indexes size on disk for all indexes in part + IndexSize getTotalSeconaryIndicesSize() const { return total_secondary_indices_size; } + virtual String getFileNameForColumn(const NameAndTypePair & column) const = 0; virtual ~IMergeTreeDataPart(); @@ -341,7 +350,9 @@ public: /// Calculate the total size of the entire directory with all the files static UInt64 calculateTotalSizeOnDisk(const DiskPtr & disk_, const String & from); - void calculateColumnsSizesOnDisk(); + + /// Calculate column and secondary indices sizes on disk. + void calculateColumnsAndSecondaryIndicesSizesOnDisk(); String getRelativePathForPrefix(const String & prefix) const; @@ -396,6 +407,10 @@ protected: /// Size for each column, calculated once in calcuateColumnSizesOnDisk ColumnSizeByName columns_sizes; + ColumnSize total_secondary_indices_size; + + IndexSizeByName secondary_index_sizes; + /// Total size on disk, not only columns. May not contain size of /// checksums.txt and columns.txt. 0 - if not counted; UInt64 bytes_on_disk{0}; @@ -450,6 +465,10 @@ private: void loadPartitionAndMinMaxIndex(); + void calculateColumnsSizesOnDisk(); + + void calculateSecondaryIndicesSizesOnDisk(); + /// Load default compression codec from file default_compression_codec.txt /// if it not exists tries to deduce codec from compressed column without /// any specifial compression. diff --git a/src/Storages/MergeTree/MergeTreeData.cpp b/src/Storages/MergeTree/MergeTreeData.cpp index c04e0d2e38f..10e5fe9e71f 100644 --- a/src/Storages/MergeTree/MergeTreeData.cpp +++ b/src/Storages/MergeTree/MergeTreeData.cpp @@ -1167,7 +1167,7 @@ void MergeTreeData::loadDataParts(bool skip_sanity_checks) } } - calculateColumnSizesImpl(); + calculateColumnAndSecondaryIndexSizesImpl(); LOG_DEBUG(log, "Loaded data parts ({} items)", data_parts_indexes.size()); @@ -2352,7 +2352,7 @@ bool MergeTreeData::renameTempPartAndReplace( { covered_part->remove_time.store(current_time, std::memory_order_relaxed); modifyPartState(covered_part, DataPartState::Outdated); - removePartContributionToColumnSizes(covered_part); + removePartContributionToColumnAndSecondaryIndexSizes(covered_part); reduce_bytes += covered_part->getBytesOnDisk(); reduce_rows += covered_part->rows_count; ++reduce_parts; @@ -2361,7 +2361,7 @@ bool MergeTreeData::renameTempPartAndReplace( decreaseDataVolume(reduce_bytes, reduce_rows, reduce_parts); modifyPartState(part_it, DataPartState::Committed); - addPartContributionToColumnSizes(part); + addPartContributionToColumnAndSecondaryIndexSizes(part); addPartContributionToDataVolume(part); } @@ -2404,7 +2404,7 @@ void MergeTreeData::removePartsFromWorkingSet(const MergeTreeData::DataPartsVect { if (part->getState() == IMergeTreeDataPart::State::Committed) { - removePartContributionToColumnSizes(part); + removePartContributionToColumnAndSecondaryIndexSizes(part); removePartContributionToDataVolume(part); } @@ -2542,7 +2542,7 @@ restore_covered) if (part->getState() == DataPartState::Committed) { removePartContributionToDataVolume(part); - removePartContributionToColumnSizes(part); + removePartContributionToColumnAndSecondaryIndexSizes(part); } modifyPartState(it_part, DataPartState::Deleting); @@ -2590,7 +2590,7 @@ restore_covered) if ((*it)->getState() != DataPartState::Committed) { - addPartContributionToColumnSizes(*it); + addPartContributionToColumnAndSecondaryIndexSizes(*it); addPartContributionToDataVolume(*it); modifyPartState(it, DataPartState::Committed); // iterator is not invalidated here } @@ -2621,7 +2621,7 @@ restore_covered) if ((*it)->getState() != DataPartState::Committed) { - addPartContributionToColumnSizes(*it); + addPartContributionToColumnAndSecondaryIndexSizes(*it); addPartContributionToDataVolume(*it); modifyPartState(it, DataPartState::Committed); } @@ -2973,32 +2973,46 @@ static void loadPartAndFixMetadataImpl(MergeTreeData::MutableDataPartPtr part) part->modification_time = disk->getLastModified(full_part_path).epochTime(); } -void MergeTreeData::calculateColumnSizesImpl() +void MergeTreeData::calculateColumnAndSecondaryIndexSizesImpl() { + std::cerr << "MergeTreeData::calculateColumnAndSecondaryIndexSizesImpl" << std::endl; + column_sizes.clear(); /// Take into account only committed parts auto committed_parts_range = getDataPartsStateRange(DataPartState::Committed); for (const auto & part : committed_parts_range) - addPartContributionToColumnSizes(part); + addPartContributionToColumnAndSecondaryIndexSizes(part); } -void MergeTreeData::addPartContributionToColumnSizes(const DataPartPtr & part) +void MergeTreeData::addPartContributionToColumnAndSecondaryIndexSizes(const DataPartPtr & part) { + std::cerr << "MergeTreeData::addPartContributionToColumnAndSecondaryIndexSizes " << part->name << std::endl; + for (const auto & column : part->getColumns()) { + std::cerr << "Column name " << column.name << std::endl; ColumnSize & total_column_size = column_sizes[column.name]; + std::cerr << "Total column size compressed " << total_column_size.data_compressed << " uncompressed size " << total_column_size.data_uncompressed << std::endl; ColumnSize part_column_size = part->getColumnSize(column.name, *column.type); total_column_size.add(part_column_size); } + + auto indexes_descriptions = getInMemoryMetadataPtr()->secondary_indices; + for (const auto & index : indexes_descriptions) + { + IndexSize & total_secondary_index_size = secondary_index_sizes[index.name]; + IndexSize part_index_size = part->getSecondaryIndexSize(index.name); + total_secondary_index_size.add(part_index_size); + } } -void MergeTreeData::removePartContributionToColumnSizes(const DataPartPtr & part) +void MergeTreeData::removePartContributionToColumnAndSecondaryIndexSizes(const DataPartPtr & part) { for (const auto & column : part->getColumns()) { ColumnSize & total_column_size = column_sizes[column.name]; - ColumnSize part_column_size = part->getColumnSize(column.name, *column.type); + ColumnSize part_secondary_index_size = part->getColumnSize(column.name, *column.type); auto log_subtract = [&](size_t & from, size_t value, const char * field) { @@ -3009,9 +3023,29 @@ void MergeTreeData::removePartContributionToColumnSizes(const DataPartPtr & part from -= value; }; - log_subtract(total_column_size.data_compressed, part_column_size.data_compressed, ".data_compressed"); - log_subtract(total_column_size.data_uncompressed, part_column_size.data_uncompressed, ".data_uncompressed"); - log_subtract(total_column_size.marks, part_column_size.marks, ".marks"); + log_subtract(total_column_size.data_compressed, part_secondary_index_size.data_compressed, ".data_compressed"); + log_subtract(total_column_size.data_uncompressed, part_secondary_index_size.data_uncompressed, ".data_uncompressed"); + log_subtract(total_column_size.marks, part_secondary_index_size.marks, ".marks"); + } + + auto indexes_descriptions = getInMemoryMetadataPtr()->secondary_indices; + for (const auto & index : indexes_descriptions) + { + IndexSize & total_secondary_index_size = secondary_index_sizes[index.name]; + IndexSize part_secondary_index_size = part->getSecondaryIndexSize(index.name); + + auto log_subtract = [&](size_t & from, size_t value, const char * field) + { + if (value > from) + LOG_ERROR(log, "Possibly incorrect index size subtraction: {} - {} = {}, index: {}, field: {}", + from, value, from - value, index.name, field); + + from -= value; + }; + + log_subtract(total_secondary_index_size.data_compressed, part_secondary_index_size.data_compressed, ".data_compressed"); + log_subtract(total_secondary_index_size.data_uncompressed, part_secondary_index_size.data_uncompressed, ".data_uncompressed"); + log_subtract(total_secondary_index_size.marks, part_secondary_index_size.marks, ".marks"); } } @@ -4043,7 +4077,7 @@ MergeTreeData::DataPartsVector MergeTreeData::Transaction::commit(MergeTreeData: reduce_rows += covered_part->rows_count; data.modifyPartState(covered_part, DataPartState::Outdated); - data.removePartContributionToColumnSizes(covered_part); + data.removePartContributionToColumnAndSecondaryIndexSizes(covered_part); } reduce_parts += covered_parts.size(); @@ -4052,7 +4086,7 @@ MergeTreeData::DataPartsVector MergeTreeData::Transaction::commit(MergeTreeData: ++add_parts; data.modifyPartState(part, DataPartState::Committed); - data.addPartContributionToColumnSizes(part); + data.addPartContributionToColumnAndSecondaryIndexSizes(part); } } data.decreaseDataVolume(reduce_bytes, reduce_rows, reduce_parts); diff --git a/src/Storages/MergeTree/MergeTreeData.h b/src/Storages/MergeTree/MergeTreeData.h index bdebd5e9187..0e0e84d011b 100644 --- a/src/Storages/MergeTree/MergeTreeData.h +++ b/src/Storages/MergeTree/MergeTreeData.h @@ -654,6 +654,12 @@ public: return column_sizes; } + IndexSizeByName getSecondaryIndexSizes() const override + { + auto lock = lockParts(); + return secondary_index_sizes; + } + /// For ATTACH/DETACH/DROP PARTITION. String getPartitionIDFromQuery(const ASTPtr & ast, ContextPtr context) const; std::unordered_set getPartitionIDsFromQuery(const ASTs & asts, ContextPtr context) const; @@ -873,6 +879,9 @@ protected: /// Current column sizes in compressed and uncompressed form. ColumnSizeByName column_sizes; + /// Current secondary index sizes in compressed and uncompressed form. + IndexSizeByName secondary_index_sizes; + /// Engine-specific methods BrokenPartCallback broken_part_callback; @@ -1005,11 +1014,12 @@ protected: void checkStoragePolicy(const StoragePolicyPtr & new_storage_policy) const; - /// Calculates column sizes in compressed form for the current state of data_parts. Call with data_parts mutex locked. - void calculateColumnSizesImpl(); - /// Adds or subtracts the contribution of the part to compressed column sizes. - void addPartContributionToColumnSizes(const DataPartPtr & part); - void removePartContributionToColumnSizes(const DataPartPtr & part); + /// Calculates column and secondary indexes sizes in compressed form for the current state of data_parts. Call with data_parts mutex locked. + void calculateColumnAndSecondaryIndexSizesImpl(); + + /// Adds or subtracts the contribution of the part to compressed column and secondary indexes sizes. + void addPartContributionToColumnAndSecondaryIndexSizes(const DataPartPtr & part); + void removePartContributionToColumnAndSecondaryIndexSizes(const DataPartPtr & part); /// If there is no part in the partition with ID `partition_id`, returns empty ptr. Should be called under the lock. DataPartPtr getAnyPartInPartition(const String & partition_id, DataPartsLock & data_parts_lock) const; diff --git a/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/src/Storages/MergeTree/MergedBlockOutputStream.cpp index 5206f77290b..43146709686 100644 --- a/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -87,7 +87,8 @@ void MergedBlockOutputStream::writeSuffixAndFinalizePart( new_part->checksums = checksums; new_part->setBytesOnDisk(checksums.getTotalSizeOnDisk()); new_part->index_granularity = writer->getIndexGranularity(); - new_part->calculateColumnsSizesOnDisk(); + new_part->calculateColumnsAndSecondaryIndicesSizesOnDisk(); + if (default_codec != nullptr) new_part->default_codec = default_codec; new_part->storage.lockSharedData(*new_part); diff --git a/src/Storages/MergeTree/MutateTask.cpp b/src/Storages/MergeTree/MutateTask.cpp index b8941fc9d84..115de043cd2 100644 --- a/src/Storages/MergeTree/MutateTask.cpp +++ b/src/Storages/MergeTree/MutateTask.cpp @@ -475,7 +475,7 @@ void finalizeMutatedPart( new_data_part->setBytesOnDisk( MergeTreeData::DataPart::calculateTotalSizeOnDisk(new_data_part->volume->getDisk(), new_data_part->getFullRelativePath())); new_data_part->default_codec = codec; - new_data_part->calculateColumnsSizesOnDisk(); + new_data_part->calculateColumnsAndSecondaryIndicesSizesOnDisk(); new_data_part->storage.lockSharedData(*new_data_part); } diff --git a/src/Storages/System/StorageSystemDataSkippingIndices.cpp b/src/Storages/System/StorageSystemDataSkippingIndices.cpp index 7a6ce4ec519..d7fc06da953 100644 --- a/src/Storages/System/StorageSystemDataSkippingIndices.cpp +++ b/src/Storages/System/StorageSystemDataSkippingIndices.cpp @@ -25,6 +25,9 @@ StorageSystemDataSkippingIndices::StorageSystemDataSkippingIndices(const Storage { "type", std::make_shared() }, { "expr", std::make_shared() }, { "granularity", std::make_shared() }, + { "data_compressed_bytes", std::make_shared() }, + { "data_uncompressed_bytes", std::make_shared() }, + { "marks", std::make_shared()} })); setInMemoryMetadata(storage_metadata); } @@ -97,6 +100,7 @@ protected: continue; const auto indices = metadata_snapshot->getSecondaryIndices(); + auto secondary_index_sizes = table->getSecondaryIndexSizes(); for (const auto & index : indices) { ++rows_count; @@ -127,6 +131,21 @@ protected: // 'granularity' column if (column_mask[src_index++]) res_columns[res_index++]->insert(index.granularity); + + auto & secondary_index_size = secondary_index_sizes[index.name]; + + // 'compressed bytes' column + if (column_mask[src_index++]) + res_columns[res_index++]->insert(secondary_index_size.data_compressed); + + // 'uncompressed bytes' column + + if (column_mask[src_index++]) + res_columns[res_index++]->insert(secondary_index_size.data_uncompressed); + + /// 'marks' column + if (column_mask[src_index++]) + res_columns[res_index++]->insert(secondary_index_size.marks); } } } diff --git a/src/Storages/System/StorageSystemParts.cpp b/src/Storages/System/StorageSystemParts.cpp index e79978463dd..6826082ef1d 100644 --- a/src/Storages/System/StorageSystemParts.cpp +++ b/src/Storages/System/StorageSystemParts.cpp @@ -30,6 +30,9 @@ StorageSystemParts::StorageSystemParts(const StorageID & table_id_) {"data_compressed_bytes", std::make_shared()}, {"data_uncompressed_bytes", std::make_shared()}, {"marks_bytes", std::make_shared()}, + {"secondary_indices_compressed_bytes", std::make_shared()}, + {"secondary_indices_uncompressed_bytes", std::make_shared()}, + {"secondary_indices_marks_bytes", std::make_shared()}, {"modification_time", std::make_shared()}, {"remove_time", std::make_shared()}, {"refcount", std::make_shared()}, @@ -98,6 +101,7 @@ void StorageSystemParts::processNextStorage( auto part_state = all_parts_state[part_number]; ColumnSize columns_size = part->getTotalColumnsSize(); + ColumnSize secondary_indexes_size = part->getTotalSeconaryIndicesSize(); size_t src_index = 0, res_index = 0; if (columns_mask[src_index++]) @@ -126,6 +130,12 @@ void StorageSystemParts::processNextStorage( columns[res_index++]->insert(columns_size.data_uncompressed); if (columns_mask[src_index++]) columns[res_index++]->insert(columns_size.marks); + if (columns_mask[src_index++]) + columns[res_index++]->insert(secondary_indexes_size.data_compressed); + if (columns_mask[src_index++]) + columns[res_index++]->insert(secondary_indexes_size.data_uncompressed); + if (columns_mask[src_index++]) + columns[res_index++]->insert(secondary_indexes_size.marks); if (columns_mask[src_index++]) columns[res_index++]->insert(static_cast(part->modification_time)); From ce0c41e1ad6a025a0117e7486ff9fd9a511c5be5 Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Fri, 8 Oct 2021 23:43:16 +0300 Subject: [PATCH 176/264] Fixed tests --- src/Storages/MergeTree/MergeTreeData.cpp | 6 ------ ...1917_system_data_skipping_indices.reference | 10 +++++----- .../01932_alter_index_with_order.reference | 18 +++++++++--------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/Storages/MergeTree/MergeTreeData.cpp b/src/Storages/MergeTree/MergeTreeData.cpp index 10e5fe9e71f..1ede7669832 100644 --- a/src/Storages/MergeTree/MergeTreeData.cpp +++ b/src/Storages/MergeTree/MergeTreeData.cpp @@ -2975,8 +2975,6 @@ static void loadPartAndFixMetadataImpl(MergeTreeData::MutableDataPartPtr part) void MergeTreeData::calculateColumnAndSecondaryIndexSizesImpl() { - std::cerr << "MergeTreeData::calculateColumnAndSecondaryIndexSizesImpl" << std::endl; - column_sizes.clear(); /// Take into account only committed parts @@ -2987,13 +2985,9 @@ void MergeTreeData::calculateColumnAndSecondaryIndexSizesImpl() void MergeTreeData::addPartContributionToColumnAndSecondaryIndexSizes(const DataPartPtr & part) { - std::cerr << "MergeTreeData::addPartContributionToColumnAndSecondaryIndexSizes " << part->name << std::endl; - for (const auto & column : part->getColumns()) { - std::cerr << "Column name " << column.name << std::endl; ColumnSize & total_column_size = column_sizes[column.name]; - std::cerr << "Total column size compressed " << total_column_size.data_compressed << " uncompressed size " << total_column_size.data_uncompressed << std::endl; ColumnSize part_column_size = part->getColumnSize(column.name, *column.type); total_column_size.add(part_column_size); } diff --git a/tests/queries/0_stateless/01917_system_data_skipping_indices.reference b/tests/queries/0_stateless/01917_system_data_skipping_indices.reference index b5a4b596a97..ca7e87e017b 100644 --- a/tests/queries/0_stateless/01917_system_data_skipping_indices.reference +++ b/tests/queries/0_stateless/01917_system_data_skipping_indices.reference @@ -1,8 +1,8 @@ -default data_01917 d1_idx minmax d1 1 -default data_01917 d1_null_idx minmax assumeNotNull(d1_null) 1 -default data_01917_2 memory set frequency * length(name) 5 -default data_01917_2 sample_index1 minmax length(name), name 4 -default data_01917_2 sample_index2 ngrambf_v1 lower(name), name 4 +test data_01917 d1_idx minmax d1 1 0 0 0 +test data_01917 d1_null_idx minmax assumeNotNull(d1_null) 1 0 0 0 +test data_01917_2 memory set frequency * length(name) 5 0 0 0 +test data_01917_2 sample_index1 minmax length(name), name 4 0 0 0 +test data_01917_2 sample_index2 ngrambf_v1 lower(name), name 4 0 0 0 2 3 d1_idx diff --git a/tests/queries/0_stateless/01932_alter_index_with_order.reference b/tests/queries/0_stateless/01932_alter_index_with_order.reference index 07e1aab3df9..eff9ea7da0e 100644 --- a/tests/queries/0_stateless/01932_alter_index_with_order.reference +++ b/tests/queries/0_stateless/01932_alter_index_with_order.reference @@ -1,9 +1,9 @@ -default alter_index_test index_a set a 1 -default alter_index_test index_b minmax b 1 -default alter_index_test index_c set c 2 -default alter_index_test index_a set a 1 -default alter_index_test index_d set d 1 -default alter_index_test index_b minmax b 1 -default alter_index_test index_c set c 2 -default alter_index_test index_a set a 1 -default alter_index_test index_d set d 1 +default alter_index_test index_a set a 1 0 0 0 +default alter_index_test index_b minmax b 1 0 0 0 +default alter_index_test index_c set c 2 0 0 0 +default alter_index_test index_a set a 1 0 0 0 +default alter_index_test index_d set d 1 0 0 0 +default alter_index_test index_b minmax b 1 0 0 0 +default alter_index_test index_c set c 2 0 0 0 +default alter_index_test index_a set a 1 0 0 0 +default alter_index_test index_d set d 1 0 0 0 From 61a725f53199697451200a2d24e0173347f8b9e2 Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Sun, 10 Oct 2021 23:53:31 +0300 Subject: [PATCH 177/264] Fixed tests --- .../01917_system_data_skipping_indices.reference | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/queries/0_stateless/01917_system_data_skipping_indices.reference b/tests/queries/0_stateless/01917_system_data_skipping_indices.reference index ca7e87e017b..115d60f60cc 100644 --- a/tests/queries/0_stateless/01917_system_data_skipping_indices.reference +++ b/tests/queries/0_stateless/01917_system_data_skipping_indices.reference @@ -1,8 +1,8 @@ -test data_01917 d1_idx minmax d1 1 0 0 0 -test data_01917 d1_null_idx minmax assumeNotNull(d1_null) 1 0 0 0 -test data_01917_2 memory set frequency * length(name) 5 0 0 0 -test data_01917_2 sample_index1 minmax length(name), name 4 0 0 0 -test data_01917_2 sample_index2 ngrambf_v1 lower(name), name 4 0 0 0 +default data_01917 d1_idx minmax d1 1 0 0 0 +default data_01917 d1_null_idx minmax assumeNotNull(d1_null) 1 0 0 0 +default data_01917_2 memory set frequency * length(name) 5 0 0 0 +default data_01917_2 sample_index1 minmax length(name), name 4 0 0 0 +default data_01917_2 sample_index2 ngrambf_v1 lower(name), name 4 0 0 0 2 3 d1_idx From a07ce981214ab0f046afa23fb3f5551bc24a7270 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Mon, 11 Oct 2021 18:07:00 +0800 Subject: [PATCH 178/264] Use system.text_log in test --- .../01666_merge_tree_max_query_limit.sh | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh b/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh index 6fb337f2ca5..e04c9515009 100755 --- a/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh +++ b/tests/queries/0_stateless/01666_merge_tree_max_query_limit.sh @@ -4,8 +4,7 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck source=../shell_config.sh . "$CURDIR"/../shell_config.sh -function wait_for_query_to_start() -{ +function wait_for_query_to_start() { while [[ $($CLICKHOUSE_CURL -sS "$CLICKHOUSE_URL" -d "SELECT sum(read_rows) FROM system.processes WHERE query_id = '$1'") == 0 ]]; do sleep 0.1; done } @@ -21,14 +20,14 @@ insert into simple select number, number + 100 from numbers(5000); query_id="long_running_query-$CLICKHOUSE_DATABASE" echo "Spin up a long running query" -${CLICKHOUSE_CLIENT} --query "select sleepEachRow(0.1) from simple settings max_block_size = 1 format Null" --query_id "$query_id" > /dev/null 2>&1 & +${CLICKHOUSE_CLIENT} --query "select sleepEachRow(0.1) from simple settings max_block_size = 1 format Null" --query_id "$query_id" >/dev/null 2>&1 & wait_for_query_to_start "$query_id" # query which reads marks >= min_marks_to_honor_max_concurrent_queries is throttled echo "Check if another query with some marks to read is throttled" -${CLICKHOUSE_CLIENT} --query "select * from simple" 2> /dev/null; +${CLICKHOUSE_CLIENT} --query "select * from simple" 2>/dev/null CODE=$? -[ "$CODE" -ne "202" ] && echo "Expected error code: 202 but got: $CODE" && exit 1; +[ "$CODE" -ne "202" ] && echo "Expected error code: 202 but got: $CODE" && exit 1 echo "yes" # query which reads marks less than min_marks_to_honor_max_concurrent_queries is allowed @@ -41,9 +40,9 @@ ${CLICKHOUSE_CLIENT} --query "alter table simple modify setting min_marks_to_hon # Now smaller queries are also throttled echo "Check if another query with less marks to read is throttled" -${CLICKHOUSE_CLIENT} --query "select * from simple where i = 0" 2> /dev/null; +${CLICKHOUSE_CLIENT} --query "select * from simple where i = 0" 2>/dev/null CODE=$? -[ "$CODE" -ne "202" ] && echo "Expected error code: 202 but got: $CODE" && exit 1; +[ "$CODE" -ne "202" ] && echo "Expected error code: 202 but got: $CODE" && exit 1 echo "yes" echo "Modify max_concurrent_queries to 2" @@ -58,9 +57,9 @@ ${CLICKHOUSE_CLIENT} --query "alter table simple modify setting max_concurrent_q # Now queries are throttled again echo "Check if another query with less marks to read is throttled" -${CLICKHOUSE_CLIENT} --query "select * from simple where i = 0" 2> /dev/null; +${CLICKHOUSE_CLIENT} --query "select * from simple where i = 0" 2>/dev/null CODE=$? -[ "$CODE" -ne "202" ] && echo "Expected error code: 202 but got: $CODE" && exit 1; +[ "$CODE" -ne "202" ] && echo "Expected error code: 202 but got: $CODE" && exit 1 echo "yes" ${CLICKHOUSE_CLIENT} --query "KILL QUERY WHERE query_id = '$query_id' SYNC FORMAT Null" @@ -70,10 +69,9 @@ wait query_id=max_concurrent_queries_$RANDOM ${CLICKHOUSE_CLIENT} --query_id "$query_id" --query "select i from simple where j in (select i from simple where i < 10)" -# We have to grep the server's error log because the following warning message +# We have to search the server's error log because the following warning message # is generated during pipeline destruction and thus is not sent to the client. -grep -E -q "{$query_id} .*We have query_id removed but it's not recorded. This is a bug" /var/log/clickhouse-server/clickhouse-server.err.log && exit 1 +${CLICKHOUSE_CLIENT} --query "system flush logs" +if [[ $(${CLICKHOUSE_CLIENT} --query "select count() > 0 from system.text_log where query_id = '$query_id' and level = 'Warning' and message like '%We have query_id removed but it\'s not recorded. This is a bug%' format TSVRaw") == 1 ]]; then echo "We have query_id removed but it's not recorded. This is a bug." >&2; exit 1; fi -${CLICKHOUSE_CLIENT} --multiline --multiquery --query " -drop table simple -" +${CLICKHOUSE_CLIENT} --query "drop table simple" From 9ad919d91a8da739b1aa8a3d708b608f34dbf583 Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 11 Oct 2021 13:25:54 +0300 Subject: [PATCH 179/264] More timeouts in stress test --- docker/test/stress/stress | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/docker/test/stress/stress b/docker/test/stress/stress index 8fc4ade2da6..1559b084565 100755 --- a/docker/test/stress/stress +++ b/docker/test/stress/stress @@ -71,42 +71,42 @@ def prepare_for_hung_check(drop_databases): # FIXME this function should not exist, but... # ThreadFuzzer significantly slows down server and causes false-positive hung check failures - call("clickhouse client -q 'SYSTEM STOP THREAD FUZZER'", shell=True, stderr=STDOUT) + call("clickhouse client -q 'SYSTEM STOP THREAD FUZZER'", shell=True, stderr=STDOUT, timeout=30) # We attach gdb to clickhouse-server before running tests # to print stacktraces of all crashes even if clickhouse cannot print it for some reason. # However, it obstruct checking for hung queries. logging.info("Will terminate gdb (if any)") - call("kill -TERM $(pidof gdb)", shell=True, stderr=STDOUT) + call("kill -TERM $(pidof gdb)", shell=True, stderr=STDOUT, timeout=30) # Some tests set too low memory limit for default user and forget to reset in back. # It may cause SYSTEM queries to fail, let's disable memory limit. - call("clickhouse client --max_memory_usage_for_user=0 -q 'SELECT 1 FORMAT Null'", shell=True, stderr=STDOUT) + call("clickhouse client --max_memory_usage_for_user=0 -q 'SELECT 1 FORMAT Null'", shell=True, stderr=STDOUT, timeout=30) # Some tests execute SYSTEM STOP MERGES or similar queries. # It may cause some ALTERs to hang. # Possibly we should fix tests and forbid to use such queries without specifying table. - call("clickhouse client -q 'SYSTEM START MERGES'", shell=True, stderr=STDOUT) - call("clickhouse client -q 'SYSTEM START DISTRIBUTED SENDS'", shell=True, stderr=STDOUT) - call("clickhouse client -q 'SYSTEM START TTL MERGES'", shell=True, stderr=STDOUT) - call("clickhouse client -q 'SYSTEM START MOVES'", shell=True, stderr=STDOUT) - call("clickhouse client -q 'SYSTEM START FETCHES'", shell=True, stderr=STDOUT) - call("clickhouse client -q 'SYSTEM START REPLICATED SENDS'", shell=True, stderr=STDOUT) - call("clickhouse client -q 'SYSTEM START REPLICATION QUEUES'", shell=True, stderr=STDOUT) + call("clickhouse client -q 'SYSTEM START MERGES'", shell=True, stderr=STDOUT, timeout=30) + call("clickhouse client -q 'SYSTEM START DISTRIBUTED SENDS'", shell=True, stderr=STDOUT, timeout=30) + call("clickhouse client -q 'SYSTEM START TTL MERGES'", shell=True, stderr=STDOUT, timeout=30) + call("clickhouse client -q 'SYSTEM START MOVES'", shell=True, stderr=STDOUT, timeout=30) + call("clickhouse client -q 'SYSTEM START FETCHES'", shell=True, stderr=STDOUT, timeout=30) + call("clickhouse client -q 'SYSTEM START REPLICATED SENDS'", shell=True, stderr=STDOUT, timeout=30) + call("clickhouse client -q 'SYSTEM START REPLICATION QUEUES'", shell=True, stderr=STDOUT, timeout=30) # Issue #21004, live views are experimental, so let's just suppress it - call("""clickhouse client -q "KILL QUERY WHERE upper(query) LIKE 'WATCH %'" """, shell=True, stderr=STDOUT) + call("""clickhouse client -q "KILL QUERY WHERE upper(query) LIKE 'WATCH %'" """, shell=True, stderr=STDOUT, timeout=30) # Kill other queries which known to be slow # It's query from 01232_preparing_sets_race_condition_long, it may take up to 1000 seconds in slow builds - call("""clickhouse client -q "KILL QUERY WHERE query LIKE 'insert into tableB select %'" """, shell=True, stderr=STDOUT) + call("""clickhouse client -q "KILL QUERY WHERE query LIKE 'insert into tableB select %'" """, shell=True, stderr=STDOUT, timeout=30) # Long query from 00084_external_agregation - call("""clickhouse client -q "KILL QUERY WHERE query LIKE 'SELECT URL, uniq(SearchPhrase) AS u FROM test.hits GROUP BY URL ORDER BY u %'" """, shell=True, stderr=STDOUT) + call("""clickhouse client -q "KILL QUERY WHERE query LIKE 'SELECT URL, uniq(SearchPhrase) AS u FROM test.hits GROUP BY URL ORDER BY u %'" """, shell=True, stderr=STDOUT, timeout=30) if drop_databases: # Here we try to drop all databases in async mode. If some queries really hung, than drop will hung too. # Otherwise we will get rid of queries which wait for background pool. It can take a long time on slow builds (more than 900 seconds). - databases = check_output('clickhouse client -q "SHOW DATABASES"', shell=True).decode('utf-8').strip().split() + databases = check_output('clickhouse client -q "SHOW DATABASES"', shell=True, timeout=30).decode('utf-8').strip().split() for db in databases: if db == "system": continue @@ -117,13 +117,13 @@ def prepare_for_hung_check(drop_databases): # Wait for last queries to finish if any, not longer than 300 seconds call("""clickhouse client -q "select sleepEachRow(( select maxOrDefault(300 - elapsed) + 1 from system.processes where query not like '%from system.processes%' and elapsed < 300 - ) / 300) from numbers(300) format Null" """, shell=True, stderr=STDOUT) + ) / 300) from numbers(300) format Null" """, shell=True, stderr=STDOUT, timeout=30) # Even if all clickhouse-test processes are finished, there are probably some sh scripts, # which still run some new queries. Let's ignore them. try: query = """clickhouse client -q "SELECT count() FROM system.processes where where elapsed > 300" """ - output = check_output(query, shell=True, stderr=STDOUT).decode('utf-8').strip() + output = check_output(query, shell=True, stderr=STDOUT, timeout=30).decode('utf-8').strip() if int(output) == 0: return False except: @@ -176,6 +176,7 @@ if __name__ == "__main__": if res != 0 and have_long_running_queries: logging.info("Hung check failed with exit code {}".format(res)) hung_check_status = "Hung check failed\tFAIL\n" - open(os.path.join(args.output_folder, "test_results.tsv"), 'w+').write(hung_check_status) + with open(os.path.join(args.output_folder, "test_results.tsv"), 'w+') as results: + results.write(hung_check_status) logging.info("Stress test finished") From 83717b7c3b7e64ad752f53d2041bc8360e609715 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Wed, 29 Sep 2021 18:05:57 +0800 Subject: [PATCH 180/264] Get rid of naming limitation of projections. --- src/Storages/MergeTree/IMergeTreeDataPart.cpp | 8 ++++++-- src/Storages/MergeTree/MergeTask.cpp | 16 +++++++++++----- src/Storages/MergeTree/MergeTask.h | 6 +++--- .../MergeTree/MergeTreeDataMergerMutator.cpp | 4 ++-- .../MergeTree/MergeTreeDataMergerMutator.h | 2 +- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 4 +--- src/Storages/MergeTree/MergeTreeDataWriter.cpp | 2 +- src/Storages/MergeTree/MutateTask.cpp | 8 ++++---- src/Storages/MergeTree/checkDataPart.cpp | 8 +++++--- src/Storages/ProjectionsDescription.cpp | 17 +++++++---------- 10 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.cpp b/src/Storages/MergeTree/IMergeTreeDataPart.cpp index dc2c5f8185d..6ac53c68e84 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.cpp +++ b/src/Storages/MergeTree/IMergeTreeDataPart.cpp @@ -439,9 +439,13 @@ void IMergeTreeDataPart::removeIfNeeded() if (file_name.empty()) throw Exception("relative_path " + relative_path + " of part " + name + " is invalid or not set", ErrorCodes::LOGICAL_ERROR); - if (!startsWith(file_name, "tmp")) + if (!startsWith(file_name, "tmp") && !endsWith(file_name, ".tmp_proj")) { - LOG_ERROR(storage.log, "~DataPart() should remove part {} but its name doesn't start with tmp. Too suspicious, keeping the part.", path); + LOG_ERROR( + storage.log, + "~DataPart() should remove part {} but its name doesn't start with \"tmp\" or end with \".tmp_proj\". Too " + "suspicious, keeping the part.", + path); return; } } diff --git a/src/Storages/MergeTree/MergeTask.cpp b/src/Storages/MergeTree/MergeTask.cpp index 357659b3bbb..c6e8dafd8b0 100644 --- a/src/Storages/MergeTree/MergeTask.cpp +++ b/src/Storages/MergeTree/MergeTask.cpp @@ -89,7 +89,10 @@ static void extractMergingAndGatheringColumns( bool MergeTask::ExecuteAndFinalizeHorizontalPart::prepare() { - const String local_tmp_prefix = global_ctx->parent_part ? ctx->prefix : "tmp_merge_"; + // projection parts have different prefix and suffix compared to normal parts. + // E.g. `proj_a.proj` for a normal projection merge and `proj_a.tmp_proj` for a projection materialization merge. + const String local_tmp_prefix = global_ctx->parent_part ? "" : "tmp_merge_"; + const String local_tmp_suffix = global_ctx->parent_part ? ctx->suffix : ""; if (global_ctx->merges_blocker->isCancelled()) throw Exception("Cancelled merging parts", ErrorCodes::ABORTED); @@ -114,7 +117,8 @@ bool MergeTask::ExecuteAndFinalizeHorizontalPart::prepare() } ctx->disk = global_ctx->space_reservation->getDisk(); - auto local_new_part_tmp_path = global_ctx->data->relative_data_path + local_tmp_prefix + global_ctx->future_part->name + (global_ctx->parent_part ? ".proj" : "") + "/"; + auto local_new_part_relative_tmp_path = local_tmp_prefix + global_ctx->future_part->name + local_tmp_suffix + "/"; + auto local_new_part_tmp_path = global_ctx->data->relative_data_path + local_new_part_relative_tmp_path; if (ctx->disk->exists(local_new_part_tmp_path)) throw Exception("Directory " + fullPath(ctx->disk, local_new_part_tmp_path) + " already exists", ErrorCodes::DIRECTORY_ALREADY_EXISTS); @@ -138,7 +142,7 @@ bool MergeTask::ExecuteAndFinalizeHorizontalPart::prepare() global_ctx->future_part->type, global_ctx->future_part->part_info, local_single_disk_volume, - local_tmp_prefix + global_ctx->future_part->name + (global_ctx->parent_part ? ".proj" : ""), + local_new_part_relative_tmp_path, global_ctx->parent_part); global_ctx->new_data_part->uuid = global_ctx->future_part->uuid; @@ -526,7 +530,9 @@ bool MergeTask::MergeProjectionsStage::mergeMinMaxIndexAndPrepareProjections() c auto projection_future_part = std::make_shared(); projection_future_part->assign(std::move(projection_parts)); projection_future_part->name = projection.name; - projection_future_part->path = global_ctx->future_part->path + "/" + projection.name + ".proj/"; + // TODO (ab): path in future_part is only for merge process introspection, which is not available for merges of projection parts. + // Let's comment this out to avoid code inconsistency and add it back after we implement projection merge introspection. + // projection_future_part->path = global_ctx->future_part->path + "/" + projection.name + ".proj/"; projection_future_part->part_info = {"all", 0, 0, 0}; MergeTreeData::MergingParams projection_merging_params; @@ -553,7 +559,7 @@ bool MergeTask::MergeProjectionsStage::mergeMinMaxIndexAndPrepareProjections() c global_ctx->deduplicate_by_columns, projection_merging_params, global_ctx->new_data_part.get(), - "", // empty string for projection + ".proj", global_ctx->data, global_ctx->merges_blocker, global_ctx->ttl_merges_blocker)); diff --git a/src/Storages/MergeTree/MergeTask.h b/src/Storages/MergeTree/MergeTask.h index 05903f94c91..22dc70bd78c 100644 --- a/src/Storages/MergeTree/MergeTask.h +++ b/src/Storages/MergeTree/MergeTask.h @@ -58,7 +58,7 @@ public: Names deduplicate_by_columns_, MergeTreeData::MergingParams merging_params_, const IMergeTreeDataPart * parent_part_, - String prefix_, + String suffix_, MergeTreeData * data_, ActionBlocker * merges_blocker_, ActionBlocker * ttl_merges_blocker_) @@ -83,7 +83,7 @@ public: auto prepare_stage_ctx = std::make_shared(); - prepare_stage_ctx->prefix = std::move(prefix_); + prepare_stage_ctx->suffix = std::move(suffix_); prepare_stage_ctx->merging_params = std::move(merging_params_); (*stages.begin())->setRuntimeContext(std::move(prepare_stage_ctx), global_ctx); @@ -170,7 +170,7 @@ private: struct ExecuteAndFinalizeHorizontalPartRuntimeContext : public IStageRuntimeContext //-V730 { /// Dependencies - String prefix; + String suffix; MergeTreeData::MergingParams merging_params{}; DiskPtr tmp_disk{nullptr}; diff --git a/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index 903f4cd27fc..5d97c64b49b 100644 --- a/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -428,7 +428,7 @@ MergeTaskPtr MergeTreeDataMergerMutator::mergePartsToTemporaryPart( const Names & deduplicate_by_columns, const MergeTreeData::MergingParams & merging_params, const IMergeTreeDataPart * parent_part, - const String & prefix) + const String & suffix) { return std::make_shared( future_part, @@ -442,7 +442,7 @@ MergeTaskPtr MergeTreeDataMergerMutator::mergePartsToTemporaryPart( deduplicate_by_columns, merging_params, parent_part, - prefix, + suffix, &data, &merges_blocker, &ttl_merges_blocker); diff --git a/src/Storages/MergeTree/MergeTreeDataMergerMutator.h b/src/Storages/MergeTree/MergeTreeDataMergerMutator.h index 9eb91d7fbf8..22650ac4eca 100644 --- a/src/Storages/MergeTree/MergeTreeDataMergerMutator.h +++ b/src/Storages/MergeTree/MergeTreeDataMergerMutator.h @@ -108,7 +108,7 @@ public: const Names & deduplicate_by_columns, const MergeTreeData::MergingParams & merging_params, const IMergeTreeDataPart * parent_part = nullptr, - const String & prefix = ""); + const String & suffix = ""); /// Mutate a single data part with the specified commands. Will create and return a temporary part. MutateTaskPtr mutatePartToTemporaryPart( diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 03d76a7f79b..77a91af037e 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -173,9 +173,7 @@ QueryPlanPtr MergeTreeDataSelectExecutor::read( auto projection_plan = std::make_unique(); if (query_info.projection->desc->is_minmax_count_projection) { - Pipe pipe(std::make_shared( - query_info.minmax_count_projection_block.cloneEmpty(), - Chunk(query_info.minmax_count_projection_block.getColumns(), query_info.minmax_count_projection_block.rows()))); + Pipe pipe(std::make_shared(query_info.minmax_count_projection_block)); auto read_from_pipe = std::make_unique(std::move(pipe)); projection_plan->addStep(std::move(read_from_pipe)); } diff --git a/src/Storages/MergeTree/MergeTreeDataWriter.cpp b/src/Storages/MergeTree/MergeTreeDataWriter.cpp index d939312c0bb..752f85a1290 100644 --- a/src/Storages/MergeTree/MergeTreeDataWriter.cpp +++ b/src/Storages/MergeTree/MergeTreeDataWriter.cpp @@ -575,7 +575,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataWriter::writeTempProjectionPart( return writeProjectionPartImpl( part_name, part_type, - "tmp_insert_" + part_name + ".proj" /* relative_path */, + part_name + ".tmp_proj" /* relative_path */, true /* is_temp */, parent_part, data, diff --git a/src/Storages/MergeTree/MutateTask.cpp b/src/Storages/MergeTree/MutateTask.cpp index b8941fc9d84..fbc2f58d424 100644 --- a/src/Storages/MergeTree/MutateTask.cpp +++ b/src/Storages/MergeTree/MutateTask.cpp @@ -654,7 +654,7 @@ public: {}, projection_merging_params, ctx->new_data_part.get(), - "tmp_merge_"); + ".tmp_proj"); next_level_parts.push_back(executeHere(tmp_part_merge_task)); @@ -832,8 +832,8 @@ bool PartMergerWriter::mutateOriginalPartAndPrepareProjections() auto projection_block = projection_squash.add({}); if (projection_block) { - projection_parts[projection.name].emplace_back( - MergeTreeDataWriter::writeTempProjectionPart(*ctx->data, ctx->log, projection_block, projection, ctx->new_data_part.get(), ++block_num)); + projection_parts[projection.name].emplace_back(MergeTreeDataWriter::writeTempProjectionPart( + *ctx->data, ctx->log, projection_block, projection, ctx->new_data_part.get(), ++block_num)); } } @@ -1082,7 +1082,7 @@ private: if (!ctx->disk->isDirectory(it->path())) ctx->disk->createHardLink(it->path(), destination); - else if (!startsWith("tmp_", it->name())) // ignore projection tmp merge dir + else if (!endsWith(".tmp_proj", it->name())) // ignore projection tmp merge dir { // it's a projection part directory ctx->disk->createDirectories(destination); diff --git a/src/Storages/MergeTree/checkDataPart.cpp b/src/Storages/MergeTree/checkDataPart.cpp index 8a234833da7..0af395fd1bd 100644 --- a/src/Storages/MergeTree/checkDataPart.cpp +++ b/src/Storages/MergeTree/checkDataPart.cpp @@ -102,7 +102,7 @@ IMergeTreeDataPart::Checksums checkDataPart( /// It also calculates checksum of projections. auto checksum_file = [&](const String & file_path, const String & file_name) { - if (disk->isDirectory(file_path) && endsWith(file_name, ".proj") && !startsWith(file_name, "tmp_")) // ignore projection tmp merge dir + if (disk->isDirectory(file_path) && endsWith(file_name, ".proj")) { auto projection_name = file_name.substr(0, file_name.size() - sizeof(".proj") + 1); auto pit = data_part->getProjectionParts().find(projection_name); @@ -124,7 +124,8 @@ IMergeTreeDataPart::Checksums checkDataPart( auto file_buf = disk->readFile(proj_path); HashingReadBuffer hashing_buf(*file_buf); hashing_buf.ignoreAll(); - projection_checksums_data.files[MergeTreeDataPartCompact::DATA_FILE_NAME_WITH_EXTENSION] = IMergeTreeDataPart::Checksums::Checksum(hashing_buf.count(), hashing_buf.getHash()); + projection_checksums_data.files[MergeTreeDataPartCompact::DATA_FILE_NAME_WITH_EXTENSION] + = IMergeTreeDataPart::Checksums::Checksum(hashing_buf.count(), hashing_buf.getHash()); } else { @@ -140,7 +141,8 @@ IMergeTreeDataPart::Checksums checkDataPart( [&](const ISerialization::SubstreamPath & substream_path) { String projection_file_name = ISerialization::getFileNameForStream(projection_column, substream_path) + ".bin"; - checksums_data.files[projection_file_name] = checksum_compressed_file(disk, projection_path + projection_file_name); + checksums_data.files[projection_file_name] + = checksum_compressed_file(disk, projection_path + projection_file_name); }, {}); } diff --git a/src/Storages/ProjectionsDescription.cpp b/src/Storages/ProjectionsDescription.cpp index c0b96bd9f54..42294b8152c 100644 --- a/src/Storages/ProjectionsDescription.cpp +++ b/src/Storages/ProjectionsDescription.cpp @@ -89,9 +89,6 @@ ProjectionDescription::getProjectionFromAST(const ASTPtr & definition_ast, const if (projection_definition->name.empty()) throw Exception("Projection must have name in definition.", ErrorCodes::INCORRECT_QUERY); - if (startsWith(projection_definition->name, "tmp_")) - throw Exception("Projection's name cannot start with 'tmp_'", ErrorCodes::INCORRECT_QUERY); - if (!projection_definition->query) throw Exception("QUERY is required for projection", ErrorCodes::INCORRECT_QUERY); @@ -220,13 +217,13 @@ void ProjectionDescription::recalculateWithNewColumns(const ColumnsDescription & Block ProjectionDescription::calculate(const Block & block, ContextPtr context) const { auto builder = InterpreterSelectQuery( - query_ast, - context, - Pipe(std::make_shared(block, Chunk(block.getColumns(), block.rows()))), - SelectQueryOptions{ - type == ProjectionDescription::Type::Normal ? QueryProcessingStage::FetchColumns - : QueryProcessingStage::WithMergeableState}) - .buildQueryPipeline(); + query_ast, + context, + Pipe(std::make_shared(block, Chunk(block.getColumns(), block.rows()))), + SelectQueryOptions{ + type == ProjectionDescription::Type::Normal ? QueryProcessingStage::FetchColumns + : QueryProcessingStage::WithMergeableState}) + .buildQueryPipeline(); builder.resize(1); builder.addTransform(std::make_shared(builder.getHeader(), block.rows(), 0)); From b0d887a0fef89fb529cff4f7c02cfab8cf75c280 Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Mon, 11 Oct 2021 14:00:10 +0300 Subject: [PATCH 181/264] Added tests --- src/Storages/MergeTree/IMergeTreeDataPart.cpp | 1 + ...28_system_data_skipping_indices_size.reference | 1 + .../2028_system_data_skipping_indices_size.sql | 15 +++++++++++++++ 3 files changed, 17 insertions(+) create mode 100644 tests/queries/0_stateless/2028_system_data_skipping_indices_size.reference create mode 100644 tests/queries/0_stateless/2028_system_data_skipping_indices_size.sql diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.cpp b/src/Storages/MergeTree/IMergeTreeDataPart.cpp index 1a6290580a0..0f701cc4adf 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.cpp +++ b/src/Storages/MergeTree/IMergeTreeDataPart.cpp @@ -1452,6 +1452,7 @@ void IMergeTreeDataPart::calculateSecondaryIndicesSizesOnDisk() auto index_file_name = index_name_escaped + index_ptr->getSerializedFileExtension(); auto index_marks_file_name = index_name_escaped + index_granularity_info.marks_file_extension; + /// If part does not contain index auto bin_checksum = checksums.files.find(index_file_name); if (bin_checksum != checksums.files.end()) { diff --git a/tests/queries/0_stateless/2028_system_data_skipping_indices_size.reference b/tests/queries/0_stateless/2028_system_data_skipping_indices_size.reference new file mode 100644 index 00000000000..d0378511850 --- /dev/null +++ b/tests/queries/0_stateless/2028_system_data_skipping_indices_size.reference @@ -0,0 +1 @@ +default test_table value_index minmax value 1 38 12 24 diff --git a/tests/queries/0_stateless/2028_system_data_skipping_indices_size.sql b/tests/queries/0_stateless/2028_system_data_skipping_indices_size.sql new file mode 100644 index 00000000000..e77f88aa36f --- /dev/null +++ b/tests/queries/0_stateless/2028_system_data_skipping_indices_size.sql @@ -0,0 +1,15 @@ +DROP TABLE IF EXISTS test_table; + +CREATE TABLE test_table +( + key UInt64, + value String, + INDEX value_index value TYPE minmax GRANULARITY 1 +) +Engine=MergeTree() +ORDER BY key; + +INSERT INTO test_table VALUES (0, 'Value'); +SELECT * FROM system.data_skipping_indices WHERE database = currentDatabase(); + +DROP TABLE test_table; From 95a69b9f4b6478f902c7a970296a8c5b2c193a9c Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 11 Oct 2021 14:05:52 +0300 Subject: [PATCH 182/264] Make test non endless --- .../01509_check_many_parallel_quorum_inserts_long.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/queries/0_stateless/01509_check_many_parallel_quorum_inserts_long.sh b/tests/queries/0_stateless/01509_check_many_parallel_quorum_inserts_long.sh index c2682cd8cfa..6533eeb12f5 100755 --- a/tests/queries/0_stateless/01509_check_many_parallel_quorum_inserts_long.sh +++ b/tests/queries/0_stateless/01509_check_many_parallel_quorum_inserts_long.sh @@ -18,9 +18,10 @@ for i in $(seq 1 $NUM_REPLICAS); do done function thread { - while true - do + i=0 retries=300 + while [[ $i -lt $retries ]]; do # server can be dead $CLICKHOUSE_CLIENT --insert_quorum 5 --insert_quorum_parallel 1 --query "INSERT INTO r$1 SELECT $2" && break + ((++i)) sleep 0.1 done } From 72bccaa50141cd1206d1d064bc2d767a68cb9f99 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Mon, 11 Oct 2021 19:12:08 +0800 Subject: [PATCH 183/264] Fix path name --- src/Storages/MergeTree/IMergeTreeDataPart.h | 1 + src/Storages/MergeTree/MergeTask.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.h b/src/Storages/MergeTree/IMergeTreeDataPart.h index be48aed5c8b..b74b2ca3321 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.h +++ b/src/Storages/MergeTree/IMergeTreeDataPart.h @@ -175,6 +175,7 @@ public: /// A directory path (relative to storage's path) where part data is actually stored /// Examples: 'detached/tmp_fetch_', 'tmp_', '' + /// NOTE: Cannot have trailing slash. mutable String relative_path; MergeTreeIndexGranularityInfo index_granularity_info; diff --git a/src/Storages/MergeTree/MergeTask.cpp b/src/Storages/MergeTree/MergeTask.cpp index c6e8dafd8b0..aa3f91a4f00 100644 --- a/src/Storages/MergeTree/MergeTask.cpp +++ b/src/Storages/MergeTree/MergeTask.cpp @@ -117,8 +117,8 @@ bool MergeTask::ExecuteAndFinalizeHorizontalPart::prepare() } ctx->disk = global_ctx->space_reservation->getDisk(); - auto local_new_part_relative_tmp_path = local_tmp_prefix + global_ctx->future_part->name + local_tmp_suffix + "/"; - auto local_new_part_tmp_path = global_ctx->data->relative_data_path + local_new_part_relative_tmp_path; + auto local_new_part_relative_tmp_path_name = local_tmp_prefix + global_ctx->future_part->name + local_tmp_suffix; + auto local_new_part_tmp_path = global_ctx->data->relative_data_path + local_new_part_relative_tmp_path_name + "/"; if (ctx->disk->exists(local_new_part_tmp_path)) throw Exception("Directory " + fullPath(ctx->disk, local_new_part_tmp_path) + " already exists", ErrorCodes::DIRECTORY_ALREADY_EXISTS); @@ -142,7 +142,7 @@ bool MergeTask::ExecuteAndFinalizeHorizontalPart::prepare() global_ctx->future_part->type, global_ctx->future_part->part_info, local_single_disk_volume, - local_new_part_relative_tmp_path, + local_new_part_relative_tmp_path_name, global_ctx->parent_part); global_ctx->new_data_part->uuid = global_ctx->future_part->uuid; From 2370a8d6dabd9b7fdd2aaa4571b123053c60d835 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 14:28:46 +0300 Subject: [PATCH 184/264] Fix PVS-Studio --- src/Common/JSONBuilder.h | 2 +- src/Dictionaries/HTTPDictionarySource.cpp | 2 +- src/Functions/FunctionsBinaryRepr.cpp | 4 ++-- src/Functions/FunctionsMiscellaneous.h | 2 +- .../ExternalUserDefinedExecutableFunctionsLoader.cpp | 10 +++++----- src/Storages/Kafka/KafkaSource.cpp | 2 +- src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Common/JSONBuilder.h b/src/Common/JSONBuilder.h index 12a2b129645..b1a1ec4ae6a 100644 --- a/src/Common/JSONBuilder.h +++ b/src/Common/JSONBuilder.h @@ -94,7 +94,7 @@ class JSONMap : public IItem }; public: - void add(std::string key, ItemPtr value) { values.emplace_back(Pair{.key = std::move(key), .value = std::move(value)}); } + void add(std::string key, ItemPtr value) { values.emplace_back(Pair{.key = std::move(key), .value = std::move(value)}); } //-V1030 void add(std::string key, std::string value) { add(std::move(key), std::make_unique(std::move(value))); } void add(std::string key, const char * value) { add(std::move(key), std::make_unique(value)); } void add(std::string key, std::string_view value) { add(std::move(key), std::make_unique(value)); } diff --git a/src/Dictionaries/HTTPDictionarySource.cpp b/src/Dictionaries/HTTPDictionarySource.cpp index d6a0c25e9f1..95e816ee45a 100644 --- a/src/Dictionaries/HTTPDictionarySource.cpp +++ b/src/Dictionaries/HTTPDictionarySource.cpp @@ -254,7 +254,7 @@ void registerDictionarySourceHTTP(DictionarySourceFactory & factory) .format =config.getString(settings_config_prefix + ".format", ""), .update_field = config.getString(settings_config_prefix + ".update_field", ""), .update_lag = config.getUInt64(settings_config_prefix + ".update_lag", 1), - .header_entries = std::move(header_entries) + .header_entries = std::move(header_entries) //-V1030 }; return std::make_unique(dict_struct, configuration, credentials, sample_block, context, created_from_ddl); diff --git a/src/Functions/FunctionsBinaryRepr.cpp b/src/Functions/FunctionsBinaryRepr.cpp index 7f0835d8edf..20b2acac88a 100644 --- a/src/Functions/FunctionsBinaryRepr.cpp +++ b/src/Functions/FunctionsBinaryRepr.cpp @@ -50,7 +50,7 @@ struct HexImpl UInt8 byte = x >> offset; /// Skip leading zeros - if (byte == 0 && !was_nonzero && offset) + if (byte == 0 && !was_nonzero && offset) //-V560 continue; was_nonzero = true; @@ -138,7 +138,7 @@ struct BinImpl UInt8 byte = x >> offset; /// Skip leading zeros - if (byte == 0 && !was_nonzero && offset) + if (byte == 0 && !was_nonzero && offset) //-V560 continue; was_nonzero = true; diff --git a/src/Functions/FunctionsMiscellaneous.h b/src/Functions/FunctionsMiscellaneous.h index 32700cb692e..7e8cab842c8 100644 --- a/src/Functions/FunctionsMiscellaneous.h +++ b/src/Functions/FunctionsMiscellaneous.h @@ -238,7 +238,7 @@ public: capture = std::make_shared(Capture{ .captured_names = captured_names_, - .captured_types = std::move(captured_types), + .captured_types = std::move(captured_types), //-V1030 .lambda_arguments = lambda_arguments_, .return_name = expression_return_name_, .return_type = function_return_type_, diff --git a/src/Interpreters/ExternalUserDefinedExecutableFunctionsLoader.cpp b/src/Interpreters/ExternalUserDefinedExecutableFunctionsLoader.cpp index f8d2c0a86ef..2de7b4b7846 100644 --- a/src/Interpreters/ExternalUserDefinedExecutableFunctionsLoader.cpp +++ b/src/Interpreters/ExternalUserDefinedExecutableFunctionsLoader.cpp @@ -107,11 +107,11 @@ ExternalLoader::LoadablePtr ExternalUserDefinedExecutableFunctionsLoader::create UserDefinedExecutableFunctionConfiguration function_configuration { .type = function_type, - .name = std::move(name), - .script_path = std::move(command), - .format = std::move(format), - .argument_types = std::move(argument_types), - .result_type = std::move(result_type), + .name = std::move(name), //-V1030 + .script_path = std::move(command), //-V1030 + .format = std::move(format), //-V1030 + .argument_types = std::move(argument_types), //-V1030 + .result_type = std::move(result_type), //-V1030 .pool_size = pool_size, .command_termination_timeout = command_termination_timeout, .max_command_execution_time = max_command_execution_time, diff --git a/src/Storages/Kafka/KafkaSource.cpp b/src/Storages/Kafka/KafkaSource.cpp index 68fc17a97e5..ad48858b658 100644 --- a/src/Storages/Kafka/KafkaSource.cpp +++ b/src/Storages/Kafka/KafkaSource.cpp @@ -67,7 +67,7 @@ Chunk KafkaSource::generateImpl() broken = true; } - if (!buffer || is_finished) + if (is_finished) return {}; is_finished = true; diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 03d76a7f79b..88b0878bb74 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -983,7 +983,7 @@ RangesInDataParts MergeTreeDataSelectExecutor::filterPartsByPrimaryKeyAndSkipInd index_stats.emplace_back(ReadFromMergeTree::IndexStat{ .type = ReadFromMergeTree::IndexType::Skip, .name = index_name, - .description = std::move(description), + .description = std::move(description), //-V1030 .num_parts_after = index_and_condition.total_parts - index_and_condition.parts_dropped, .num_granules_after = index_and_condition.total_granules - index_and_condition.granules_dropped}); } From e0a4fb31a9b37d78ef61c38816d9b38fc51ff48d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 14:34:05 +0300 Subject: [PATCH 185/264] Update submodules to simplify cross build --- contrib/grpc | 2 +- contrib/llvm | 2 +- contrib/protobuf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/grpc b/contrib/grpc index 60c986e15ca..7eac189a6ba 160000 --- a/contrib/grpc +++ b/contrib/grpc @@ -1 +1 @@ -Subproject commit 60c986e15cae70aade721d26badabab1f822fdd6 +Subproject commit 7eac189a6badddac593580ec2ad1478bd2656fc7 diff --git a/contrib/llvm b/contrib/llvm index f30bbecef78..20607e61728 160000 --- a/contrib/llvm +++ b/contrib/llvm @@ -1 +1 @@ -Subproject commit f30bbecef78b75b527e257c1304d0be2f2f95975 +Subproject commit 20607e61728e97c969e536644c3c0c1bb1a50672 diff --git a/contrib/protobuf b/contrib/protobuf index 75601841d17..c1c5d020260 160000 --- a/contrib/protobuf +++ b/contrib/protobuf @@ -1 +1 @@ -Subproject commit 75601841d172c73ae6bf4ce8121f42b875cdbabd +Subproject commit c1c5d02026059f4c3cb51aaa08e82288d3e08b89 From e24be8dfb0461b02fb48fbab458f4c71d5e62a8a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 11 Oct 2021 14:41:49 +0300 Subject: [PATCH 186/264] Update submodule --- contrib/sysroot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/sysroot b/contrib/sysroot index bb46f9d9237..611d3315e9e 160000 --- a/contrib/sysroot +++ b/contrib/sysroot @@ -1 +1 @@ -Subproject commit bb46f9d92379def88cb1376ee3852ee60913ef83 +Subproject commit 611d3315e9e369a338de4ffa128eb87b4fb87dec From 59a78830f9b73f9ff366449874047828019ad58e Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 11 Oct 2021 14:46:01 +0300 Subject: [PATCH 187/264] Better timeouts in clickhouse-test --- tests/clickhouse-test | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/clickhouse-test b/tests/clickhouse-test index f10e38b87e5..061333297e2 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -89,10 +89,13 @@ def make_clickhouse_client(base_args): # hence we should use 'system'. database='system', settings=get_additional_client_options_dict(base_args)) + def clickhouse_execute_one(base_args, *args, **kwargs): return make_clickhouse_client(base_args).execute_one(*args, **kwargs) + def clickhouse_execute(base_args, *args, **kwargs): return make_clickhouse_client(base_args).execute(*args, **kwargs) + def clickhouse_execute_pandas(base_args, *args, **kwargs): return make_clickhouse_client(base_args).execute_pandas(*args, **kwargs) @@ -109,6 +112,7 @@ def stop_tests(): global restarted_tests with stop_tests_triggered_lock: + print("Stopping tests") if not stop_tests_triggered.is_set(): stop_tests_triggered.set() @@ -875,7 +879,7 @@ def run_tests_array(all_tests_with_params): while True: if is_concurrent: - case = queue.get() + case = queue.get(timeout=args.timeout) if not case: break else: @@ -1076,10 +1080,10 @@ def do_run_tests(jobs, test_suite: TestSuite, parallel): pool.map_async(run_tests_array, parallel_tests_array) for suit in test_suite.parallel_tests: - queue.put(suit) + queue.put(suit, timeout=args.timeout) for _ in range(jobs): - queue.put(None) + queue.put(None, timeout=args.timeout) queue.close() From 0ca8660af60cc94697fb9b8a8d7c227d0c399cbd Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 11 Oct 2021 14:52:31 +0300 Subject: [PATCH 188/264] Update build-cross-arm.md --- docs/en/development/build-cross-arm.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/docs/en/development/build-cross-arm.md b/docs/en/development/build-cross-arm.md index 7c2b002d638..2b3f976783c 100644 --- a/docs/en/development/build-cross-arm.md +++ b/docs/en/development/build-cross-arm.md @@ -9,16 +9,9 @@ This is for the case when you have Linux machine and want to use it to build `cl The cross-build for AARCH64 is based on the [Build instructions](../development/build.md), follow them first. -## Install Clang-8 {#install-clang-8} +## Install Clang-13 Follow the instructions from https://apt.llvm.org/ for your Ubuntu or Debian setup. -For example, in Ubuntu Bionic you can use the following commands: - -``` bash -echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main" | sudo tee /etc/apt/sources.list.d/llvm.list -sudo apt-get update -sudo apt-get install clang-8 -``` ## Install Cross-Compilation Toolset {#install-cross-compilation-toolset} From 467b45f3b5de51233b6adac2de11222975bb9677 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 11 Oct 2021 14:52:44 +0300 Subject: [PATCH 189/264] Update build-cross-arm.md --- docs/en/development/build-cross-arm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/development/build-cross-arm.md b/docs/en/development/build-cross-arm.md index 2b3f976783c..e4d0c170ff6 100644 --- a/docs/en/development/build-cross-arm.md +++ b/docs/en/development/build-cross-arm.md @@ -27,7 +27,7 @@ tar xJf gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz -C build-aarch64/cma ``` bash cd ClickHouse mkdir build-arm64 -CC=clang-8 CXX=clang++-8 cmake . -Bbuild-arm64 -DCMAKE_TOOLCHAIN_FILE=cmake/linux/toolchain-aarch64.cmake +CC=clang-13 CXX=clang++-13 cmake . -Bbuild-arm64 -DCMAKE_TOOLCHAIN_FILE=cmake/linux/toolchain-aarch64.cmake ninja -C build-arm64 ``` From f2d97e322589bdc92df7c910068fb0ad08aa8ad9 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 11 Oct 2021 14:53:12 +0300 Subject: [PATCH 190/264] Update build-cross-arm.md --- docs/en/development/build-cross-arm.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/en/development/build-cross-arm.md b/docs/en/development/build-cross-arm.md index e4d0c170ff6..eb99105a857 100644 --- a/docs/en/development/build-cross-arm.md +++ b/docs/en/development/build-cross-arm.md @@ -11,7 +11,10 @@ The cross-build for AARCH64 is based on the [Build instructions](../development/ ## Install Clang-13 -Follow the instructions from https://apt.llvm.org/ for your Ubuntu or Debian setup. +Follow the instructions from https://apt.llvm.org/ for your Ubuntu or Debian setup or do +``` +sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" +``` ## Install Cross-Compilation Toolset {#install-cross-compilation-toolset} From f4269ce41750648e3be629b08ce73e38afa273ae Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Wed, 8 Sep 2021 20:10:49 +0800 Subject: [PATCH 191/264] Allow optimize_arithmetic_operations_in_aggregate_functions when alias is used. --- .../ArithmeticOperationsInAgrFuncOptimize.cpp | 12 +++++++----- ...etic_operations_in_aggr_func_with_alias.reference | 10 ++++++++++ ...arithmetic_operations_in_aggr_func_with_alias.sql | 4 ++++ .../0_stateless/01470_columns_transformers.reference | 4 ++-- 4 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.reference create mode 100644 tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.sql diff --git a/src/Interpreters/ArithmeticOperationsInAgrFuncOptimize.cpp b/src/Interpreters/ArithmeticOperationsInAgrFuncOptimize.cpp index bdd9ce32707..70a58971d3f 100644 --- a/src/Interpreters/ArithmeticOperationsInAgrFuncOptimize.cpp +++ b/src/Interpreters/ArithmeticOperationsInAgrFuncOptimize.cpp @@ -107,10 +107,7 @@ ASTPtr tryExchangeFunctions(const ASTFunction & func) || !supported.find(lower_name)->second.count(child_func->name)) return {}; - /// Cannot rewrite function with alias cause alias could become undefined - if (!func.tryGetAlias().empty() || !child_func->tryGetAlias().empty()) - return {}; - + auto original_alias = func.tryGetAlias(); const auto & child_func_args = child_func->arguments->children; const auto * first_literal = child_func_args[0]->as(); const auto * second_literal = child_func_args[1]->as(); @@ -132,7 +129,12 @@ ASTPtr tryExchangeFunctions(const ASTFunction & func) optimized_ast = exchangeExtractSecondArgument(new_name, *child_func); } - return optimized_ast; + if (optimized_ast) + { + optimized_ast->setAlias(original_alias); + return optimized_ast; + } + return {}; } } diff --git a/tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.reference b/tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.reference new file mode 100644 index 00000000000..9e0d871041b --- /dev/null +++ b/tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.reference @@ -0,0 +1,10 @@ +SELECT min(n AS a) + (1 AS b) AS c +FROM +( + SELECT number AS n + FROM numbers(10) + WHERE (1 > 0) AND (n > 0) +) +WHERE (a > 0) AND (b > 0) +HAVING c > 0 +2 diff --git a/tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.sql b/tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.sql new file mode 100644 index 00000000000..73b87817bb3 --- /dev/null +++ b/tests/queries/0_stateless/01271_optimize_arithmetic_operations_in_aggr_func_with_alias.sql @@ -0,0 +1,4 @@ +set optimize_arithmetic_operations_in_aggregate_functions = 1; + +explain syntax select min((n as a) + (1 as b)) c from (select number n from numbers(10)) where a > 0 and b > 0 having c > 0; +select min((n as a) + (1 as b)) c from (select number n from numbers(10)) where a > 0 and b > 0 having c > 0; diff --git a/tests/queries/0_stateless/01470_columns_transformers.reference b/tests/queries/0_stateless/01470_columns_transformers.reference index ae0adb3ba60..8fa86582018 100644 --- a/tests/queries/0_stateless/01470_columns_transformers.reference +++ b/tests/queries/0_stateless/01470_columns_transformers.reference @@ -54,8 +54,8 @@ SELECT sum(k) FROM columns_transformers SELECT - avg(i + 1 AS i), - avg(j + 2 AS j), + avg(i) + 1, + avg(j) + 2, avg(k) FROM columns_transformers SELECT From 635783fb663267180f25e92637b7915399b884b6 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Fri, 24 Sep 2021 00:23:17 +0800 Subject: [PATCH 192/264] Only do TreeOptimizer for initial queries --- src/Interpreters/TreeOptimizer.cpp | 4 ---- src/Interpreters/TreeRewriter.cpp | 8 +++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Interpreters/TreeOptimizer.cpp b/src/Interpreters/TreeOptimizer.cpp index 3236418fe6f..8fb72f74c65 100644 --- a/src/Interpreters/TreeOptimizer.cpp +++ b/src/Interpreters/TreeOptimizer.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include @@ -710,9 +709,6 @@ void TreeOptimizer::apply(ASTPtr & query, TreeRewriterResult & result, if (settings.optimize_arithmetic_operations_in_aggregate_functions) optimizeAggregationFunctions(query); - /// Push the predicate expression down to the subqueries. - result.rewrite_subqueries = PredicateExpressionsOptimizer(context, tables_with_columns, settings).optimize(*select_query); - /// GROUP BY injective function elimination. optimizeGroupBy(select_query, result.source_columns_set, context); diff --git a/src/Interpreters/TreeRewriter.cpp b/src/Interpreters/TreeRewriter.cpp index 8f923d82b27..9bcddb6b982 100644 --- a/src/Interpreters/TreeRewriter.cpp +++ b/src/Interpreters/TreeRewriter.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -1036,7 +1037,12 @@ TreeRewriterResultPtr TreeRewriter::analyzeSelect( if (settings.legacy_column_name_of_tuple_literal) markTupleLiteralsAsLegacy(query); - TreeOptimizer::apply(query, result, tables_with_columns, getContext()); + /// Push the predicate expression down to subqueries. The optimization should be applied to both initial and secondary queries. + result.rewrite_subqueries = PredicateExpressionsOptimizer(getContext(), tables_with_columns, settings).optimize(*select_query); + + /// Only apply AST optimization for initial queries. + if (getContext()->getClientInfo().query_kind == ClientInfo::QueryKind::INITIAL_QUERY) + TreeOptimizer::apply(query, result, tables_with_columns, getContext()); /// array_join_alias_to_name, array_join_result_to_source. getArrayJoinedColumns(query, result, select_query, result.source_columns, source_columns_set); From 3ae960e04b7675b54d5e386573c387c72ad1e5cd Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 11 Oct 2021 16:40:12 +0300 Subject: [PATCH 193/264] Review fixes --- docker/test/stress/stress | 2 +- tests/clickhouse-test | 6 +++--- ...4_cancel_http_readonly_queries_on_client_close.sh | 5 +++-- .../0_stateless/01085_max_distributed_connections.sh | 5 +++-- .../01085_max_distributed_connections_http.sh | 5 +++-- .../0_stateless/01600_quota_by_forwarded_ip.sh | 12 +++++++++--- .../0_stateless/01602_max_distributed_connections.sh | 8 ++++++-- .../queries/0_stateless/01675_data_type_coroutine.sh | 6 ++++-- .../0_stateless/01681_hyperscan_debug_assertion.sh | 5 +++-- .../01834_alias_columns_laziness_filimonov.sh | 5 +++-- tests/queries/0_stateless/02044_url_glob_parallel.sh | 6 ++++-- 11 files changed, 42 insertions(+), 23 deletions(-) diff --git a/docker/test/stress/stress b/docker/test/stress/stress index 1559b084565..5e98c67d8e1 100755 --- a/docker/test/stress/stress +++ b/docker/test/stress/stress @@ -117,7 +117,7 @@ def prepare_for_hung_check(drop_databases): # Wait for last queries to finish if any, not longer than 300 seconds call("""clickhouse client -q "select sleepEachRow(( select maxOrDefault(300 - elapsed) + 1 from system.processes where query not like '%from system.processes%' and elapsed < 300 - ) / 300) from numbers(300) format Null" """, shell=True, stderr=STDOUT, timeout=30) + ) / 300) from numbers(300) format Null" """, shell=True, stderr=STDOUT, timeout=330) # Even if all clickhouse-test processes are finished, there are probably some sh scripts, # which still run some new queries. Let's ignore them. diff --git a/tests/clickhouse-test b/tests/clickhouse-test index 061333297e2..62860a36fc7 100755 --- a/tests/clickhouse-test +++ b/tests/clickhouse-test @@ -879,7 +879,7 @@ def run_tests_array(all_tests_with_params): while True: if is_concurrent: - case = queue.get(timeout=args.timeout) + case = queue.get(timeout=args.timeout * 1.1) if not case: break else: @@ -1080,10 +1080,10 @@ def do_run_tests(jobs, test_suite: TestSuite, parallel): pool.map_async(run_tests_array, parallel_tests_array) for suit in test_suite.parallel_tests: - queue.put(suit, timeout=args.timeout) + queue.put(suit, timeout=args.timeout * 1.1) for _ in range(jobs): - queue.put(None, timeout=args.timeout) + queue.put(None, timeout=args.timeout * 1.1) queue.close() diff --git a/tests/queries/0_stateless/00834_cancel_http_readonly_queries_on_client_close.sh b/tests/queries/0_stateless/00834_cancel_http_readonly_queries_on_client_close.sh index 340df58e473..74b4c4052f8 100755 --- a/tests/queries/0_stateless/00834_cancel_http_readonly_queries_on_client_close.sh +++ b/tests/queries/0_stateless/00834_cancel_http_readonly_queries_on_client_close.sh @@ -7,9 +7,10 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ${CLICKHOUSE_CURL} --max-time 1 -sS "${CLICKHOUSE_URL}&query_id=cancel_http_readonly_queries_on_client_close&cancel_http_readonly_queries_on_client_close=1&query=SELECT+count()+FROM+system.numbers" 2>&1 | grep -cF 'curl: (28)' -while true -do +i=0 retries=300 +while [[ $i -lt $retries ]]; do ${CLICKHOUSE_CURL} -sS --data "SELECT count() FROM system.processes WHERE query_id = 'cancel_http_readonly_queries_on_client_close'" "${CLICKHOUSE_URL}" | grep '0' && break + ((++i)) sleep 0.2 done diff --git a/tests/queries/0_stateless/01085_max_distributed_connections.sh b/tests/queries/0_stateless/01085_max_distributed_connections.sh index 4ffcd980956..34862289d1e 100755 --- a/tests/queries/0_stateless/01085_max_distributed_connections.sh +++ b/tests/queries/0_stateless/01085_max_distributed_connections.sh @@ -5,10 +5,10 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck source=../shell_config.sh . "$CURDIR"/../shell_config.sh +i=0 retries=300 # Sometimes five seconds are not enough due to system overload. # But if it can run in less than five seconds at least sometimes - it is enough for the test. -while true -do +while [[ $i -lt $retries ]]; do opts=( --max_distributed_connections 20 --max_threads 1 @@ -19,4 +19,5 @@ do # "$@" left to pass manual options (like --experimental_use_processors 0) during manual testing timeout 10s ${CLICKHOUSE_CLIENT} "${opts[@]}" "$@" && break + ((++i)) done diff --git a/tests/queries/0_stateless/01085_max_distributed_connections_http.sh b/tests/queries/0_stateless/01085_max_distributed_connections_http.sh index 3edf70f31b8..0e40918257d 100755 --- a/tests/queries/0_stateless/01085_max_distributed_connections_http.sh +++ b/tests/queries/0_stateless/01085_max_distributed_connections_http.sh @@ -8,9 +8,10 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # Sometimes 1.8 seconds are not enough due to system overload. # But if it can run in less than five seconds at least sometimes - it is enough for the test. -while true -do +i=0 retries=100 +while [[ $i -lt $retries ]]; do query="SELECT sleepEachRow(1) FROM remote('127.{2,3}', system.one) FORMAT Null" # 1.8 less then 2 seconds, but long enough to cover possible load peaks timeout 1.8s ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}&max_distributed_connections=2&max_threads=1" -d "$query" && break + ((++i)) done diff --git a/tests/queries/0_stateless/01600_quota_by_forwarded_ip.sh b/tests/queries/0_stateless/01600_quota_by_forwarded_ip.sh index 97e4da5f9e3..1d768c8b027 100755 --- a/tests/queries/0_stateless/01600_quota_by_forwarded_ip.sh +++ b/tests/queries/0_stateless/01600_quota_by_forwarded_ip.sh @@ -21,7 +21,9 @@ CREATE QUOTA quota_by_forwarded_ip_${CLICKHOUSE_DATABASE} KEYED BY forwarded_ip_ echo '--- Test with quota by immediate IP ---' -while true; do +i=0 retries=300 +while [[ $i -lt $retries ]]; do + ((++i)) ${CLICKHOUSE_CURL} --fail -sS "${CLICKHOUSE_URL}&user=quoted_by_ip_${CLICKHOUSE_DATABASE}" -d "SELECT count() FROM numbers(10)" 2>/dev/null || break done | uniq @@ -33,14 +35,18 @@ ${CLICKHOUSE_CURL} -H 'X-Forwarded-For: 1.2.3.4' -sS "${CLICKHOUSE_URL}&user=quo echo '--- Test with quota by forwarded IP ---' -while true; do +i=0 retries=300 +while [[ $i -lt $retries ]]; do + ((++i)) ${CLICKHOUSE_CURL} --fail -sS "${CLICKHOUSE_URL}&user=quoted_by_forwarded_ip_${CLICKHOUSE_DATABASE}" -d "SELECT count() FROM numbers(10)" 2>/dev/null || break done | uniq ${CLICKHOUSE_CURL} -sS "${CLICKHOUSE_URL}&user=quoted_by_forwarded_ip_${CLICKHOUSE_DATABASE}" -d "SELECT count() FROM numbers(10)" | grep -oF 'exceeded' +i=0 retries=300 # X-Forwarded-For is respected for quota by forwarded IP address -while true; do +while [[ $i -lt $retries ]]; do + ((++i)) ${CLICKHOUSE_CURL} -H 'X-Forwarded-For: 1.2.3.4' -sS "${CLICKHOUSE_URL}&user=quoted_by_forwarded_ip_${CLICKHOUSE_DATABASE}" -d "SELECT count() FROM numbers(10)" | grep -oP '^10$' || break done | uniq diff --git a/tests/queries/0_stateless/01602_max_distributed_connections.sh b/tests/queries/0_stateless/01602_max_distributed_connections.sh index 51ff803ad5e..ed835a8768f 100755 --- a/tests/queries/0_stateless/01602_max_distributed_connections.sh +++ b/tests/queries/0_stateless/01602_max_distributed_connections.sh @@ -13,14 +13,18 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # If concurrency is 10 (good), the query may take less than 10 second with non-zero probability # and the following loops will finish with probability 1 assuming independent random variables. -while true; do +i=0 retries=30 +while [[ $i -lt $retries ]]; do timeout 10 ${CLICKHOUSE_CLIENT} --max_threads 1 --max_distributed_connections 10 --query " SELECT sleep(1.5) FROM remote('127.{1..10}', system.one) FORMAT Null" --prefer_localhost_replica=0 && break + ((++i)) done -while true; do +i=0 retries=30 +while [[ $i -lt $retries ]]; do timeout 10 ${CLICKHOUSE_CLIENT} --max_threads 1 --max_distributed_connections 10 --query " SELECT sleep(1.5) FROM remote('127.{1..10}', system.one) FORMAT Null" --prefer_localhost_replica=1 && break + ((++i)) done # If max_distributed_connections is low and async_socket_for_remote is disabled, diff --git a/tests/queries/0_stateless/01675_data_type_coroutine.sh b/tests/queries/0_stateless/01675_data_type_coroutine.sh index 781e43e4134..8e80d722a4c 100755 --- a/tests/queries/0_stateless/01675_data_type_coroutine.sh +++ b/tests/queries/0_stateless/01675_data_type_coroutine.sh @@ -4,12 +4,14 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck source=../shell_config.sh . "$CURDIR"/../shell_config.sh + +counter=0 retries=60 I=0 -while true -do +while [[ $counter -lt $retries ]]; do I=$((I + 1)) TYPE=$(perl -e "print 'Array(' x $I; print 'UInt8'; print ')' x $I") ${CLICKHOUSE_CLIENT} --max_parser_depth 1000000 --query "SELECT * FROM remote('127.0.0.{1,2}', generateRandom('x $TYPE', 1, 1, 1)) LIMIT 1 FORMAT Null" 2>&1 | grep -q -F 'Maximum parse depth' && break; + ((++counter)) done #echo "I = ${I}" diff --git a/tests/queries/0_stateless/01681_hyperscan_debug_assertion.sh b/tests/queries/0_stateless/01681_hyperscan_debug_assertion.sh index 2b4cd1a5f01..62469da0b3e 100755 --- a/tests/queries/0_stateless/01681_hyperscan_debug_assertion.sh +++ b/tests/queries/0_stateless/01681_hyperscan_debug_assertion.sh @@ -13,13 +13,14 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) M=1000000 -while true -do +i=0 retries=300 +while [[ $i -lt $retries ]]; do $CLICKHOUSE_CLIENT --allow_hyperscan 1 --max_memory_usage $M --format Null --query " SELECT [1, 2, 3, 11] = arraySort(multiMatchAllIndices('фабрикант', ['', 'рикан', 'а', 'f[a${RANDOM}e]b[ei]rl', 'ф[иа${RANDOM}эе]б[еэи][рпл]', 'афиукд', 'a[f${RANDOM}t],th', '^ф[аие${RANDOM}э]?б?[еэи]?$', 'бе${RANDOM}рлик', 'fa${RANDOM}b', 'фа[беьв]+е?[рл${RANDOM}ко]'])) " 2>&1 | grep -q 'Memory limit' || break; M=$((M + 100000)) + ((++i)) done echo 'Ok' diff --git a/tests/queries/0_stateless/01834_alias_columns_laziness_filimonov.sh b/tests/queries/0_stateless/01834_alias_columns_laziness_filimonov.sh index 793f477b3cb..1d70ba1df7c 100755 --- a/tests/queries/0_stateless/01834_alias_columns_laziness_filimonov.sh +++ b/tests/queries/0_stateless/01834_alias_columns_laziness_filimonov.sh @@ -16,9 +16,10 @@ insert into aliases_lazyness(x) select * from numbers(40); # The exact time is not guaranteed, so we check in a loop that at least once # the query will process in less than one second, that proves that the behaviour is not like it was long time ago. -while true -do +i=0 retries=300 +while [[ $i -lt $retries ]]; do timeout 1 ${CLICKHOUSE_CLIENT} --query "SELECT x, y FROM aliases_lazyness WHERE x = 1 FORMAT Null" && break + ((++i)) done ${CLICKHOUSE_CLIENT} --multiquery --query " diff --git a/tests/queries/0_stateless/02044_url_glob_parallel.sh b/tests/queries/0_stateless/02044_url_glob_parallel.sh index 6491a661201..c9c779a9ddb 100755 --- a/tests/queries/0_stateless/02044_url_glob_parallel.sh +++ b/tests/queries/0_stateless/02044_url_glob_parallel.sh @@ -5,9 +5,11 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck source=../shell_config.sh . "$CURDIR"/../shell_config.sh + +i=0 retries=60 # Sometimes five seconds are not enough due to system overload. # But if it can run in less than five seconds at least sometimes - it is enough for the test. -while true -do +while [[ $i -lt $retries ]]; do timeout 5s ${CLICKHOUSE_CLIENT} --max_threads 10 --query "SELECT * FROM url('http://127.0.0.{1..10}:${CLICKHOUSE_PORT_HTTP}/?query=SELECT+sleep(1)', TSV, 'x UInt8')" --format Null && break + ((++i)) done From ab4b2295749a900c803dd8620d19f8d46a7d023d Mon Sep 17 00:00:00 2001 From: Haavard Kvaalen Date: Mon, 11 Oct 2021 16:20:51 +0200 Subject: [PATCH 194/264] Make sure we update position on commit Make sure we update GTID set on QueryEvents with "COMMIT" or "XA COMMIT". Without this we could have to redo the last transaction if e.g. ClickHouse was restarted. Note that this did not affect normal transactions on InnoDB, since they are terminated with a XID_EVENT. --- src/Core/MySQL/MySQLReplication.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Core/MySQL/MySQLReplication.cpp b/src/Core/MySQL/MySQLReplication.cpp index b5468d15edc..b5adab67e3a 100644 --- a/src/Core/MySQL/MySQLReplication.cpp +++ b/src/Core/MySQL/MySQLReplication.cpp @@ -815,6 +815,7 @@ namespace MySQLReplication { event = std::make_shared(std::move(event_header)); event->parseEvent(event_payload); + position.update(event); auto query = std::static_pointer_cast(event); switch (query->typ) @@ -826,7 +827,7 @@ namespace MySQLReplication break; } default: - position.update(event); + break; } break; } From 362bcb2f6662c7c05731efed229d0a9273bc307f Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Mon, 30 Aug 2021 14:04:59 +0300 Subject: [PATCH 195/264] Introduce ProfileEvents packet --- programs/client/Client.cpp | 4 + src/Client/ClientBase.cpp | 9 ++ src/Client/ClientBase.h | 1 + src/Client/Connection.cpp | 21 ++++ src/Client/Connection.h | 3 + src/Client/HedgedConnections.cpp | 2 + src/Client/LocalConnection.cpp | 2 + src/Client/MultiplexedConnections.cpp | 2 + src/Client/Suggest.cpp | 3 + src/Common/CurrentMetrics.h | 6 ++ src/Common/MemoryTracker.h | 5 + src/Core/Protocol.h | 3 +- src/DataStreams/ConnectionCollector.cpp | 2 + src/DataStreams/RemoteQueryExecutor.cpp | 4 + src/Server/TCPHandler.cpp | 137 ++++++++++++++++++++++++ src/Server/TCPHandler.h | 4 + 16 files changed, 207 insertions(+), 1 deletion(-) diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp index 04193036872..da910430985 100644 --- a/programs/client/Client.cpp +++ b/programs/client/Client.cpp @@ -15,6 +15,7 @@ #include #include #include "Client.h" +#include "Core/Protocol.h" #include #include @@ -377,6 +378,9 @@ std::vector Client::loadWarningMessages() case Protocol::Server::EndOfStream: return messages; + case Protocol::Server::ProfileEvents: + continue; + default: throw Exception(ErrorCodes::UNKNOWN_PACKET_FROM_SERVER, "Unknown packet {} from server {}", packet.type, connection->getDescription()); diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index 56d9993d14b..ee5f3580050 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -9,6 +9,7 @@ #include #include #include +#include "Core/Protocol.h" #if !defined(ARCADIA_BUILD) # include @@ -611,6 +612,10 @@ bool ClientBase::receiveAndProcessPacket(ASTPtr parsed_query, bool cancelled) onEndOfStream(); return false; + case Protocol::Server::ProfileEvents: + onProfileEvents(); + return true; + default: throw Exception( ErrorCodes::UNKNOWN_PACKET_FROM_SERVER, "Unknown packet {} from server {}", packet.type, connection->getDescription()); @@ -651,6 +656,10 @@ void ClientBase::onEndOfStream() } +void ClientBase::onProfileEvents() +{} + + /// Flush all buffers. void ClientBase::resetOutput() { diff --git a/src/Client/ClientBase.h b/src/Client/ClientBase.h index b122803e1db..0fa205a4d6e 100644 --- a/src/Client/ClientBase.h +++ b/src/Client/ClientBase.h @@ -114,6 +114,7 @@ private: void onReceiveExceptionFromServer(std::unique_ptr && e); void onProfileInfo(const BlockStreamProfileInfo & profile_info); void onEndOfStream(); + void onProfileEvents(); void sendData(Block & sample, const ColumnsDescription & columns_description, ASTPtr parsed_query); void sendDataFrom(ReadBuffer & buf, Block & sample, diff --git a/src/Client/Connection.cpp b/src/Client/Connection.cpp index 2aa157bb318..1aabe449ed5 100644 --- a/src/Client/Connection.cpp +++ b/src/Client/Connection.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -870,6 +871,10 @@ Packet Connection::receivePacket() case Protocol::Server::ReadTaskRequest: return res; + case Protocol::Server::ProfileEvents: + res.block = receiveProfileEvents(); + return res; + default: /// In unknown state, disconnect - to not leave unsynchronised connection. disconnect(); @@ -923,6 +928,13 @@ Block Connection::receiveDataImpl(NativeReader & reader) } +Block Connection::receiveProfileEvents() +{ + initBlockProfileEventsInput(); + return receiveDataImpl(*block_profile_events_in); +} + + void Connection::initInputBuffers() { @@ -956,6 +968,15 @@ void Connection::initBlockLogsInput() } +void Connection::initBlockProfileEventsInput() +{ + if (!block_profile_events_in) + { + block_profile_events_in = std::make_unique(*in, server_revision); + } +} + + void Connection::setDescription() { auto resolved_address = getResolvedAddress(); diff --git a/src/Client/Connection.h b/src/Client/Connection.h index a5130d876ea..b6054941aeb 100644 --- a/src/Client/Connection.h +++ b/src/Client/Connection.h @@ -206,6 +206,7 @@ private: std::shared_ptr maybe_compressed_in; std::unique_ptr block_in; std::unique_ptr block_logs_in; + std::unique_ptr block_profile_events_in; /// Where to write data for INSERT. std::shared_ptr maybe_compressed_out; @@ -249,6 +250,7 @@ private: Block receiveData(); Block receiveLogData(); Block receiveDataImpl(NativeReader & reader); + Block receiveProfileEvents(); std::vector receiveMultistringMessage(UInt64 msg_type) const; std::unique_ptr receiveException() const; @@ -258,6 +260,7 @@ private: void initInputBuffers(); void initBlockInput(); void initBlockLogsInput(); + void initBlockProfileEventsInput(); [[noreturn]] void throwUnexpectedPacket(UInt64 packet_type, const char * expected) const; }; diff --git a/src/Client/HedgedConnections.cpp b/src/Client/HedgedConnections.cpp index b833241b2bc..1ca890f40f9 100644 --- a/src/Client/HedgedConnections.cpp +++ b/src/Client/HedgedConnections.cpp @@ -1,3 +1,4 @@ +#include "Core/Protocol.h" #if defined(OS_LINUX) #include @@ -412,6 +413,7 @@ Packet HedgedConnections::receivePacketFromReplica(const ReplicaLocation & repli case Protocol::Server::Totals: case Protocol::Server::Extremes: case Protocol::Server::Log: + case Protocol::Server::ProfileEvents: replica_with_last_received_packet = replica_location; break; diff --git a/src/Client/LocalConnection.cpp b/src/Client/LocalConnection.cpp index 29bc0c84437..efd302622dd 100644 --- a/src/Client/LocalConnection.cpp +++ b/src/Client/LocalConnection.cpp @@ -5,6 +5,7 @@ #include #include #include +#include "Core/Protocol.h" namespace DB @@ -328,6 +329,7 @@ Packet LocalConnection::receivePacket() case Protocol::Server::Extremes: [[fallthrough]]; case Protocol::Server::Log: [[fallthrough]]; case Protocol::Server::Data: + case Protocol::Server::ProfileEvents: { if (state->block && state->block.value()) { diff --git a/src/Client/MultiplexedConnections.cpp b/src/Client/MultiplexedConnections.cpp index a4e1eb09253..a27f7709555 100644 --- a/src/Client/MultiplexedConnections.cpp +++ b/src/Client/MultiplexedConnections.cpp @@ -2,6 +2,7 @@ #include #include #include +#include "Core/Protocol.h" namespace DB @@ -320,6 +321,7 @@ Packet MultiplexedConnections::receivePacketUnlocked(AsyncCallback async_callbac case Protocol::Server::Totals: case Protocol::Server::Extremes: case Protocol::Server::Log: + case Protocol::Server::ProfileEvents: break; case Protocol::Server::EndOfStream: diff --git a/src/Client/Suggest.cpp b/src/Client/Suggest.cpp index f500332b616..38aeae76a38 100644 --- a/src/Client/Suggest.cpp +++ b/src/Client/Suggest.cpp @@ -6,6 +6,7 @@ #include #include #include +#include "Core/Protocol.h" #include #include #include @@ -162,6 +163,8 @@ void Suggest::fetch(IServerConnection & connection, const ConnectionTimeouts & t continue; case Protocol::Server::Log: continue; + case Protocol::Server::ProfileEvents: + continue; case Protocol::Server::Exception: packet.exception->rethrow(); diff --git a/src/Common/CurrentMetrics.h b/src/Common/CurrentMetrics.h index f6f4785a95a..21c3f704872 100644 --- a/src/Common/CurrentMetrics.h +++ b/src/Common/CurrentMetrics.h @@ -41,6 +41,12 @@ namespace CurrentMetrics values[metric].store(value, std::memory_order_relaxed); } + /// Get value of specified metric. + inline Value get(Metric metric) + { + return values[metric].load(std::memory_order_relaxed); + } + /// Add value for specified metric. You must subtract value later; or see class Increment below. inline void add(Metric metric, Value value = 1) { diff --git a/src/Common/MemoryTracker.h b/src/Common/MemoryTracker.h index b860c611be2..7da70db0876 100644 --- a/src/Common/MemoryTracker.h +++ b/src/Common/MemoryTracker.h @@ -143,6 +143,11 @@ public: metric.store(metric_, std::memory_order_relaxed); } + CurrentMetrics::Metric getMetric() + { + return metric.load(std::memory_order_relaxed); + } + void setDescription(const char * description) { description_ptr.store(description, std::memory_order_relaxed); diff --git a/src/Core/Protocol.h b/src/Core/Protocol.h index 9ec792a6230..4958f343bbc 100644 --- a/src/Core/Protocol.h +++ b/src/Core/Protocol.h @@ -80,7 +80,8 @@ namespace Protocol ReadTaskRequest = 13, /// String (UUID) describes a request for which next task is needed /// This is such an inverted logic, where server sends requests /// And client returns back response - MAX = ReadTaskRequest, + ProfileEvents = 14, + MAX = ProfileEvents, }; /// NOTE: If the type of packet argument would be Enum, the comparison packet >= 0 && packet < 10 diff --git a/src/DataStreams/ConnectionCollector.cpp b/src/DataStreams/ConnectionCollector.cpp index 8e700c0ab7f..df206478e91 100644 --- a/src/DataStreams/ConnectionCollector.cpp +++ b/src/DataStreams/ConnectionCollector.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "Core/Protocol.h" #include namespace CurrentMetrics @@ -81,6 +82,7 @@ void ConnectionCollector::drainConnections(IConnections & connections) noexcept { case Protocol::Server::EndOfStream: case Protocol::Server::Log: + case Protocol::Server::ProfileEvents: break; case Protocol::Server::Exception: diff --git a/src/DataStreams/RemoteQueryExecutor.cpp b/src/DataStreams/RemoteQueryExecutor.cpp index 3c78fddfd39..fc2db2f3f6f 100644 --- a/src/DataStreams/RemoteQueryExecutor.cpp +++ b/src/DataStreams/RemoteQueryExecutor.cpp @@ -4,6 +4,7 @@ #include #include +#include "Core/Protocol.h" #include #include #include @@ -390,6 +391,9 @@ std::optional RemoteQueryExecutor::processPacket(Packet packet) log_queue->pushBlock(std::move(packet.block)); break; + case Protocol::Server::ProfileEvents: + break; + default: got_unknown_packet_from_replica = true; throw Exception(ErrorCodes::UNKNOWN_PACKET_FROM_SERVER, "Unknown packet {} from one of the following replicas: {}", diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index f3247e7bc2b..fbb5c755142 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -812,6 +813,128 @@ void TCPHandler::sendExtremes(const Block & extremes) } +namespace +{ + using namespace ProfileEvents; + + enum ProfileEventTypes : int8_t + { + INCREMENT = 1, + GAUGE = 2, + }; + + constexpr size_t NAME_COLUMN_INDEX = 4; + constexpr size_t VALUE_COLUMN_INDEX = 5; + + /* + * Add records about provided non-zero ProfileEvents::Counters. + */ + void dumpProfileEvents( + ProfileEvents::Counters const & snapshot, + MutableColumns & columns, + String const & host_name, + time_t current_time, + UInt64 thread_id) + { + size_t rows = 0; + auto & name_column = columns[NAME_COLUMN_INDEX]; + auto & value_column = columns[VALUE_COLUMN_INDEX]; + for (ProfileEvents::Event event = 0; event < ProfileEvents::Counters::num_counters; ++event) + { + UInt64 value = snapshot[event].load(std::memory_order_relaxed); + + if (value == 0) + continue; + + const char * desc = ProfileEvents::getName(event); + name_column->insertData(desc, strlen(desc)); + value_column->insert(value); + rows++; + } + + // Fill the rest of the columns with data + for (size_t row = 0; row < rows; ++row) + { + size_t i = 0; + columns[i++]->insertData(host_name.data(), host_name.size()); + columns[i++]->insert(UInt64(current_time)); + columns[i++]->insert(UInt64{thread_id}); + columns[i++]->insert(ProfileEventTypes::INCREMENT); + } + } + + void dumpMemoryTracker( + MemoryTracker * memoryTracker, + MutableColumns & columns, + String const & host_name, + time_t current_time, + UInt64 thread_id) + { + auto metric = memoryTracker->getMetric(); + if (metric == CurrentMetrics::end()) + return; + + size_t i = 0; + columns[i++]->insertData(host_name.data(), host_name.size()); + columns[i++]->insert(UInt64(current_time)); + columns[i++]->insert(UInt64{thread_id}); + columns[i++]->insert(ProfileEventTypes::GAUGE); + + auto const * metric_name = CurrentMetrics::getName(metric); + columns[i++]->insertData(metric_name, strlen(metric_name)); + auto metric_value = CurrentMetrics::get(metric); + columns[i++]->insert(metric_value); + } +} + + +void TCPHandler::sendProfileEvents() +{ + auto thread_group = CurrentThread::getGroup(); + auto const counters_snapshot = CurrentThread::getProfileEvents().getPartiallyAtomicSnapshot(); + auto current_time = time(nullptr); + auto * memory_tracker = CurrentThread::getMemoryTracker(); + + auto const thread_id = CurrentThread::get().thread_id; + + auto profile_event_type = std::make_shared( + DataTypeEnum8::Values + { + { "increment", static_cast(INCREMENT)}, + { "gauge", static_cast(GAUGE)}, + }); + + NamesAndTypesList column_names_and_types = { + { "host_name", std::make_shared() }, + { "current_time", std::make_shared() }, + { "thread_id", std::make_shared() }, + { "type", profile_event_type }, + { "name", std::make_shared() }, + { "value", std::make_shared() }, + }; + + ColumnsWithTypeAndName temp_columns; + for (auto const & name_and_type : column_names_and_types) + temp_columns.emplace_back(name_and_type.type, name_and_type.name); + + Block block(std::move(temp_columns)); + + MutableColumns columns = block.mutateColumns(); + dumpProfileEvents(counters_snapshot, columns, server_display_name, current_time, thread_id); + dumpMemoryTracker(memory_tracker, columns, server_display_name, current_time, thread_id); + + block.setColumns(std::move(columns)); + + initProfileEventsBlockOutput(block); + + writeVarUInt(Protocol::Server::ProfileEvents, *out); + writeStringBinary("", *out); + + state.logs_block_out->write(block); + out->next(); +} + + bool TCPHandler::receiveProxyHeader() { if (in->eof()) @@ -1453,6 +1576,20 @@ void TCPHandler::initLogsBlockOutput(const Block & block) } +void TCPHandler::initProfileEventsBlockOutput(const Block & block) +{ + if (!state.profile_events_block_out) + { + const Settings & query_settings = query_context->getSettingsRef(); + state.profile_events_block_out = std::make_unique( + *out, + client_tcp_protocol_version, + block.cloneEmpty(), + !query_settings.low_cardinality_allow_in_native_format); + } +} + + bool TCPHandler::isQueryCancelled() { if (state.is_cancelled || state.sent_all_data) diff --git a/src/Server/TCPHandler.h b/src/Server/TCPHandler.h index d001b12ee66..9ff061e096b 100644 --- a/src/Server/TCPHandler.h +++ b/src/Server/TCPHandler.h @@ -48,6 +48,8 @@ struct QueryState InternalTextLogsQueuePtr logs_queue; std::unique_ptr logs_block_out; + std::unique_ptr profile_events_block_out; + /// From where to read data for INSERT. std::shared_ptr maybe_compressed_in; std::unique_ptr block_in; @@ -228,11 +230,13 @@ private: void sendProfileInfo(const BlockStreamProfileInfo & info); void sendTotals(const Block & totals); void sendExtremes(const Block & extremes); + void sendProfileEvents(); /// Creates state.block_in/block_out for blocks read/write, depending on whether compression is enabled. void initBlockInput(); void initBlockOutput(const Block & block); void initLogsBlockOutput(const Block & block); + void initProfileEventsBlockOutput(const Block & block); bool isQueryCancelled(); From e9b1e0546179c38fe748b5df947e96bcd95771b4 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Mon, 30 Aug 2021 18:35:25 +0300 Subject: [PATCH 196/264] Send profile events from all threads of current group --- src/Common/ThreadStatus.h | 4 +++- src/Interpreters/ThreadStatusExt.cpp | 1 + src/Server/TCPHandler.cpp | 23 +++++++++++++---------- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Common/ThreadStatus.h b/src/Common/ThreadStatus.h index 9e8d8f637b8..dbd0b4e5664 100644 --- a/src/Common/ThreadStatus.h +++ b/src/Common/ThreadStatus.h @@ -15,6 +15,7 @@ #include #include #include +#include namespace Poco @@ -41,7 +42,7 @@ struct ViewRuntimeData; class QueryViewsLog; using InternalTextLogsQueuePtr = std::shared_ptr; using InternalTextLogsQueueWeakPtr = std::weak_ptr; - +using ThreadStatusPtr = ThreadStatus *; /** Thread group is a collection of threads dedicated to single task * (query or other process like background merge). @@ -66,6 +67,7 @@ public: std::function fatal_error_callback; std::vector thread_ids; + std::unordered_set threads; /// The first thread created this thread group UInt64 master_thread_id = 0; diff --git a/src/Interpreters/ThreadStatusExt.cpp b/src/Interpreters/ThreadStatusExt.cpp index 465b8e31b08..81a745ef430 100644 --- a/src/Interpreters/ThreadStatusExt.cpp +++ b/src/Interpreters/ThreadStatusExt.cpp @@ -123,6 +123,7 @@ void ThreadStatus::setupState(const ThreadGroupStatusPtr & thread_group_) /// NOTE: thread may be attached multiple times if it is reused from a thread pool. thread_group->thread_ids.emplace_back(thread_id); + thread_group->threads.insert(this); logs_queue_ptr = thread_group->logs_queue_ptr; fatal_error_callback = thread_group->fatal_error_callback; diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index fbb5c755142..4c6d01c564c 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -666,6 +666,7 @@ void TCPHandler::processOrdinaryQueryWithProcessors() /// Some time passed and there is a progress. after_send_progress.restart(); sendProgress(); + sendProfileEvents(); } sendLogs(); @@ -691,6 +692,7 @@ void TCPHandler::processOrdinaryQueryWithProcessors() sendProfileInfo(executor.getProfileInfo()); sendProgress(); sendLogs(); + sendProfileEvents(); } if (state.is_connection_closed) @@ -867,12 +869,12 @@ namespace MemoryTracker * memoryTracker, MutableColumns & columns, String const & host_name, - time_t current_time, UInt64 thread_id) { auto metric = memoryTracker->getMetric(); if (metric == CurrentMetrics::end()) return; + time_t current_time = time(nullptr); size_t i = 0; columns[i++]->insertData(host_name.data(), host_name.size()); @@ -890,13 +892,6 @@ namespace void TCPHandler::sendProfileEvents() { - auto thread_group = CurrentThread::getGroup(); - auto const counters_snapshot = CurrentThread::getProfileEvents().getPartiallyAtomicSnapshot(); - auto current_time = time(nullptr); - auto * memory_tracker = CurrentThread::getMemoryTracker(); - - auto const thread_id = CurrentThread::get().thread_id; - auto profile_event_type = std::make_shared( DataTypeEnum8::Values { @@ -920,9 +915,17 @@ void TCPHandler::sendProfileEvents() Block block(std::move(temp_columns)); MutableColumns columns = block.mutateColumns(); - dumpProfileEvents(counters_snapshot, columns, server_display_name, current_time, thread_id); - dumpMemoryTracker(memory_tracker, columns, server_display_name, current_time, thread_id); + auto thread_group = CurrentThread::getGroup(); + for (auto * thread : thread_group->threads) + { + auto const counters_snapshot = thread->performance_counters.getPartiallyAtomicSnapshot(); + auto current_time = time(nullptr); + auto * memory_tracker = &thread->memory_tracker; + auto const thread_id = CurrentThread::get().thread_id; + dumpProfileEvents(counters_snapshot, columns, server_display_name, current_time, thread_id); + dumpMemoryTracker(memory_tracker, columns, server_display_name, thread_id); + } block.setColumns(std::move(columns)); initProfileEventsBlockOutput(block); From 4c5a77457076dff8041c3baaeb89feef6c853d6f Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Mon, 30 Aug 2021 18:48:22 +0300 Subject: [PATCH 197/264] Add comment --- src/Core/Protocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Protocol.h b/src/Core/Protocol.h index 4958f343bbc..b2957e4ae30 100644 --- a/src/Core/Protocol.h +++ b/src/Core/Protocol.h @@ -80,7 +80,7 @@ namespace Protocol ReadTaskRequest = 13, /// String (UUID) describes a request for which next task is needed /// This is such an inverted logic, where server sends requests /// And client returns back response - ProfileEvents = 14, + ProfileEvents = 14, /// Packet with profile events from server. MAX = ProfileEvents, }; From 803b8623c1b03dcb5bd4591d67dea421cd121b2e Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 31 Aug 2021 16:50:56 +0300 Subject: [PATCH 198/264] Fix TCPHandler::sendProfileEvents --- src/Interpreters/ThreadStatusExt.cpp | 5 +++++ src/Server/TCPHandler.cpp | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Interpreters/ThreadStatusExt.cpp b/src/Interpreters/ThreadStatusExt.cpp index 81a745ef430..7b7bfec006c 100644 --- a/src/Interpreters/ThreadStatusExt.cpp +++ b/src/Interpreters/ThreadStatusExt.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -398,6 +399,10 @@ void ThreadStatus::detachQuery(bool exit_if_already_detached, bool thread_exits) finalizePerformanceCounters(); /// Detach from thread group + { + std::lock_guard guard(thread_group->mutex); + thread_group->threads.erase(this); + } performance_counters.setParent(&ProfileEvents::global_counters); memory_tracker.reset(); diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index 4c6d01c564c..9c1b107c513 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -1,4 +1,8 @@ +#include #include +#include +#include +#include #include #include #include @@ -916,7 +920,12 @@ void TCPHandler::sendProfileEvents() MutableColumns columns = block.mutateColumns(); auto thread_group = CurrentThread::getGroup(); - for (auto * thread : thread_group->threads) + std::vector threads; + { + std::lock_guard guard(thread_group->mutex); + std::copy(thread_group->threads.begin(), thread_group->threads.end(), std::back_inserter(threads)); + } + for (auto * thread : threads) { auto const counters_snapshot = thread->performance_counters.getPartiallyAtomicSnapshot(); auto current_time = time(nullptr); @@ -933,7 +942,7 @@ void TCPHandler::sendProfileEvents() writeVarUInt(Protocol::Server::ProfileEvents, *out); writeStringBinary("", *out); - state.logs_block_out->write(block); + state.profile_events_block_out->write(block); out->next(); } From 74cdaba7fa90bf0e87c24c7c6a6c384249f33d5c Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Wed, 1 Sep 2021 17:47:12 +0300 Subject: [PATCH 199/264] WIP on profile events forwarding --- src/DataStreams/RemoteQueryExecutor.cpp | 1 + src/Server/GRPCServer.cpp | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/DataStreams/RemoteQueryExecutor.cpp b/src/DataStreams/RemoteQueryExecutor.cpp index fc2db2f3f6f..dc97e577513 100644 --- a/src/DataStreams/RemoteQueryExecutor.cpp +++ b/src/DataStreams/RemoteQueryExecutor.cpp @@ -392,6 +392,7 @@ std::optional RemoteQueryExecutor::processPacket(Packet packet) break; case Protocol::Server::ProfileEvents: + /// Pass profile events from remote server to client break; default: diff --git a/src/Server/GRPCServer.cpp b/src/Server/GRPCServer.cpp index cc3c7085dfd..fc712916372 100644 --- a/src/Server/GRPCServer.cpp +++ b/src/Server/GRPCServer.cpp @@ -596,6 +596,7 @@ namespace void addExtremesToResult(const Block & extremes); void addProfileInfoToResult(const BlockStreamProfileInfo & info); void addLogsToResult(); + void addProfileEventsToResult(); void sendResult(); void throwIfFailedToSendResult(); void sendException(const Exception & exception); @@ -1123,6 +1124,7 @@ namespace if (after_send_progress.elapsedMicroseconds() >= interactive_delay) { addProgressToResult(); + addProfileEventsToResult(); after_send_progress.restart(); } @@ -1174,6 +1176,7 @@ namespace finalize = true; io.onFinish(); addProgressToResult(); + addProfileEventsToResult(); query_scope->logPeakMemoryUsage(); addLogsToResult(); sendResult(); @@ -1437,6 +1440,11 @@ namespace } } + void Call::addProfileEventsToResult() + { + + } + void Call::sendResult() { /// gRPC doesn't allow to write anything to a finished responder. From 356723427df530d834dd9f0bae1977b95f1ccc84 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Thu, 2 Sep 2021 17:27:19 +0300 Subject: [PATCH 200/264] WIP on ProfileEvents forwarding --- src/Client/Connection.cpp | 2 ++ src/Common/CurrentThread.cpp | 18 +++++++++++ src/Common/CurrentThread.h | 3 ++ src/Common/ThreadStatus.cpp | 12 ++++++++ src/Common/ThreadStatus.h | 15 +++++++++ src/Core/Protocol.h | 3 +- src/DataStreams/RemoteQueryExecutor.cpp | 9 +++++- src/Interpreters/ThreadStatusExt.cpp | 1 + src/Server/TCPHandler.cpp | 41 ++++++++++++++++++++----- src/Server/TCPHandler.h | 1 + 10 files changed, 95 insertions(+), 10 deletions(-) diff --git a/src/Client/Connection.cpp b/src/Client/Connection.cpp index 1aabe449ed5..c6badf96bf9 100644 --- a/src/Client/Connection.cpp +++ b/src/Client/Connection.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "Core/Block.h" #include #include #include @@ -872,6 +873,7 @@ Packet Connection::receivePacket() return res; case Protocol::Server::ProfileEvents: + LOG_DEBUG(log_wrapper.get(), "Connection received ProfileEvents"); res.block = receiveProfileEvents(); return res; diff --git a/src/Common/CurrentThread.cpp b/src/Common/CurrentThread.cpp index c6b9e027c48..10d9f4d07df 100644 --- a/src/Common/CurrentThread.cpp +++ b/src/Common/CurrentThread.cpp @@ -91,6 +91,24 @@ std::shared_ptr CurrentThread::getInternalTextLogsQueue() return current_thread->getInternalTextLogsQueue(); } +void CurrentThread::attachInternalProfileEventsQueue(const InternalProfileEventsQueuePtr & queue) +{ + if (unlikely(!current_thread)) + return; + current_thread->attachInternalProfileEventsQueue(queue); +} + +InternalProfileEventsQueuePtr CurrentThread::getInternalProfileEventsQueue() +{ + if (unlikely(!current_thread)) + return nullptr; + + if (current_thread->getCurrentState() == ThreadStatus::ThreadState::Died) + return nullptr; + + return current_thread->getInternalProfileEventsQueue(); +} + ThreadGroupStatusPtr CurrentThread::getGroup() { if (unlikely(!current_thread)) diff --git a/src/Common/CurrentThread.h b/src/Common/CurrentThread.h index 96ea7f7e795..9dbe8d355d6 100644 --- a/src/Common/CurrentThread.h +++ b/src/Common/CurrentThread.h @@ -46,6 +46,9 @@ public: LogsLevel client_logs_level); static std::shared_ptr getInternalTextLogsQueue(); + static void attachInternalProfileEventsQueue(const InternalProfileEventsQueuePtr & queue); + static InternalProfileEventsQueuePtr getInternalProfileEventsQueue(); + static void setFatalErrorCallback(std::function callback); /// Makes system calls to update ProfileEvents that contain info from rusage and taskstats diff --git a/src/Common/ThreadStatus.cpp b/src/Common/ThreadStatus.cpp index b1d76c4660e..4c49e9b1d0d 100644 --- a/src/Common/ThreadStatus.cpp +++ b/src/Common/ThreadStatus.cpp @@ -10,6 +10,7 @@ #include #include +#include namespace DB @@ -197,6 +198,17 @@ void ThreadStatus::attachInternalTextLogsQueue(const InternalTextLogsQueuePtr & thread_group->client_logs_level = client_logs_level; } +void ThreadStatus::attachInternalProfileEventsQueue(const InternalProfileEventsQueuePtr & profile_queue) +{ + profile_queue_ptr = profile_queue; + + if (!thread_group) + return; + + std::lock_guard lock(thread_group->mutex); + thread_group->profile_queue_ptr = profile_queue; +} + void ThreadStatus::setFatalErrorCallback(std::function callback) { fatal_error_callback = std::move(callback); diff --git a/src/Common/ThreadStatus.h b/src/Common/ThreadStatus.h index dbd0b4e5664..16a47a21184 100644 --- a/src/Common/ThreadStatus.h +++ b/src/Common/ThreadStatus.h @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -42,6 +43,10 @@ struct ViewRuntimeData; class QueryViewsLog; using InternalTextLogsQueuePtr = std::shared_ptr; using InternalTextLogsQueueWeakPtr = std::weak_ptr; + +using InternalProfileEventsQueue = ConcurrentBoundedQueue; +using InternalProfileEventsQueuePtr = std::shared_ptr; +using InternalProfileEventsQueueWeakPtr = std::weak_ptr; using ThreadStatusPtr = ThreadStatus *; /** Thread group is a collection of threads dedicated to single task @@ -64,6 +69,7 @@ public: ContextWeakPtr global_context; InternalTextLogsQueueWeakPtr logs_queue_ptr; + InternalProfileEventsQueueWeakPtr profile_queue_ptr; std::function fatal_error_callback; std::vector thread_ids; @@ -134,6 +140,8 @@ protected: /// A logs queue used by TCPHandler to pass logs to a client InternalTextLogsQueueWeakPtr logs_queue_ptr; + InternalProfileEventsQueueWeakPtr profile_queue_ptr; + bool performance_counters_finalized = false; UInt64 query_start_time_nanoseconds = 0; UInt64 query_start_time_microseconds = 0; @@ -208,6 +216,13 @@ public: void attachInternalTextLogsQueue(const InternalTextLogsQueuePtr & logs_queue, LogsLevel client_logs_level); + InternalProfileEventsQueuePtr getInternalProfileEventsQueue() const + { + return thread_state == Died ? nullptr : profile_queue_ptr.lock(); + } + + void attachInternalProfileEventsQueue(const InternalProfileEventsQueuePtr & profile_queue); + /// Callback that is used to trigger sending fatal error messages to client. void setFatalErrorCallback(std::function callback); void onFatalError(); diff --git a/src/Core/Protocol.h b/src/Core/Protocol.h index b2957e4ae30..fb18e1135a5 100644 --- a/src/Core/Protocol.h +++ b/src/Core/Protocol.h @@ -104,7 +104,8 @@ namespace Protocol "Log", "TableColumns", "PartUUIDs", - "ReadTaskRequest" + "ReadTaskRequest", + "ProfileEvents", }; return packet <= MAX ? data[packet] diff --git a/src/DataStreams/RemoteQueryExecutor.cpp b/src/DataStreams/RemoteQueryExecutor.cpp index dc97e577513..51c5c2edc57 100644 --- a/src/DataStreams/RemoteQueryExecutor.cpp +++ b/src/DataStreams/RemoteQueryExecutor.cpp @@ -1,3 +1,5 @@ +#include + #include #include #include @@ -393,7 +395,12 @@ std::optional RemoteQueryExecutor::processPacket(Packet packet) case Protocol::Server::ProfileEvents: /// Pass profile events from remote server to client - break; + { + LOG_DEBUG(log, "RemoteQueryExecutor received ProfileEvents"); + auto profile_queue = CurrentThread::getInternalProfileEventsQueue(); + profile_queue->emplace(std::move(packet.block)); + break; + } default: got_unknown_packet_from_replica = true; diff --git a/src/Interpreters/ThreadStatusExt.cpp b/src/Interpreters/ThreadStatusExt.cpp index 7b7bfec006c..7ff74a0618c 100644 --- a/src/Interpreters/ThreadStatusExt.cpp +++ b/src/Interpreters/ThreadStatusExt.cpp @@ -129,6 +129,7 @@ void ThreadStatus::setupState(const ThreadGroupStatusPtr & thread_group_) logs_queue_ptr = thread_group->logs_queue_ptr; fatal_error_callback = thread_group->fatal_error_callback; query_context = thread_group->query_context; + profile_queue_ptr = thread_group->profile_queue_ptr; if (global_context.expired()) global_context = thread_group->global_context; diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index 9c1b107c513..f1014d611fd 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -243,6 +244,8 @@ void TCPHandler::runImpl() sendLogs(); }); } + state.profile_queue = std::make_shared(std::numeric_limits::max()); + CurrentThread::attachInternalProfileEventsQueue(state.profile_queue); query_context->setExternalTablesInitializer([this] (ContextPtr context) { @@ -670,10 +673,10 @@ void TCPHandler::processOrdinaryQueryWithProcessors() /// Some time passed and there is a progress. after_send_progress.restart(); sendProgress(); - sendProfileEvents(); } sendLogs(); + sendProfileEvents(); if (block) { @@ -696,7 +699,7 @@ void TCPHandler::processOrdinaryQueryWithProcessors() sendProfileInfo(executor.getProfileInfo()); sendProgress(); sendLogs(); - sendProfileEvents(); + // sendProfileEvents(); } if (state.is_connection_closed) @@ -935,15 +938,37 @@ void TCPHandler::sendProfileEvents() dumpProfileEvents(counters_snapshot, columns, server_display_name, current_time, thread_id); dumpMemoryTracker(memory_tracker, columns, server_display_name, thread_id); } - block.setColumns(std::move(columns)); - initProfileEventsBlockOutput(block); + MutableColumns logs_columns; + Block curr_block; + size_t rows = 0; - writeVarUInt(Protocol::Server::ProfileEvents, *out); - writeStringBinary("", *out); + bool from_queue = false; + for (; state.profile_queue->tryPop(curr_block); ++rows) + { + from_queue = true; + auto curr_columns = curr_block.getColumns(); + for (size_t j = 0; j < curr_columns.size(); ++j) + columns[j]->insertRangeFrom(*curr_columns[j], 0, curr_columns[j]->size()); + } - state.profile_events_block_out->write(block); - out->next(); + bool empty = true; + for (auto & column : columns) + empty = empty && column->empty(); + + if (!empty) + { + block.setColumns(std::move(columns)); + + initProfileEventsBlockOutput(block); + + writeVarUInt(Protocol::Server::ProfileEvents, *out); + writeStringBinary("", *out); + + state.profile_events_block_out->write(block); + out->next(); + LOG_DEBUG(log, "Sent ProfileEvents packet {} data from queue", (from_queue ? "with" : "without")); + } } diff --git a/src/Server/TCPHandler.h b/src/Server/TCPHandler.h index 9ff061e096b..b5d7d1f0776 100644 --- a/src/Server/TCPHandler.h +++ b/src/Server/TCPHandler.h @@ -48,6 +48,7 @@ struct QueryState InternalTextLogsQueuePtr logs_queue; std::unique_ptr logs_block_out; + InternalProfileEventsQueuePtr profile_queue; std::unique_ptr profile_events_block_out; /// From where to read data for INSERT. From 9071a7151ef7171c22c27570d95ddb2a018f12f6 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 7 Sep 2021 15:07:24 +0300 Subject: [PATCH 201/264] Fix communication & race conditions --- src/Common/ThreadStatus.cpp | 6 +++++ src/Server/TCPHandler.cpp | 46 ++++++++++++++++++++++++------------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/Common/ThreadStatus.cpp b/src/Common/ThreadStatus.cpp index 4c49e9b1d0d..d521106a29b 100644 --- a/src/Common/ThreadStatus.cpp +++ b/src/Common/ThreadStatus.cpp @@ -142,6 +142,12 @@ ThreadStatus::~ThreadStatus() /// We've already allocated a little bit more than the limit and cannot track it in the thread memory tracker or its parent. } + if (thread_group) + { + std::lock_guard guard(thread_group->mutex); + thread_group->threads.erase(this); + } + #if !defined(ARCADIA_BUILD) /// It may cause segfault if query_context was destroyed, but was not detached auto query_context_ptr = query_context.lock(); diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index f1014d611fd..581cba91356 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include #include #include @@ -835,6 +837,14 @@ namespace constexpr size_t NAME_COLUMN_INDEX = 4; constexpr size_t VALUE_COLUMN_INDEX = 5; + struct ProfileEventsSnapshot + { + UInt64 thread_id; + ProfileEvents::Counters counters; + CurrentMetrics::Metric metric; + time_t current_time; + }; + /* * Add records about provided non-zero ProfileEvents::Counters. */ @@ -873,12 +883,11 @@ namespace } void dumpMemoryTracker( - MemoryTracker * memoryTracker, + CurrentMetrics::Metric metric, MutableColumns & columns, String const & host_name, UInt64 thread_id) { - auto metric = memoryTracker->getMetric(); if (metric == CurrentMetrics::end()) return; time_t current_time = time(nullptr); @@ -923,20 +932,28 @@ void TCPHandler::sendProfileEvents() MutableColumns columns = block.mutateColumns(); auto thread_group = CurrentThread::getGroup(); - std::vector threads; + std::vector snapshots; { std::lock_guard guard(thread_group->mutex); - std::copy(thread_group->threads.begin(), thread_group->threads.end(), std::back_inserter(threads)); + for (auto * thread : thread_group->threads) + { + auto current_time = time(nullptr); + auto counters = thread->performance_counters.getPartiallyAtomicSnapshot(); + auto metric = thread->memory_tracker.getMetric(); + auto const thread_id = CurrentThread::get().thread_id; + snapshots.push_back(ProfileEventsSnapshot{thread_id, std::move(counters), metric, current_time}); + } } - for (auto * thread : threads) - { - auto const counters_snapshot = thread->performance_counters.getPartiallyAtomicSnapshot(); - auto current_time = time(nullptr); - auto * memory_tracker = &thread->memory_tracker; - auto const thread_id = CurrentThread::get().thread_id; - dumpProfileEvents(counters_snapshot, columns, server_display_name, current_time, thread_id); - dumpMemoryTracker(memory_tracker, columns, server_display_name, thread_id); + for (auto & snapshot : snapshots) + { + dumpProfileEvents( + snapshot.counters, + columns, + server_display_name, + snapshot.current_time, + snapshot.thread_id); + dumpMemoryTracker(snapshot.metric, columns, server_display_name, snapshot.thread_id); } MutableColumns logs_columns; @@ -952,10 +969,7 @@ void TCPHandler::sendProfileEvents() columns[j]->insertRangeFrom(*curr_columns[j], 0, curr_columns[j]->size()); } - bool empty = true; - for (auto & column : columns) - empty = empty && column->empty(); - + bool empty = columns[0]->empty(); if (!empty) { block.setColumns(std::move(columns)); From 15ac65aa33fa77f6fa7ff0d67d40db3043f4d634 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 14 Sep 2021 14:06:00 +0300 Subject: [PATCH 202/264] Add thread usage info on client side --- src/Client/ClientBase.cpp | 16 +++++++++++++--- src/Client/ClientBase.h | 2 +- src/Common/ProgressIndication.cpp | 9 +++++++++ src/Common/ProgressIndication.h | 8 ++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index ee5f3580050..988f008fef7 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -9,6 +9,8 @@ #include #include #include +#include "Columns/ColumnsNumber.h" +#include "Core/Block.h" #include "Core/Protocol.h" #if !defined(ARCADIA_BUILD) @@ -613,7 +615,7 @@ bool ClientBase::receiveAndProcessPacket(ASTPtr parsed_query, bool cancelled) return false; case Protocol::Server::ProfileEvents: - onProfileEvents(); + onProfileEvents(packet.block); return true; default: @@ -656,8 +658,16 @@ void ClientBase::onEndOfStream() } -void ClientBase::onProfileEvents() -{} +void ClientBase::onProfileEvents(Block & block) +{ + if (block.rows() == 0) + return; + const auto & array_thread_id = typeid_cast(*block.getByName("thread_id").column).getData(); + for (size_t i = 0; i < block.rows(); ++i) + { + progress_indication.addThreadIdToList(array_thread_id[i]); + } +} /// Flush all buffers. diff --git a/src/Client/ClientBase.h b/src/Client/ClientBase.h index 0fa205a4d6e..070b676366c 100644 --- a/src/Client/ClientBase.h +++ b/src/Client/ClientBase.h @@ -114,7 +114,7 @@ private: void onReceiveExceptionFromServer(std::unique_ptr && e); void onProfileInfo(const BlockStreamProfileInfo & profile_info); void onEndOfStream(); - void onProfileEvents(); + void onProfileEvents(Block & block); void sendData(Block & sample, const ColumnsDescription & columns_description, ASTPtr parsed_query); void sendDataFrom(ReadBuffer & buf, Block & sample, diff --git a/src/Common/ProgressIndication.cpp b/src/Common/ProgressIndication.cpp index 0d65eaece86..02bb7d202d7 100644 --- a/src/Common/ProgressIndication.cpp +++ b/src/Common/ProgressIndication.cpp @@ -29,6 +29,7 @@ void ProgressIndication::resetProgress() show_progress_bar = false; written_progress_chars = 0; write_progress_on_update = false; + thread_ids.clear(); } void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool write_progress_on_update_) @@ -43,6 +44,11 @@ void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool }); } +void ProgressIndication::addThreadIdToList(UInt64 thread_id) +{ + thread_ids.insert(thread_id); +} + void ProgressIndication::writeFinalProgress() { if (progress.read_rows < 1000) @@ -57,6 +63,9 @@ void ProgressIndication::writeFinalProgress() << formatReadableSizeWithDecimalSuffix(progress.read_bytes * 1000000000.0 / elapsed_ns) << "/s.)"; else std::cout << ". "; + size_t used_threads = getUsedThreadsCount(); + if (used_threads != 0) + std::cout << "\nUsed threads to process: " << used_threads << "."; } void ProgressIndication::writeProgress() diff --git a/src/Common/ProgressIndication.h b/src/Common/ProgressIndication.h index 044d8cb1a89..ba7889c7326 100644 --- a/src/Common/ProgressIndication.h +++ b/src/Common/ProgressIndication.h @@ -1,7 +1,9 @@ #pragma once +#include #include #include +#include #include @@ -41,6 +43,10 @@ public: /// How much seconds passed since query execution start. double elapsedSeconds() const { return watch.elapsedSeconds(); } + void addThreadIdToList(UInt64 thread_id); + + size_t getUsedThreadsCount() const { return thread_ids.size(); } + private: /// This flag controls whether to show the progress bar. We start showing it after /// the query has been executing for 0.5 seconds, and is still less than half complete. @@ -58,6 +64,8 @@ private: Stopwatch watch; bool write_progress_on_update = false; + + std::unordered_set thread_ids; }; } From 4c6b3c40f2f3b854b85c5ff640ad9ee0f3bbe704 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 14 Sep 2021 16:24:57 +0300 Subject: [PATCH 203/264] Calculate approximate cores number used --- src/Client/ClientBase.cpp | 26 +++++++++++++++++++- src/Common/ProgressIndication.cpp | 41 ++++++++++++++++++++++++++++--- src/Common/ProgressIndication.h | 17 +++++++++++-- 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index 988f008fef7..5e0e11d103e 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -9,6 +9,7 @@ #include #include #include +#include "Columns/ColumnString.h" #include "Columns/ColumnsNumber.h" #include "Core/Block.h" #include "Core/Protocol.h" @@ -75,6 +76,12 @@ namespace ErrorCodes } +namespace ProfileEvents +{ + extern const Event UserTimeMicroseconds; + extern const Event SystemTimeMicroseconds; +} + namespace DB { @@ -663,9 +670,26 @@ void ClientBase::onProfileEvents(Block & block) if (block.rows() == 0) return; const auto & array_thread_id = typeid_cast(*block.getByName("thread_id").column).getData(); + const auto & names = typeid_cast(*block.getByName("name").column); + const auto & array_values = typeid_cast(*block.getByName("value").column).getData(); + + auto const * user_time_name = ProfileEvents::getName(ProfileEvents::UserTimeMicroseconds); + auto const * system_time_name = ProfileEvents::getName(ProfileEvents::SystemTimeMicroseconds); + for (size_t i = 0; i < block.rows(); ++i) { - progress_indication.addThreadIdToList(array_thread_id[i]); + auto thread_id = array_thread_id[i]; + progress_indication.addThreadIdToList(thread_id); + auto event_name = names.getDataAt(i); + auto value = array_values[i]; + if (event_name == user_time_name) + { + progress_indication.updateThreadUserTime(thread_id, value); + } + else if (event_name == system_time_name) + { + progress_indication.updateThreadSystemTime(thread_id, value); + } } } diff --git a/src/Common/ProgressIndication.cpp b/src/Common/ProgressIndication.cpp index 02bb7d202d7..ceb039b15f5 100644 --- a/src/Common/ProgressIndication.cpp +++ b/src/Common/ProgressIndication.cpp @@ -1,5 +1,8 @@ #include "ProgressIndication.h" +#include +#include #include +#include #include #include #include @@ -29,7 +32,7 @@ void ProgressIndication::resetProgress() show_progress_bar = false; written_progress_chars = 0; write_progress_on_update = false; - thread_ids.clear(); + thread_times.clear(); } void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool write_progress_on_update_) @@ -46,7 +49,28 @@ void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool void ProgressIndication::addThreadIdToList(UInt64 thread_id) { - thread_ids.insert(thread_id); + if (thread_times.contains(thread_id)) + return; + thread_times[thread_id] = {}; +} + +void ProgressIndication::updateThreadUserTime(UInt64 thread_id, UInt64 value) +{ + thread_times[thread_id].user_ms = value; +} + +void ProgressIndication::updateThreadSystemTime(UInt64 thread_id, UInt64 value) +{ + thread_times[thread_id].system_ms = value; +} + +UInt64 ProgressIndication::getAccumulatedThreadTime() const +{ + return std::accumulate(thread_times.cbegin(), thread_times.cend(), static_cast(0), + [](UInt64 acc, auto const & elem) + { + return acc + elem.second.user_ms + elem.second.system_ms; + }); } void ProgressIndication::writeFinalProgress() @@ -63,9 +87,20 @@ void ProgressIndication::writeFinalProgress() << formatReadableSizeWithDecimalSuffix(progress.read_bytes * 1000000000.0 / elapsed_ns) << "/s.)"; else std::cout << ". "; + size_t used_threads = getUsedThreadsCount(); if (used_threads != 0) - std::cout << "\nUsed threads to process: " << used_threads << "."; + { + std::cout << "\nUsed threads to process: " << used_threads; + + auto elapsed_ms = watch.elapsedMicroseconds(); + auto accumulated_thread_times = getAccumulatedThreadTime(); + auto approximate_core_number = (accumulated_thread_times + elapsed_ms - 1) / elapsed_ms; + if (approximate_core_number != 0) + std::cout << " and cores: " << approximate_core_number << "."; + else + std::cout << "."; + } } void ProgressIndication::writeProgress() diff --git a/src/Common/ProgressIndication.h b/src/Common/ProgressIndication.h index ba7889c7326..7517853f74d 100644 --- a/src/Common/ProgressIndication.h +++ b/src/Common/ProgressIndication.h @@ -45,9 +45,16 @@ public: void addThreadIdToList(UInt64 thread_id); - size_t getUsedThreadsCount() const { return thread_ids.size(); } + void updateThreadUserTime(UInt64 thread_id, UInt64 value); + + void updateThreadSystemTime(UInt64 thread_id, UInt64 value); private: + + size_t getUsedThreadsCount() const { return thread_times.size(); } + + UInt64 getAccumulatedThreadTime() const; + /// This flag controls whether to show the progress bar. We start showing it after /// the query has been executing for 0.5 seconds, and is still less than half complete. bool show_progress_bar = false; @@ -65,7 +72,13 @@ private: bool write_progress_on_update = false; - std::unordered_set thread_ids; + struct ThreadTime + { + UInt64 user_ms = 0; + UInt64 system_ms = 0; + }; + + std::unordered_map thread_times; }; } From 7e3caf96bec1afefe26eff8639515ad869e635de Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Wed, 15 Sep 2021 18:45:43 +0300 Subject: [PATCH 204/264] Fix cores approximation --- src/Client/ClientBase.cpp | 9 +++-- src/Common/ProgressIndication.cpp | 56 +++++++++++++++++++++++-------- src/Common/ProgressIndication.h | 16 +++++---- src/Server/TCPHandler.cpp | 11 +++++- 4 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index 5e0e11d103e..6a05ebd7c1b 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -671,6 +671,7 @@ void ClientBase::onProfileEvents(Block & block) return; const auto & array_thread_id = typeid_cast(*block.getByName("thread_id").column).getData(); const auto & names = typeid_cast(*block.getByName("name").column); + const auto & host_names = typeid_cast(*block.getByName("host_name").column); const auto & array_values = typeid_cast(*block.getByName("value").column).getData(); auto const * user_time_name = ProfileEvents::getName(ProfileEvents::UserTimeMicroseconds); @@ -679,16 +680,18 @@ void ClientBase::onProfileEvents(Block & block) for (size_t i = 0; i < block.rows(); ++i) { auto thread_id = array_thread_id[i]; - progress_indication.addThreadIdToList(thread_id); + auto host_name = host_names.getDataAt(i).toString(); + if (thread_id != 0) + progress_indication.addThreadIdToList(host_name, thread_id); auto event_name = names.getDataAt(i); auto value = array_values[i]; if (event_name == user_time_name) { - progress_indication.updateThreadUserTime(thread_id, value); + progress_indication.updateThreadUserTime(host_name, thread_id, value); } else if (event_name == system_time_name) { - progress_indication.updateThreadSystemTime(thread_id, value); + progress_indication.updateThreadSystemTime(host_name, thread_id, value); } } } diff --git a/src/Common/ProgressIndication.cpp b/src/Common/ProgressIndication.cpp index ceb039b15f5..b06df1bba15 100644 --- a/src/Common/ProgressIndication.cpp +++ b/src/Common/ProgressIndication.cpp @@ -1,4 +1,5 @@ #include "ProgressIndication.h" +#include #include #include #include @@ -8,6 +9,11 @@ #include +namespace +{ + constexpr UInt64 ZERO = 0; +} + namespace DB { @@ -47,29 +53,53 @@ void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool }); } -void ProgressIndication::addThreadIdToList(UInt64 thread_id) +void ProgressIndication::addThreadIdToList(String const & host, UInt64 thread_id) { - if (thread_times.contains(thread_id)) + auto & thread_to_times = thread_times[host]; + if (thread_to_times.contains(thread_id)) return; - thread_times[thread_id] = {}; + thread_to_times[thread_id] = {}; } -void ProgressIndication::updateThreadUserTime(UInt64 thread_id, UInt64 value) +void ProgressIndication::updateThreadUserTime(String const & host, UInt64 thread_id, UInt64 value) { - thread_times[thread_id].user_ms = value; + thread_times[host][thread_id].user_ms = value; } -void ProgressIndication::updateThreadSystemTime(UInt64 thread_id, UInt64 value) +void ProgressIndication::updateThreadSystemTime(String const & host, UInt64 thread_id, UInt64 value) { - thread_times[thread_id].system_ms = value; + thread_times[host][thread_id].system_ms = value; } -UInt64 ProgressIndication::getAccumulatedThreadTime() const +size_t ProgressIndication::getUsedThreadsCount() const { - return std::accumulate(thread_times.cbegin(), thread_times.cend(), static_cast(0), - [](UInt64 acc, auto const & elem) + return std::accumulate(thread_times.cbegin(), thread_times.cend(), 0, + [] (size_t acc, auto const & threads) { - return acc + elem.second.user_ms + elem.second.system_ms; + return acc + threads.second.size(); + }); +} + +UInt64 ProgressIndication::getApproximateCoresNumber() const +{ + return std::accumulate(thread_times.cbegin(), thread_times.cend(), ZERO, + [](UInt64 acc, auto const & threads) + { + auto total_time = std::accumulate(threads.second.cbegin(), threads.second.cend(), ZERO, + [] (UInt64 temp, auto const & elem) + { + if (elem.first == 0) + return temp; + return temp + elem.second.user_ms + elem.second.system_ms; + }); + // Zero thread_id represents thread group which execute query + // (including thread of TCPHandler). + auto const & accumulated_time = threads.second.find(ZERO)->second; + // Performance events of TCPHandler thread are not transmitted, but + // we can calculate it's working time which shows how long the query + // is being processed. + auto io_time = accumulated_time.user_ms + accumulated_time.system_ms - total_time; + return acc + (total_time + io_time - 1) / io_time; }); } @@ -93,9 +123,7 @@ void ProgressIndication::writeFinalProgress() { std::cout << "\nUsed threads to process: " << used_threads; - auto elapsed_ms = watch.elapsedMicroseconds(); - auto accumulated_thread_times = getAccumulatedThreadTime(); - auto approximate_core_number = (accumulated_thread_times + elapsed_ms - 1) / elapsed_ms; + auto approximate_core_number = getApproximateCoresNumber(); if (approximate_core_number != 0) std::cout << " and cores: " << approximate_core_number << "."; else diff --git a/src/Common/ProgressIndication.h b/src/Common/ProgressIndication.h index 7517853f74d..f1d7d214f4f 100644 --- a/src/Common/ProgressIndication.h +++ b/src/Common/ProgressIndication.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -43,17 +44,17 @@ public: /// How much seconds passed since query execution start. double elapsedSeconds() const { return watch.elapsedSeconds(); } - void addThreadIdToList(UInt64 thread_id); + void addThreadIdToList(String const & host, UInt64 thread_id); - void updateThreadUserTime(UInt64 thread_id, UInt64 value); + void updateThreadUserTime(String const & host, UInt64 thread_id, UInt64 value); - void updateThreadSystemTime(UInt64 thread_id, UInt64 value); + void updateThreadSystemTime(String const & host, UInt64 thread_id, UInt64 value); private: - size_t getUsedThreadsCount() const { return thread_times.size(); } + size_t getUsedThreadsCount() const; - UInt64 getAccumulatedThreadTime() const; + UInt64 getApproximateCoresNumber() const; /// This flag controls whether to show the progress bar. We start showing it after /// the query has been executing for 0.5 seconds, and is still less than half complete. @@ -78,7 +79,10 @@ private: UInt64 system_ms = 0; }; - std::unordered_map thread_times; + using ThreadIdToTimeMap = std::unordered_map; + using HostToThreadTimesMap = std::unordered_map; + + HostToThreadTimesMap thread_times; }; } diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index 581cba91356..c24bf599527 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -932,19 +932,28 @@ void TCPHandler::sendProfileEvents() MutableColumns columns = block.mutateColumns(); auto thread_group = CurrentThread::getGroup(); + auto const current_thread_id = CurrentThread::get().thread_id; std::vector snapshots; + ProfileEventsSnapshot group_snapshot; { std::lock_guard guard(thread_group->mutex); for (auto * thread : thread_group->threads) { + auto const thread_id = thread->thread_id; + if (thread_id == current_thread_id) + continue; auto current_time = time(nullptr); auto counters = thread->performance_counters.getPartiallyAtomicSnapshot(); auto metric = thread->memory_tracker.getMetric(); - auto const thread_id = CurrentThread::get().thread_id; snapshots.push_back(ProfileEventsSnapshot{thread_id, std::move(counters), metric, current_time}); } + group_snapshot.counters = thread_group->performance_counters.getPartiallyAtomicSnapshot(); + group_snapshot.metric = thread_group->memory_tracker.getMetric(); + group_snapshot.current_time = time(nullptr); } + dumpProfileEvents(group_snapshot.counters, columns, server_display_name, group_snapshot.current_time, 0); + dumpMemoryTracker(group_snapshot.metric, columns, server_display_name, 0); for (auto & snapshot : snapshots) { dumpProfileEvents( From 1d2e2d73057ebd9dd791cf9e4f98107da2fd5e88 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Wed, 15 Sep 2021 23:35:04 +0300 Subject: [PATCH 205/264] cleanup --- src/DataStreams/RemoteQueryExecutor.cpp | 1 - src/Server/TCPHandler.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/DataStreams/RemoteQueryExecutor.cpp b/src/DataStreams/RemoteQueryExecutor.cpp index 51c5c2edc57..aa316e54e6f 100644 --- a/src/DataStreams/RemoteQueryExecutor.cpp +++ b/src/DataStreams/RemoteQueryExecutor.cpp @@ -396,7 +396,6 @@ std::optional RemoteQueryExecutor::processPacket(Packet packet) case Protocol::Server::ProfileEvents: /// Pass profile events from remote server to client { - LOG_DEBUG(log, "RemoteQueryExecutor received ProfileEvents"); auto profile_queue = CurrentThread::getInternalProfileEventsQueue(); profile_queue->emplace(std::move(packet.block)); break; diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index c24bf599527..04b85125d66 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -675,10 +675,10 @@ void TCPHandler::processOrdinaryQueryWithProcessors() /// Some time passed and there is a progress. after_send_progress.restart(); sendProgress(); + sendProfileEvents(); } sendLogs(); - sendProfileEvents(); if (block) { @@ -701,7 +701,7 @@ void TCPHandler::processOrdinaryQueryWithProcessors() sendProfileInfo(executor.getProfileInfo()); sendProgress(); sendLogs(); - // sendProfileEvents(); + sendProfileEvents(); } if (state.is_connection_closed) From 73df6190df357ecf219be454d116321a89c3319e Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Fri, 17 Sep 2021 18:00:13 +0300 Subject: [PATCH 206/264] Cleanup code --- src/Client/ClientBase.cpp | 6 ++- src/Client/Connection.cpp | 1 - src/Common/ProgressIndication.cpp | 69 ++++++++++++++++++++----------- src/Common/ProgressIndication.h | 25 +++++------ src/Server/TCPHandler.cpp | 12 +++--- 5 files changed, 67 insertions(+), 46 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index 6a05ebd7c1b..b3148525f8c 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -677,6 +677,7 @@ void ClientBase::onProfileEvents(Block & block) auto const * user_time_name = ProfileEvents::getName(ProfileEvents::UserTimeMicroseconds); auto const * system_time_name = ProfileEvents::getName(ProfileEvents::SystemTimeMicroseconds); + HostToThreadTimesMap thread_times; for (size_t i = 0; i < block.rows(); ++i) { auto thread_id = array_thread_id[i]; @@ -687,13 +688,14 @@ void ClientBase::onProfileEvents(Block & block) auto value = array_values[i]; if (event_name == user_time_name) { - progress_indication.updateThreadUserTime(host_name, thread_id, value); + thread_times[host_name][thread_id].user_ms = value; } else if (event_name == system_time_name) { - progress_indication.updateThreadSystemTime(host_name, thread_id, value); + thread_times[host_name][thread_id].system_ms = value; } } + progress_indication.updateThreadTimes(thread_times); } diff --git a/src/Client/Connection.cpp b/src/Client/Connection.cpp index c6badf96bf9..40f74bcf9a7 100644 --- a/src/Client/Connection.cpp +++ b/src/Client/Connection.cpp @@ -873,7 +873,6 @@ Packet Connection::receivePacket() return res; case Protocol::Server::ProfileEvents: - LOG_DEBUG(log_wrapper.get(), "Connection received ProfileEvents"); res.block = receiveProfileEvents(); return res; diff --git a/src/Common/ProgressIndication.cpp b/src/Common/ProgressIndication.cpp index b06df1bba15..9a87a86c76b 100644 --- a/src/Common/ProgressIndication.cpp +++ b/src/Common/ProgressIndication.cpp @@ -12,6 +12,28 @@ namespace { constexpr UInt64 ZERO = 0; + + UInt64 calculateNewCoresNumber(DB::ThreadIdToTimeMap const & prev, DB::ThreadIdToTimeMap const& next) + { + if (next.find(ZERO) == next.end()) + return ZERO; + auto accumulated = std::accumulate(next.cbegin(), next.cend(), ZERO, + [&prev](UInt64 acc, auto const & elem) + { + if (elem.first == ZERO) + return acc; + auto thread_time = elem.second.time(); + auto it = prev.find(elem.first); + if (it != prev.end()) + thread_time -= it->second.time(); + return acc + thread_time; + }); + + auto elapsed = next.at(ZERO).time() - (prev.contains(ZERO) ? prev.at(ZERO).time() : ZERO); + if (elapsed == ZERO) + return ZERO; + return (accumulated + elapsed - 1) / elapsed; + } } namespace DB @@ -38,6 +60,7 @@ void ProgressIndication::resetProgress() show_progress_bar = false; written_progress_chars = 0; write_progress_on_update = false; + host_active_cores.clear(); thread_times.clear(); } @@ -61,14 +84,15 @@ void ProgressIndication::addThreadIdToList(String const & host, UInt64 thread_id thread_to_times[thread_id] = {}; } -void ProgressIndication::updateThreadUserTime(String const & host, UInt64 thread_id, UInt64 value) +void ProgressIndication::updateThreadTimes(HostToThreadTimesMap & new_thread_times) { - thread_times[host][thread_id].user_ms = value; -} - -void ProgressIndication::updateThreadSystemTime(String const & host, UInt64 thread_id, UInt64 value) -{ - thread_times[host][thread_id].system_ms = value; + for (auto & new_host_map : new_thread_times) + { + auto & host_map = thread_times[new_host_map.first]; + auto new_cores = calculateNewCoresNumber(host_map, new_host_map.second); + host_active_cores[new_host_map.first] = new_cores; + host_map = std::move(new_host_map.second); + } } size_t ProgressIndication::getUsedThreadsCount() const @@ -82,24 +106,10 @@ size_t ProgressIndication::getUsedThreadsCount() const UInt64 ProgressIndication::getApproximateCoresNumber() const { - return std::accumulate(thread_times.cbegin(), thread_times.cend(), ZERO, - [](UInt64 acc, auto const & threads) + return std::accumulate(host_active_cores.cbegin(), host_active_cores.cend(), ZERO, + [](UInt64 acc, auto const & elem) { - auto total_time = std::accumulate(threads.second.cbegin(), threads.second.cend(), ZERO, - [] (UInt64 temp, auto const & elem) - { - if (elem.first == 0) - return temp; - return temp + elem.second.user_ms + elem.second.system_ms; - }); - // Zero thread_id represents thread group which execute query - // (including thread of TCPHandler). - auto const & accumulated_time = threads.second.find(ZERO)->second; - // Performance events of TCPHandler thread are not transmitted, but - // we can calculate it's working time which shows how long the query - // is being processed. - auto io_time = accumulated_time.user_ms + accumulated_time.system_ms - total_time; - return acc + (total_time + io_time - 1) / io_time; + return acc + elem.second; }); } @@ -220,6 +230,17 @@ void ProgressIndication::writeProgress() message << ' ' << (99 * current_count / max_count) << '%'; } + // If approximate cores number is known, display it. + auto cores_number = getApproximateCoresNumber(); + if (cores_number != 0) + { + // Calculated cores number may be not accurate + // so it's better to print min(threads, cores). + auto threads_number = getUsedThreadsCount(); + message << " Running " << threads_number << " threads on " + << std::min(cores_number, threads_number) << " cores."; + } + message << CLEAR_TO_END_OF_LINE; ++increment; diff --git a/src/Common/ProgressIndication.h b/src/Common/ProgressIndication.h index f1d7d214f4f..4a98b5e849b 100644 --- a/src/Common/ProgressIndication.h +++ b/src/Common/ProgressIndication.h @@ -14,6 +14,17 @@ namespace DB { +struct ThreadTime +{ + UInt64 time() const noexcept { return user_ms + system_ms; } + + UInt64 user_ms = 0; + UInt64 system_ms = 0; +}; + +using ThreadIdToTimeMap = std::unordered_map; +using HostToThreadTimesMap = std::unordered_map; + class ProgressIndication { public: @@ -46,9 +57,7 @@ public: void addThreadIdToList(String const & host, UInt64 thread_id); - void updateThreadUserTime(String const & host, UInt64 thread_id, UInt64 value); - - void updateThreadSystemTime(String const & host, UInt64 thread_id, UInt64 value); + void updateThreadTimes(HostToThreadTimesMap & new_thread_times); private: @@ -73,15 +82,7 @@ private: bool write_progress_on_update = false; - struct ThreadTime - { - UInt64 user_ms = 0; - UInt64 system_ms = 0; - }; - - using ThreadIdToTimeMap = std::unordered_map; - using HostToThreadTimesMap = std::unordered_map; - + std::unordered_map host_active_cores; HostToThreadTimesMap thread_times; }; diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index 04b85125d66..9bca044617a 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -947,13 +947,12 @@ void TCPHandler::sendProfileEvents() auto metric = thread->memory_tracker.getMetric(); snapshots.push_back(ProfileEventsSnapshot{thread_id, std::move(counters), metric, current_time}); } - group_snapshot.counters = thread_group->performance_counters.getPartiallyAtomicSnapshot(); - group_snapshot.metric = thread_group->memory_tracker.getMetric(); + group_snapshot.current_time = time(nullptr); + group_snapshot.metric = thread_group->memory_tracker.getMetric(); + group_snapshot.counters = thread_group->performance_counters.getPartiallyAtomicSnapshot(); } - dumpProfileEvents(group_snapshot.counters, columns, server_display_name, group_snapshot.current_time, 0); - dumpMemoryTracker(group_snapshot.metric, columns, server_display_name, 0); for (auto & snapshot : snapshots) { dumpProfileEvents( @@ -964,15 +963,15 @@ void TCPHandler::sendProfileEvents() snapshot.thread_id); dumpMemoryTracker(snapshot.metric, columns, server_display_name, snapshot.thread_id); } + dumpProfileEvents(group_snapshot.counters, columns, server_display_name, group_snapshot.current_time, 0); + dumpMemoryTracker(group_snapshot.metric, columns, server_display_name, 0); MutableColumns logs_columns; Block curr_block; size_t rows = 0; - bool from_queue = false; for (; state.profile_queue->tryPop(curr_block); ++rows) { - from_queue = true; auto curr_columns = curr_block.getColumns(); for (size_t j = 0; j < curr_columns.size(); ++j) columns[j]->insertRangeFrom(*curr_columns[j], 0, curr_columns[j]->size()); @@ -990,7 +989,6 @@ void TCPHandler::sendProfileEvents() state.profile_events_block_out->write(block); out->next(); - LOG_DEBUG(log, "Sent ProfileEvents packet {} data from queue", (from_queue ? "with" : "without")); } } From 9f9af28b5ec5eb58f73c16f4d2737c3f284d163f Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Fri, 17 Sep 2021 19:47:54 +0300 Subject: [PATCH 207/264] Output memory usage with progress --- src/Client/ClientBase.cpp | 6 ++- src/Common/MemoryTracker.h | 3 ++ src/Common/ProgressIndication.cpp | 45 ++++++++++------- src/Common/ProgressIndication.h | 15 +++--- src/Server/TCPHandler.cpp | 82 ++++++++++++++++++------------- 5 files changed, 91 insertions(+), 60 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index b3148525f8c..1e104292e06 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -694,8 +694,12 @@ void ClientBase::onProfileEvents(Block & block) { thread_times[host_name][thread_id].system_ms = value; } + else if (event_name == MemoryTracker::USAGE_EVENT_NAME) + { + thread_times[host_name][thread_id].memory_usage = value; + } } - progress_indication.updateThreadTimes(thread_times); + progress_indication.updateThreadEventData(thread_times); } diff --git a/src/Common/MemoryTracker.h b/src/Common/MemoryTracker.h index 7da70db0876..ce0eef52e17 100644 --- a/src/Common/MemoryTracker.h +++ b/src/Common/MemoryTracker.h @@ -64,6 +64,9 @@ private: void setOrRaiseProfilerLimit(Int64 value); public: + + static constexpr auto USAGE_EVENT_NAME = "MemoryTrackerUsage"; + explicit MemoryTracker(VariableContext level_ = VariableContext::Thread); explicit MemoryTracker(MemoryTracker * parent_, VariableContext level_ = VariableContext::Thread); diff --git a/src/Common/ProgressIndication.cpp b/src/Common/ProgressIndication.cpp index 9a87a86c76b..189af2e9972 100644 --- a/src/Common/ProgressIndication.cpp +++ b/src/Common/ProgressIndication.cpp @@ -61,7 +61,7 @@ void ProgressIndication::resetProgress() written_progress_chars = 0; write_progress_on_update = false; host_active_cores.clear(); - thread_times.clear(); + thread_data.clear(); } void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool write_progress_on_update_) @@ -78,17 +78,17 @@ void ProgressIndication::setFileProgressCallback(ContextMutablePtr context, bool void ProgressIndication::addThreadIdToList(String const & host, UInt64 thread_id) { - auto & thread_to_times = thread_times[host]; + auto & thread_to_times = thread_data[host]; if (thread_to_times.contains(thread_id)) return; thread_to_times[thread_id] = {}; } -void ProgressIndication::updateThreadTimes(HostToThreadTimesMap & new_thread_times) +void ProgressIndication::updateThreadEventData(HostToThreadTimesMap & new_thread_data) { - for (auto & new_host_map : new_thread_times) + for (auto & new_host_map : new_thread_data) { - auto & host_map = thread_times[new_host_map.first]; + auto & host_map = thread_data[new_host_map.first]; auto new_cores = calculateNewCoresNumber(host_map, new_host_map.second); host_active_cores[new_host_map.first] = new_cores; host_map = std::move(new_host_map.second); @@ -97,7 +97,7 @@ void ProgressIndication::updateThreadTimes(HostToThreadTimesMap & new_thread_tim size_t ProgressIndication::getUsedThreadsCount() const { - return std::accumulate(thread_times.cbegin(), thread_times.cend(), 0, + return std::accumulate(thread_data.cbegin(), thread_data.cend(), 0, [] (size_t acc, auto const & threads) { return acc + threads.second.size(); @@ -113,6 +113,19 @@ UInt64 ProgressIndication::getApproximateCoresNumber() const }); } +UInt64 ProgressIndication::getMemoryUsage() const +{ + return std::accumulate(thread_data.cbegin(), thread_data.cend(), ZERO, + [](UInt64 acc, auto const & host_data) + { + return acc + std::accumulate(host_data.second.cbegin(), host_data.second.cend(), ZERO, + [](UInt64 memory, auto const & data) + { + return memory + data.second.memory_usage; + }); + }); +} + void ProgressIndication::writeFinalProgress() { if (progress.read_rows < 1000) @@ -127,18 +140,6 @@ void ProgressIndication::writeFinalProgress() << formatReadableSizeWithDecimalSuffix(progress.read_bytes * 1000000000.0 / elapsed_ns) << "/s.)"; else std::cout << ". "; - - size_t used_threads = getUsedThreadsCount(); - if (used_threads != 0) - { - std::cout << "\nUsed threads to process: " << used_threads; - - auto approximate_core_number = getApproximateCoresNumber(); - if (approximate_core_number != 0) - std::cout << " and cores: " << approximate_core_number << "."; - else - std::cout << "."; - } } void ProgressIndication::writeProgress() @@ -238,7 +239,13 @@ void ProgressIndication::writeProgress() // so it's better to print min(threads, cores). auto threads_number = getUsedThreadsCount(); message << " Running " << threads_number << " threads on " - << std::min(cores_number, threads_number) << " cores."; + << std::min(cores_number, threads_number) << " cores"; + + auto memory_usage = getMemoryUsage(); + if (memory_usage != 0) + message << " with " << formatReadableSizeWithDecimalSuffix(memory_usage) << " RAM used."; + else + message << "."; } message << CLEAR_TO_END_OF_LINE; diff --git a/src/Common/ProgressIndication.h b/src/Common/ProgressIndication.h index 4a98b5e849b..3d9bbc7f3ff 100644 --- a/src/Common/ProgressIndication.h +++ b/src/Common/ProgressIndication.h @@ -14,15 +14,16 @@ namespace DB { -struct ThreadTime +struct ThreadEventData { UInt64 time() const noexcept { return user_ms + system_ms; } - UInt64 user_ms = 0; - UInt64 system_ms = 0; + UInt64 user_ms = 0; + UInt64 system_ms = 0; + UInt64 memory_usage = 0; }; -using ThreadIdToTimeMap = std::unordered_map; +using ThreadIdToTimeMap = std::unordered_map; using HostToThreadTimesMap = std::unordered_map; class ProgressIndication @@ -57,7 +58,7 @@ public: void addThreadIdToList(String const & host, UInt64 thread_id); - void updateThreadTimes(HostToThreadTimesMap & new_thread_times); + void updateThreadEventData(HostToThreadTimesMap & new_thread_data); private: @@ -65,6 +66,8 @@ private: UInt64 getApproximateCoresNumber() const; + UInt64 getMemoryUsage() const; + /// This flag controls whether to show the progress bar. We start showing it after /// the query has been executing for 0.5 seconds, and is still less than half complete. bool show_progress_bar = false; @@ -83,7 +86,7 @@ private: bool write_progress_on_update = false; std::unordered_map host_active_cores; - HostToThreadTimesMap thread_times; + HostToThreadTimesMap thread_data; }; } diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index 9bca044617a..45a65f990df 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -842,6 +842,7 @@ namespace UInt64 thread_id; ProfileEvents::Counters counters; CurrentMetrics::Metric metric; + Int64 memory_usage; time_t current_time; }; @@ -849,18 +850,16 @@ namespace * Add records about provided non-zero ProfileEvents::Counters. */ void dumpProfileEvents( - ProfileEvents::Counters const & snapshot, + ProfileEventsSnapshot const & snapshot, MutableColumns & columns, - String const & host_name, - time_t current_time, - UInt64 thread_id) + String const & host_name) { size_t rows = 0; auto & name_column = columns[NAME_COLUMN_INDEX]; auto & value_column = columns[VALUE_COLUMN_INDEX]; for (ProfileEvents::Event event = 0; event < ProfileEvents::Counters::num_counters; ++event) { - UInt64 value = snapshot[event].load(std::memory_order_relaxed); + UInt64 value = snapshot.counters[event].load(std::memory_order_relaxed); if (value == 0) continue; @@ -876,32 +875,43 @@ namespace { size_t i = 0; columns[i++]->insertData(host_name.data(), host_name.size()); - columns[i++]->insert(UInt64(current_time)); - columns[i++]->insert(UInt64{thread_id}); + columns[i++]->insert(UInt64(snapshot.current_time)); + columns[i++]->insert(UInt64{snapshot.thread_id}); columns[i++]->insert(ProfileEventTypes::INCREMENT); } } void dumpMemoryTracker( - CurrentMetrics::Metric metric, + ProfileEventsSnapshot const & snapshot, MutableColumns & columns, - String const & host_name, - UInt64 thread_id) + String const & host_name) { - if (metric == CurrentMetrics::end()) - return; - time_t current_time = time(nullptr); + { + size_t i = 0; + columns[i++]->insertData(host_name.data(), host_name.size()); + columns[i++]->insert(UInt64(snapshot.current_time)); + columns[i++]->insert(UInt64{snapshot.thread_id}); + columns[i++]->insert(ProfileEventTypes::GAUGE); - size_t i = 0; - columns[i++]->insertData(host_name.data(), host_name.size()); - columns[i++]->insert(UInt64(current_time)); - columns[i++]->insert(UInt64{thread_id}); - columns[i++]->insert(ProfileEventTypes::GAUGE); + columns[i++]->insertData(MemoryTracker::USAGE_EVENT_NAME, strlen(MemoryTracker::USAGE_EVENT_NAME)); + columns[i++]->insert(snapshot.memory_usage); + } - auto const * metric_name = CurrentMetrics::getName(metric); - columns[i++]->insertData(metric_name, strlen(metric_name)); - auto metric_value = CurrentMetrics::get(metric); - columns[i++]->insert(metric_value); + if (snapshot.metric != CurrentMetrics::end()) + { + time_t current_time = time(nullptr); + + size_t i = 0; + columns[i++]->insertData(host_name.data(), host_name.size()); + columns[i++]->insert(UInt64(current_time)); + columns[i++]->insert(UInt64{snapshot.thread_id}); + columns[i++]->insert(ProfileEventTypes::GAUGE); + + auto const * metric_name = CurrentMetrics::getName(snapshot.metric); + columns[i++]->insertData(metric_name, strlen(metric_name)); + auto metric_value = CurrentMetrics::get(snapshot.metric); + columns[i++]->insert(metric_value); + } } } @@ -945,26 +955,30 @@ void TCPHandler::sendProfileEvents() auto current_time = time(nullptr); auto counters = thread->performance_counters.getPartiallyAtomicSnapshot(); auto metric = thread->memory_tracker.getMetric(); - snapshots.push_back(ProfileEventsSnapshot{thread_id, std::move(counters), metric, current_time}); + auto memory_usage = thread->memory_tracker.get(); + snapshots.push_back(ProfileEventsSnapshot{ + thread_id, + std::move(counters), + metric, + memory_usage, + current_time + }); } + group_snapshot.thread_id = 0; group_snapshot.current_time = time(nullptr); - group_snapshot.metric = thread_group->memory_tracker.getMetric(); - group_snapshot.counters = thread_group->performance_counters.getPartiallyAtomicSnapshot(); + group_snapshot.metric = thread_group->memory_tracker.getMetric(); + group_snapshot.memory_usage = thread_group->memory_tracker.get(); + group_snapshot.counters = thread_group->performance_counters.getPartiallyAtomicSnapshot(); } for (auto & snapshot : snapshots) { - dumpProfileEvents( - snapshot.counters, - columns, - server_display_name, - snapshot.current_time, - snapshot.thread_id); - dumpMemoryTracker(snapshot.metric, columns, server_display_name, snapshot.thread_id); + dumpProfileEvents(snapshot, columns, server_display_name); + dumpMemoryTracker(snapshot, columns, server_display_name); } - dumpProfileEvents(group_snapshot.counters, columns, server_display_name, group_snapshot.current_time, 0); - dumpMemoryTracker(group_snapshot.metric, columns, server_display_name, 0); + dumpProfileEvents(group_snapshot, columns, server_display_name); + dumpMemoryTracker(group_snapshot, columns, server_display_name); MutableColumns logs_columns; Block curr_block; From 0bdabf46f281a14d1138e2bd0956f10e746bc436 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Mon, 20 Sep 2021 18:59:27 +0300 Subject: [PATCH 208/264] Send ProfileEvents only to supported clients --- src/Core/ProtocolDefines.h | 4 +++- src/Server/TCPHandler.cpp | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Core/ProtocolDefines.h b/src/Core/ProtocolDefines.h index 37875305e75..6c62b969ff9 100644 --- a/src/Core/ProtocolDefines.h +++ b/src/Core/ProtocolDefines.h @@ -36,6 +36,8 @@ #define DBMS_MIN_PROTOCOL_VERSION_WITH_DISTRIBUTED_DEPTH 54448 +#define DBMS_MIN_PROTOCOL_VERSION_WITH_PROFILE_EVENTS 54450 + /// Version of ClickHouse TCP protocol. /// /// Should be incremented manually on protocol changes. @@ -43,6 +45,6 @@ /// NOTE: DBMS_TCP_PROTOCOL_VERSION has nothing common with VERSION_REVISION, /// later is just a number for server version (one number instead of commit SHA) /// for simplicity (sometimes it may be more convenient in some use cases). -#define DBMS_TCP_PROTOCOL_VERSION 54449 +#define DBMS_TCP_PROTOCOL_VERSION 54450 #define DBMS_MIN_PROTOCOL_VERSION_WITH_INITIAL_QUERY_START_TIME 54449 diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index 45a65f990df..c036715aea7 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -918,6 +918,9 @@ namespace void TCPHandler::sendProfileEvents() { + if (client_tcp_protocol_version < DBMS_MIN_PROTOCOL_VERSION_WITH_PROFILE_EVENTS) + return; + auto profile_event_type = std::make_shared( DataTypeEnum8::Values { From c1f3e7e0bb8f5073c056c635cf101bdae4c7a941 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 21 Sep 2021 00:47:48 +0300 Subject: [PATCH 209/264] Fix build --- src/Common/ProgressIndication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Common/ProgressIndication.cpp b/src/Common/ProgressIndication.cpp index 189af2e9972..0fe40b306cb 100644 --- a/src/Common/ProgressIndication.cpp +++ b/src/Common/ProgressIndication.cpp @@ -237,7 +237,7 @@ void ProgressIndication::writeProgress() { // Calculated cores number may be not accurate // so it's better to print min(threads, cores). - auto threads_number = getUsedThreadsCount(); + UInt64 threads_number = getUsedThreadsCount(); message << " Running " << threads_number << " threads on " << std::min(cores_number, threads_number) << " cores"; From 3a0764634e0be034c7e7ae93a4ec44a76d0e2b64 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 21 Sep 2021 00:52:01 +0300 Subject: [PATCH 210/264] Update InternalProfileEventsQueue usage --- src/DataStreams/RemoteQueryExecutor.cpp | 6 ++---- src/Server/TCPHandler.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/DataStreams/RemoteQueryExecutor.cpp b/src/DataStreams/RemoteQueryExecutor.cpp index aa316e54e6f..08d3db748b7 100644 --- a/src/DataStreams/RemoteQueryExecutor.cpp +++ b/src/DataStreams/RemoteQueryExecutor.cpp @@ -395,11 +395,9 @@ std::optional RemoteQueryExecutor::processPacket(Packet packet) case Protocol::Server::ProfileEvents: /// Pass profile events from remote server to client - { - auto profile_queue = CurrentThread::getInternalProfileEventsQueue(); + if (auto profile_queue = CurrentThread::getInternalProfileEventsQueue()) profile_queue->emplace(std::move(packet.block)); - break; - } + break; default: got_unknown_packet_from_replica = true; diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index c036715aea7..c25cb1dddfc 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -246,8 +246,11 @@ void TCPHandler::runImpl() sendLogs(); }); } - state.profile_queue = std::make_shared(std::numeric_limits::max()); - CurrentThread::attachInternalProfileEventsQueue(state.profile_queue); + if (client_tcp_protocol_version >= DBMS_MIN_PROTOCOL_VERSION_WITH_PROFILE_EVENTS) + { + state.profile_queue = std::make_shared(std::numeric_limits::max()); + CurrentThread::attachInternalProfileEventsQueue(state.profile_queue); + } query_context->setExternalTablesInitializer([this] (ContextPtr context) { From 9590c97a19f2330983e9ccbba5ba5fb7e5f16076 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Tue, 21 Sep 2021 15:29:04 +0300 Subject: [PATCH 211/264] Create ProfileEventsQueue in GRPCServer --- src/Server/GRPCServer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Server/GRPCServer.cpp b/src/Server/GRPCServer.cpp index fc712916372..d0e054677c0 100644 --- a/src/Server/GRPCServer.cpp +++ b/src/Server/GRPCServer.cpp @@ -1,4 +1,6 @@ #include "GRPCServer.h" +#include +#include #if USE_GRPC #include @@ -622,6 +624,7 @@ namespace BlockIO io; Progress progress; InternalTextLogsQueuePtr logs_queue; + InternalProfileEventsQueuePtr profile_queue; GRPCQueryInfo query_info; /// We reuse the same messages multiple times. GRPCResult result; @@ -773,6 +776,8 @@ namespace CurrentThread::attachInternalTextLogsQueue(logs_queue, client_logs_level); CurrentThread::setFatalErrorCallback([this]{ onFatalError(); }); } + profile_queue = std::make_shared(std::numeric_limits::max()); + CurrentThread::attachInternalProfileEventsQueue(profile_queue); /// Set the current database if specified. if (!query_info.database().empty()) From 7c3192735adda0ec7067dc4cfef92de47b9af938 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Wed, 6 Oct 2021 16:52:59 +0300 Subject: [PATCH 212/264] Reset profile events stream in Connection::sendQuery --- src/Client/Connection.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Client/Connection.cpp b/src/Client/Connection.cpp index 40f74bcf9a7..1531e6c1e91 100644 --- a/src/Client/Connection.cpp +++ b/src/Client/Connection.cpp @@ -537,6 +537,7 @@ void Connection::sendQuery( maybe_compressed_out.reset(); block_in.reset(); block_logs_in.reset(); + block_profile_events_in.reset(); block_out.reset(); /// Send empty block which means end of data. From bfdd34c13d24466e96e06b185690960d07d33bb4 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Mon, 11 Oct 2021 16:55:08 +0300 Subject: [PATCH 213/264] code cleanup --- src/Client/ClientBase.cpp | 9 +++++---- src/Server/GRPCServer.cpp | 11 ----------- src/Server/TCPHandler.cpp | 21 +-------------------- 3 files changed, 6 insertions(+), 35 deletions(-) diff --git a/src/Client/ClientBase.cpp b/src/Client/ClientBase.cpp index 1e104292e06..baf082a3541 100644 --- a/src/Client/ClientBase.cpp +++ b/src/Client/ClientBase.cpp @@ -667,18 +667,19 @@ void ClientBase::onEndOfStream() void ClientBase::onProfileEvents(Block & block) { - if (block.rows() == 0) + const auto rows = block.rows(); + if (rows == 0) return; const auto & array_thread_id = typeid_cast(*block.getByName("thread_id").column).getData(); const auto & names = typeid_cast(*block.getByName("name").column); const auto & host_names = typeid_cast(*block.getByName("host_name").column); const auto & array_values = typeid_cast(*block.getByName("value").column).getData(); - auto const * user_time_name = ProfileEvents::getName(ProfileEvents::UserTimeMicroseconds); - auto const * system_time_name = ProfileEvents::getName(ProfileEvents::SystemTimeMicroseconds); + const auto * user_time_name = ProfileEvents::getName(ProfileEvents::UserTimeMicroseconds); + const auto * system_time_name = ProfileEvents::getName(ProfileEvents::SystemTimeMicroseconds); HostToThreadTimesMap thread_times; - for (size_t i = 0; i < block.rows(); ++i) + for (size_t i = 0; i < rows; ++i) { auto thread_id = array_thread_id[i]; auto host_name = host_names.getDataAt(i).toString(); diff --git a/src/Server/GRPCServer.cpp b/src/Server/GRPCServer.cpp index d0e054677c0..3b01f3aedde 100644 --- a/src/Server/GRPCServer.cpp +++ b/src/Server/GRPCServer.cpp @@ -598,7 +598,6 @@ namespace void addExtremesToResult(const Block & extremes); void addProfileInfoToResult(const BlockStreamProfileInfo & info); void addLogsToResult(); - void addProfileEventsToResult(); void sendResult(); void throwIfFailedToSendResult(); void sendException(const Exception & exception); @@ -624,7 +623,6 @@ namespace BlockIO io; Progress progress; InternalTextLogsQueuePtr logs_queue; - InternalProfileEventsQueuePtr profile_queue; GRPCQueryInfo query_info; /// We reuse the same messages multiple times. GRPCResult result; @@ -776,8 +774,6 @@ namespace CurrentThread::attachInternalTextLogsQueue(logs_queue, client_logs_level); CurrentThread::setFatalErrorCallback([this]{ onFatalError(); }); } - profile_queue = std::make_shared(std::numeric_limits::max()); - CurrentThread::attachInternalProfileEventsQueue(profile_queue); /// Set the current database if specified. if (!query_info.database().empty()) @@ -1129,7 +1125,6 @@ namespace if (after_send_progress.elapsedMicroseconds() >= interactive_delay) { addProgressToResult(); - addProfileEventsToResult(); after_send_progress.restart(); } @@ -1181,7 +1176,6 @@ namespace finalize = true; io.onFinish(); addProgressToResult(); - addProfileEventsToResult(); query_scope->logPeakMemoryUsage(); addLogsToResult(); sendResult(); @@ -1445,11 +1439,6 @@ namespace } } - void Call::addProfileEventsToResult() - { - - } - void Call::sendResult() { /// gRPC doesn't allow to write anything to a finished responder. diff --git a/src/Server/TCPHandler.cpp b/src/Server/TCPHandler.cpp index c25cb1dddfc..2401b8614fa 100644 --- a/src/Server/TCPHandler.cpp +++ b/src/Server/TCPHandler.cpp @@ -844,7 +844,6 @@ namespace { UInt64 thread_id; ProfileEvents::Counters counters; - CurrentMetrics::Metric metric; Int64 memory_usage; time_t current_time; }; @@ -899,22 +898,6 @@ namespace columns[i++]->insertData(MemoryTracker::USAGE_EVENT_NAME, strlen(MemoryTracker::USAGE_EVENT_NAME)); columns[i++]->insert(snapshot.memory_usage); } - - if (snapshot.metric != CurrentMetrics::end()) - { - time_t current_time = time(nullptr); - - size_t i = 0; - columns[i++]->insertData(host_name.data(), host_name.size()); - columns[i++]->insert(UInt64(current_time)); - columns[i++]->insert(UInt64{snapshot.thread_id}); - columns[i++]->insert(ProfileEventTypes::GAUGE); - - auto const * metric_name = CurrentMetrics::getName(snapshot.metric); - columns[i++]->insertData(metric_name, strlen(metric_name)); - auto metric_value = CurrentMetrics::get(snapshot.metric); - columns[i++]->insert(metric_value); - } } } @@ -953,6 +936,7 @@ void TCPHandler::sendProfileEvents() ProfileEventsSnapshot group_snapshot; { std::lock_guard guard(thread_group->mutex); + snapshots.reserve(thread_group->threads.size()); for (auto * thread : thread_group->threads) { auto const thread_id = thread->thread_id; @@ -960,12 +944,10 @@ void TCPHandler::sendProfileEvents() continue; auto current_time = time(nullptr); auto counters = thread->performance_counters.getPartiallyAtomicSnapshot(); - auto metric = thread->memory_tracker.getMetric(); auto memory_usage = thread->memory_tracker.get(); snapshots.push_back(ProfileEventsSnapshot{ thread_id, std::move(counters), - metric, memory_usage, current_time }); @@ -973,7 +955,6 @@ void TCPHandler::sendProfileEvents() group_snapshot.thread_id = 0; group_snapshot.current_time = time(nullptr); - group_snapshot.metric = thread_group->memory_tracker.getMetric(); group_snapshot.memory_usage = thread_group->memory_tracker.get(); group_snapshot.counters = thread_group->performance_counters.getPartiallyAtomicSnapshot(); } From e6c088fe056b919374ec4bd53c10b2c3ef9794b0 Mon Sep 17 00:00:00 2001 From: Vladimir C Date: Mon, 11 Oct 2021 13:03:00 +0300 Subject: [PATCH 214/264] Mark join_engine_deadlock as long test --- ...adlock.reference => 02033_join_engine_deadlock_long.reference} | 0 ...join_engine_deadlock.sh => 02033_join_engine_deadlock_long.sh} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/queries/0_stateless/{02033_join_engine_deadlock.reference => 02033_join_engine_deadlock_long.reference} (100%) rename tests/queries/0_stateless/{02033_join_engine_deadlock.sh => 02033_join_engine_deadlock_long.sh} (100%) diff --git a/tests/queries/0_stateless/02033_join_engine_deadlock.reference b/tests/queries/0_stateless/02033_join_engine_deadlock_long.reference similarity index 100% rename from tests/queries/0_stateless/02033_join_engine_deadlock.reference rename to tests/queries/0_stateless/02033_join_engine_deadlock_long.reference diff --git a/tests/queries/0_stateless/02033_join_engine_deadlock.sh b/tests/queries/0_stateless/02033_join_engine_deadlock_long.sh similarity index 100% rename from tests/queries/0_stateless/02033_join_engine_deadlock.sh rename to tests/queries/0_stateless/02033_join_engine_deadlock_long.sh From 706e2b6b8816a3e9a5022341331227a1986987da Mon Sep 17 00:00:00 2001 From: Alexander Tokmakov Date: Mon, 11 Oct 2021 21:42:46 +0300 Subject: [PATCH 215/264] more strict check for intersecting parts --- src/Storages/MergeTree/MergeTreePartInfo.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Storages/MergeTree/MergeTreePartInfo.h b/src/Storages/MergeTree/MergeTreePartInfo.h index df3d9cb9237..82fe0b860c8 100644 --- a/src/Storages/MergeTree/MergeTreePartInfo.h +++ b/src/Storages/MergeTree/MergeTreePartInfo.h @@ -60,11 +60,16 @@ struct MergeTreePartInfo /// True if contains rhs (this part is obtained by merging rhs with some other parts or mutating rhs) bool contains(const MergeTreePartInfo & rhs) const { + /// Containing part may have equal level iff block numbers are equal (unless level is MAX_LEVEL) + /// (e.g. all_0_5_2 does not contain all_0_4_2, but all_0_5_3 or all_0_4_2_9 do) + bool strictly_contains_block_range = (min_block == rhs.min_block && max_block == rhs.max_block) || level > rhs.level + || level == MAX_LEVEL || level == LEGACY_MAX_LEVEL; return partition_id == rhs.partition_id /// Parts for different partitions are not merged && min_block <= rhs.min_block && max_block >= rhs.max_block && level >= rhs.level - && mutation >= rhs.mutation; + && mutation >= rhs.mutation + && strictly_contains_block_range; } /// Return part mutation version, if part wasn't mutated return zero From f1791ddc44e9dfe6644aa1f406e6b3924374e725 Mon Sep 17 00:00:00 2001 From: Denny Crane Date: Mon, 11 Oct 2021 15:49:30 -0300 Subject: [PATCH 216/264] explanation for volume/max_data_part_size_bytes --- docs/en/engines/table-engines/mergetree-family/mergetree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/engines/table-engines/mergetree-family/mergetree.md b/docs/en/engines/table-engines/mergetree-family/mergetree.md index f7118f7557e..4f473279067 100644 --- a/docs/en/engines/table-engines/mergetree-family/mergetree.md +++ b/docs/en/engines/table-engines/mergetree-family/mergetree.md @@ -688,7 +688,7 @@ Tags: - `policy_name_N` — Policy name. Policy names must be unique. - `volume_name_N` — Volume name. Volume names must be unique. - `disk` — a disk within a volume. -- `max_data_part_size_bytes` — the maximum size of a part that can be stored on any of the volume’s disks. +- `max_data_part_size_bytes` — the maximum size of a part that can be stored on any of the volume’s disks. If the a size of a merged part estimated to be bigger than `max_data_part_size_bytes` then this part will be written to a next volume. Basically this feature allows to keep new/small parts on a hot (SSD) volume and move them to a cold (HDD) volume when they reach large size. Do not use this setting if your policy has only one volume. - `move_factor` — when the amount of available space gets lower than this factor, data automatically start to move on the next volume if any (by default, 0.1). - `prefer_not_to_merge` — Disables merging of data parts on this volume. When this setting is enabled, merging data on this volume is not allowed. This allows controlling how ClickHouse works with slow disks. From fb83d2ddd593f914a465274566eb9bdca429ed55 Mon Sep 17 00:00:00 2001 From: Denny Crane Date: Mon, 11 Oct 2021 15:56:02 -0300 Subject: [PATCH 217/264] Update mergetree.md --- docs/ru/engines/table-engines/mergetree-family/mergetree.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/engines/table-engines/mergetree-family/mergetree.md b/docs/ru/engines/table-engines/mergetree-family/mergetree.md index e8152441101..bef14924d36 100644 --- a/docs/ru/engines/table-engines/mergetree-family/mergetree.md +++ b/docs/ru/engines/table-engines/mergetree-family/mergetree.md @@ -668,7 +668,7 @@ TTL d + INTERVAL 1 MONTH GROUP BY k1, k2 SET x = max(x), y = min(y); - `policy_name_N` — название политики. Названия политик должны быть уникальны. - `volume_name_N` — название тома. Названия томов должны быть уникальны. - `disk` — диск, находящийся внутри тома. -- `max_data_part_size_bytes` — максимальный размер куска данных, который может находится на любом из дисков этого тома. +- `max_data_part_size_bytes` — максимальный размер куска данных, который может находится на любом из дисков этого тома. Если в результате слияния размер куска ожидается больше, чем max_data_part_size_bytes, то этот кусок будет записан в следующий том. В основном эта функция позволяет хранить новые / мелкие куски на горячем (SSD) томе и перемещать их на холодный (HDD) том, когда они достигают большого размера. Не используйте этот параметр, если политика имеет только один том. - `move_factor` — доля доступного свободного места на томе, если места становится меньше, то данные начнут перемещение на следующий том, если он есть (по умолчанию 0.1). - `prefer_not_to_merge` — Отключает слияние кусков данных, хранящихся на данном томе. Если данная настройка включена, то слияние данных, хранящихся на данном томе, не допускается. Это позволяет контролировать работу ClickHouse с медленными дисками. From 381d666e4b368ba3d750bafea5399a076a27a5f5 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 11 Oct 2021 23:09:31 +0300 Subject: [PATCH 218/264] Ignore parallel removing warning in 00992_system_parts_race_condition_zookeeper_long CI: https://clickhouse-test-reports.s3.yandex.net/0/6c7fbf0b888db9c1272478189f0ff40212a3e7c9/functional_stateless_tests_(release,_databaseordinary)/test_run.txt.out.log --- .../00992_system_parts_race_condition_zookeeper_long.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper_long.sh b/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper_long.sh index 273b39961af..aee8a7727e5 100755 --- a/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper_long.sh +++ b/tests/queries/0_stateless/00992_system_parts_race_condition_zookeeper_long.sh @@ -79,7 +79,7 @@ timeout $TIMEOUT bash -c thread5 2> /dev/null & wait check_replication_consistency "alter_table" "count(), sum(a), sum(b), round(sum(c))" -$CLICKHOUSE_CLIENT -n -q "DROP TABLE alter_table0;" & -$CLICKHOUSE_CLIENT -n -q "DROP TABLE alter_table1;" & +$CLICKHOUSE_CLIENT -n -q "DROP TABLE alter_table0;" 2> >(grep -F -v 'is already started to be removing by another replica right now') & +$CLICKHOUSE_CLIENT -n -q "DROP TABLE alter_table1;" 2> >(grep -F -v 'is already started to be removing by another replica right now') & wait From 83a9a8d4dc8239035c4a0ff9c85658d17c78131b Mon Sep 17 00:00:00 2001 From: tavplubix Date: Mon, 11 Oct 2021 23:23:56 +0300 Subject: [PATCH 219/264] Update KeeperStateMachine.cpp --- src/Coordination/KeeperStateMachine.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Coordination/KeeperStateMachine.cpp b/src/Coordination/KeeperStateMachine.cpp index be4f73cf5ae..682a523fcaf 100644 --- a/src/Coordination/KeeperStateMachine.cpp +++ b/src/Coordination/KeeperStateMachine.cpp @@ -125,10 +125,6 @@ nuraft::ptr KeeperStateMachine::commit(const uint64_t log_idx, n } else { - LOG_TEST(log, "Commit request for session {} with type {}, log id {}{}", - request_for_session.session_id, toString(request_for_session.request->getOpNum()), log_idx, - request_for_session.request->getPath().empty() ? "" : ", path " + request_for_session.request->getPath()); - std::lock_guard lock(storage_and_responses_lock); KeeperStorage::ResponsesForSessions responses_for_sessions = storage->processRequest(request_for_session.request, request_for_session.session_id, log_idx); for (auto & response_for_session : responses_for_sessions) From d4e496c31424bfe428626ac3a18e5de1b13e13dc Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 01:47:34 +0300 Subject: [PATCH 220/264] Add support for PowerPC build --- cmake/linux/default_libs.cmake | 2 +- cmake/target.cmake | 13 +- contrib/CMakeLists.txt | 2 +- .../internal/jemalloc_internal_defs.h.in | 4 +- contrib/libuv-cmake/CMakeLists.txt | 160 ++++++++++++++++++ src/Interpreters/ITokenExtractor.cpp | 2 +- utils/CMakeLists.txt | 2 +- utils/memcpy-bench/CMakeLists.txt | 2 +- 8 files changed, 175 insertions(+), 12 deletions(-) create mode 100644 contrib/libuv-cmake/CMakeLists.txt diff --git a/cmake/linux/default_libs.cmake b/cmake/linux/default_libs.cmake index c1e4d450389..a2da7ba1915 100644 --- a/cmake/linux/default_libs.cmake +++ b/cmake/linux/default_libs.cmake @@ -5,7 +5,7 @@ set (DEFAULT_LIBS "-nodefaultlibs") # We need builtins from Clang's RT even without libcxx - for ubsan+int128. # See https://bugs.llvm.org/show_bug.cgi?id=16404 -if (COMPILER_CLANG AND NOT (CMAKE_CROSSCOMPILING AND ARCH_AARCH64)) +if (COMPILER_CLANG AND NOT CMAKE_CROSSCOMPILING) execute_process (COMMAND ${CMAKE_CXX_COMPILER} --print-libgcc-file-name --rtlib=compiler-rt OUTPUT_VARIABLE BUILTINS_LIBRARY OUTPUT_STRIP_TRAILING_WHITESPACE) else () set (BUILTINS_LIBRARY "-lgcc") diff --git a/cmake/target.cmake b/cmake/target.cmake index d1a0b8f9cbf..ca6009e68d3 100644 --- a/cmake/target.cmake +++ b/cmake/target.cmake @@ -34,11 +34,14 @@ if (CMAKE_CROSSCOMPILING) # FIXME: broken dependencies set (ENABLE_PROTOBUF OFF CACHE INTERNAL "") set (ENABLE_GRPC OFF CACHE INTERNAL "") - - set (ENABLE_PARQUET OFF CACHE INTERNAL "") - set (ENABLE_ORC OFF CACHE INTERNAL "") - - set (ENABLE_MYSQL OFF CACHE INTERNAL "") + set (USE_SENTRY OFF CACHE INTERNAL "") +# set (ENABLE_ROCKSDB OFF CACHE INTERNAL "") + endif () + elseif (ARCH_PPC64LE) + set (ENABLE_PROTOBUF OFF CACHE INTERNAL "") + set (ENABLE_GRPC OFF CACHE INTERNAL "") + set (USE_SENTRY OFF CACHE INTERNAL "") +# set (ENABLE_ROCKSDB OFF CACHE INTERNAL "") endif () elseif (OS_FREEBSD) # FIXME: broken dependencies diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index 4d817c4c6e2..5ff85fa85c2 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -278,7 +278,7 @@ if (USE_FASTOPS) endif() if (USE_AMQPCPP OR USE_CASSANDRA) - add_subdirectory (libuv) + add_subdirectory (libuv-cmake) endif() if (USE_AMQPCPP) add_subdirectory (amqpcpp-cmake) diff --git a/contrib/jemalloc-cmake/include_linux_ppc64le/jemalloc/internal/jemalloc_internal_defs.h.in b/contrib/jemalloc-cmake/include_linux_ppc64le/jemalloc/internal/jemalloc_internal_defs.h.in index 8068861041f..97d0d4d8471 100644 --- a/contrib/jemalloc-cmake/include_linux_ppc64le/jemalloc/internal/jemalloc_internal_defs.h.in +++ b/contrib/jemalloc-cmake/include_linux_ppc64le/jemalloc/internal/jemalloc_internal_defs.h.in @@ -81,7 +81,7 @@ /* #undef JEMALLOC_HAVE_ISSETUGID */ /* Defined if pthread_atfork(3) is available. */ -#define JEMALLOC_HAVE_PTHREAD_ATFORK +/* #undef JEMALLOC_HAVE_PTHREAD_ATFORK */ /* Defined if pthread_setname_np(3) is available. */ #define JEMALLOC_HAVE_PTHREAD_SETNAME_NP @@ -284,7 +284,7 @@ #define JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS /* Defined if madvise(2) is available but MADV_FREE is not (x86 Linux only). */ -/* #undef JEMALLOC_DEFINE_MADVISE_FREE */ +#define JEMALLOC_DEFINE_MADVISE_FREE /* * Defined if MADV_DO[NT]DUMP is supported as an argument to madvise. diff --git a/contrib/libuv-cmake/CMakeLists.txt b/contrib/libuv-cmake/CMakeLists.txt new file mode 100644 index 00000000000..4fbd0575b55 --- /dev/null +++ b/contrib/libuv-cmake/CMakeLists.txt @@ -0,0 +1,160 @@ +# This file is a modified version of contrib/libuv/CMakeLists.txt + +include(CMakeDependentOption) + +set (SOURCE_DIR "${CMAKE_SOURCE_DIR}/contrib/libuv") +set (BINARY_DIR "${CMAKE_BINARY_DIR}/contrib/libuv") + + +if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") + list(APPEND uv_cflags -fvisibility=hidden --std=gnu89) + list(APPEND uv_cflags -Wall -Wextra -Wstrict-prototypes) + list(APPEND uv_cflags -Wno-unused-parameter) +endif() + +set(uv_sources + src/fs-poll.c + src/idna.c + src/inet.c + src/random.c + src/strscpy.c + src/threadpool.c + src/timer.c + src/uv-common.c + src/uv-data-getter-setters.c + src/version.c + src/unix/async.c + src/unix/core.c + src/unix/dl.c + src/unix/fs.c + src/unix/getaddrinfo.c + src/unix/getnameinfo.c + src/unix/loop-watcher.c + src/unix/loop.c + src/unix/pipe.c + src/unix/poll.c + src/unix/process.c + src/unix/random-devurandom.c + src/unix/signal.c + src/unix/stream.c + src/unix/tcp.c + src/unix/thread.c + src/unix/tty.c + src/unix/udp.c) + +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux|OS/390") + list(APPEND uv_sources src/unix/proctitle.c) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD") + list(APPEND uv_sources src/unix/freebsd.c) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD") + list(APPEND uv_sources src/unix/posix-hrtime.c src/unix/bsd-proctitle.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD") + list(APPEND uv_sources src/unix/bsd-ifaddrs.c src/unix/kqueue.c) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND uv_sources src/unix/random-getrandom.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + list(APPEND uv_sources src/unix/random-getentropy.c) +endif() + +if(APPLE) + list(APPEND uv_defines _DARWIN_UNLIMITED_SELECT=1 _DARWIN_USE_64_BIT_INODE=1) + list(APPEND uv_sources + src/unix/darwin-proctitle.c + src/unix/darwin.c + src/unix/fsevents.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112) + list(APPEND uv_libraries dl rt) + list(APPEND uv_sources + src/unix/linux-core.c + src/unix/linux-inotify.c + src/unix/linux-syscalls.c + src/unix/procfs-exepath.c + src/unix/random-getrandom.c + src/unix/random-sysctl-linux.c + src/unix/sysinfo-loadavg.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") + list(APPEND uv_sources src/unix/netbsd.c) + list(APPEND uv_libraries kvm) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + list(APPEND uv_sources src/unix/openbsd.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "OS/390") + list(APPEND uv_defines PATH_MAX=255) + list(APPEND uv_defines _AE_BIMODAL) + list(APPEND uv_defines _ALL_SOURCE) + list(APPEND uv_defines _LARGE_TIME_API) + list(APPEND uv_defines _OPEN_MSGQ_EXT) + list(APPEND uv_defines _OPEN_SYS_FILE_EXT) + list(APPEND uv_defines _OPEN_SYS_IF_EXT) + list(APPEND uv_defines _OPEN_SYS_SOCK_EXT3) + list(APPEND uv_defines _OPEN_SYS_SOCK_IPV6) + list(APPEND uv_defines _UNIX03_SOURCE) + list(APPEND uv_defines _UNIX03_THREADS) + list(APPEND uv_defines _UNIX03_WITHDRAWN) + list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED) + list(APPEND uv_sources + src/unix/pthread-fixes.c + src/unix/pthread-barrier.c + src/unix/os390.c + src/unix/os390-syscalls.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500) + list(APPEND uv_libraries kstat nsl sendfile socket) + list(APPEND uv_sources src/unix/no-proctitle.c src/unix/sunos.c) +endif() + +set(uv_sources_tmp "") +foreach(file ${uv_sources}) + list(APPEND uv_sources_tmp "${SOURCE_DIR}/${file}") +endforeach(file) +set(uv_sources "${uv_sources_tmp}") + +list(APPEND uv_defines CLICKHOUSE_GLIBC_COMPATIBILITY) + +add_library(uv ${uv_sources}) +target_compile_definitions(uv + INTERFACE USING_UV_SHARED=1 + PRIVATE ${uv_defines} BUILDING_UV_SHARED=1) +target_compile_options(uv PRIVATE ${uv_cflags}) +target_include_directories(uv PUBLIC ${SOURCE_DIR}/include PRIVATE ${SOURCE_DIR}/src) +target_link_libraries(uv ${uv_libraries}) + +add_library(uv_a STATIC ${uv_sources}) +target_compile_definitions(uv_a PRIVATE ${uv_defines}) +target_compile_options(uv_a PRIVATE ${uv_cflags}) +target_include_directories(uv_a PUBLIC ${SOURCE_DIR}/include PRIVATE ${SOURCE_DIR}/src) +target_link_libraries(uv_a ${uv_libraries}) + +if(UNIX) + # Now for some gibbering horrors from beyond the stars... + foreach(x ${uv_libraries}) + set(LIBS "${LIBS} -l${x}") + endforeach(x) + file(STRINGS ${SOURCE_DIR}/configure.ac configure_ac REGEX ^AC_INIT) + string(REGEX MATCH [0-9]+[.][0-9]+[.][0-9]+ PACKAGE_VERSION "${configure_ac}") + string(REGEX MATCH ^[0-9]+ UV_VERSION_MAJOR "${PACKAGE_VERSION}") + # The version in the filename is mirroring the behaviour of autotools. + set_target_properties(uv PROPERTIES VERSION ${UV_VERSION_MAJOR}.0.0 + SOVERSION ${UV_VERSION_MAJOR}) +endif() + diff --git a/src/Interpreters/ITokenExtractor.cpp b/src/Interpreters/ITokenExtractor.cpp index 83166079e89..8c1af130f71 100644 --- a/src/Interpreters/ITokenExtractor.cpp +++ b/src/Interpreters/ITokenExtractor.cpp @@ -6,7 +6,7 @@ #include #if defined(__SSE2__) -#include +#include #if defined(__SSE4_2__) #include diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index a6bf2843e9a..8309b6bcb53 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -38,7 +38,7 @@ if (NOT DEFINED ENABLE_UTILS OR ENABLE_UTILS) endif () # memcpy_jart.S contains position dependent code - if (NOT CMAKE_POSITION_INDEPENDENT_CODE AND NOT OS_DARWIN AND NOT OS_SUNOS AND NOT ARCH_AARCH64) + if (NOT CMAKE_POSITION_INDEPENDENT_CODE AND OS_LINUX AND ARCH_AMD64) add_subdirectory (memcpy-bench) endif () endif () diff --git a/utils/memcpy-bench/CMakeLists.txt b/utils/memcpy-bench/CMakeLists.txt index 5353b6fb68e..593a359a876 100644 --- a/utils/memcpy-bench/CMakeLists.txt +++ b/utils/memcpy-bench/CMakeLists.txt @@ -16,7 +16,7 @@ add_executable (memcpy-bench add_compile_options(memcpy-bench PRIVATE -fno-tree-loop-distribute-patterns) if (OS_SUNOS) - target_compile_options(memcpy-bench PRIVATE "-Wa,--divide") + target_compile_options(memcpy-bench PRIVATE "-Wa,--divide") endif() set_source_files_properties(FastMemcpy.cpp PROPERTIES COMPILE_FLAGS "-Wno-old-style-cast") From 0c6c716bdd7c18bb2fe7cabcadaa0189eb8e7457 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 01:49:29 +0300 Subject: [PATCH 221/264] Update submodule --- contrib/sysroot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/sysroot b/contrib/sysroot index 611d3315e9e..002415524b5 160000 --- a/contrib/sysroot +++ b/contrib/sysroot @@ -1 +1 @@ -Subproject commit 611d3315e9e369a338de4ffa128eb87b4fb87dec +Subproject commit 002415524b5d14124bb8a61a3ce7ac65774f5479 From 54f3d0d2d977d62bee1a75510974326b9dc91047 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 02:02:44 +0300 Subject: [PATCH 222/264] Fix error --- cmake/target.cmake | 1 - 1 file changed, 1 deletion(-) diff --git a/cmake/target.cmake b/cmake/target.cmake index ca6009e68d3..872202f2f29 100644 --- a/cmake/target.cmake +++ b/cmake/target.cmake @@ -36,7 +36,6 @@ if (CMAKE_CROSSCOMPILING) set (ENABLE_GRPC OFF CACHE INTERNAL "") set (USE_SENTRY OFF CACHE INTERNAL "") # set (ENABLE_ROCKSDB OFF CACHE INTERNAL "") - endif () elseif (ARCH_PPC64LE) set (ENABLE_PROTOBUF OFF CACHE INTERNAL "") set (ENABLE_GRPC OFF CACHE INTERNAL "") From fa14dbdf429c06c3acc64311f0b49948028b6f51 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 02:03:00 +0300 Subject: [PATCH 223/264] Update submodules --- contrib/boost | 2 +- contrib/libuv | 2 +- contrib/s2geometry | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/boost b/contrib/boost index 66d17f060c4..311cfd49896 160000 --- a/contrib/boost +++ b/contrib/boost @@ -1 +1 @@ -Subproject commit 66d17f060c4867aeea99fa2a20cfdae89ae2a2ec +Subproject commit 311cfd498966d4f77742703d605d9c2e7b4cc6a8 diff --git a/contrib/libuv b/contrib/libuv index e2e9b7e9f97..95081e7c16c 160000 --- a/contrib/libuv +++ b/contrib/libuv @@ -1 +1 @@ -Subproject commit e2e9b7e9f978ce8a1367b5fe781d97d1ce9f94ab +Subproject commit 95081e7c16c9857babe6d4e2bc1c779198ea89ae diff --git a/contrib/s2geometry b/contrib/s2geometry index 20ea540d81f..38b7a290f92 160000 --- a/contrib/s2geometry +++ b/contrib/s2geometry @@ -1 +1 @@ -Subproject commit 20ea540d81f4575a3fc0aea585aac611bcd03ede +Subproject commit 38b7a290f927cc372218c2094602b83e35b18c05 From 96de70c0005bcb88666c82f1f36e9a1c05bfa0fe Mon Sep 17 00:00:00 2001 From: Thom O'Connor Date: Mon, 11 Oct 2021 17:06:07 -0600 Subject: [PATCH 224/264] Adjusted documentation to align stripe size with write size, and correct block size to common RAID recommendations --- docs/en/operations/tips.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/en/operations/tips.md b/docs/en/operations/tips.md index 27fc7d47a76..5cbbe71b3e0 100644 --- a/docs/en/operations/tips.md +++ b/docs/en/operations/tips.md @@ -1,4 +1,3 @@ ---- toc_priority: 58 toc_title: Usage Recommendations --- @@ -60,7 +59,7 @@ $ echo 4096 | sudo tee /sys/block/md2/md/stripe_cache_size Calculate the exact number from the number of devices and the block size, using the formula: `2 * num_devices * chunk_size_in_bytes / 4096`. -A block size of 1024 bytes (1KB) is sufficient for most RAID configurations. A block size range of 1KB to 16KB is common across many storage system vendors or DBMS. +A block size of 64 KB is sufficient for most RAID configurations. The average clickhouse-server write size is approximately 1 MB (1024 KB), and thus the recommended stripe size is also 1 MB. The block size can be optimized if needed when set to 1 MB divided by the number of non-parity disks in the RAID array, such that each write is parallelized across all available non-parity disks. Never set the block size too small or too large. You can use RAID-0 on SSD. From e1409c143b7d05a31bd26b8ebf063a160ce8b87d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 02:06:22 +0300 Subject: [PATCH 225/264] Add toolchain file --- cmake/linux/toolchain-ppc64le.cmake | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 cmake/linux/toolchain-ppc64le.cmake diff --git a/cmake/linux/toolchain-ppc64le.cmake b/cmake/linux/toolchain-ppc64le.cmake new file mode 100644 index 00000000000..cf85fc20fc4 --- /dev/null +++ b/cmake/linux/toolchain-ppc64le.cmake @@ -0,0 +1,32 @@ +set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set (CMAKE_SYSTEM_NAME "Linux") +set (CMAKE_SYSTEM_PROCESSOR "ppc64le") +set (CMAKE_C_COMPILER_TARGET "ppc64le-linux-gnu") +set (CMAKE_CXX_COMPILER_TARGET "ppc64le-linux-gnu") +set (CMAKE_ASM_COMPILER_TARGET "ppc64le-linux-gnu") + +set (TOOLCHAIN_PATH "${CMAKE_CURRENT_LIST_DIR}/../../contrib/sysroot/linux-powerpc64le") + +set (CMAKE_SYSROOT "${TOOLCHAIN_PATH}/powerpc64le-linux-gnu/libc") + +find_program (LLVM_AR_PATH NAMES "llvm-ar" "llvm-ar-13" "llvm-ar-12" "llvm-ar-11" "llvm-ar-10" "llvm-ar-9" "llvm-ar-8") +find_program (LLVM_RANLIB_PATH NAMES "llvm-ranlib" "llvm-ranlib-13" "llvm-ranlib-12" "llvm-ranlib-11" "llvm-ranlib-10" "llvm-ranlib-9") + +set (CMAKE_AR "${LLVM_AR_PATH}" CACHE FILEPATH "" FORCE) +set (CMAKE_RANLIB "${LLVM_RANLIB_PATH}" CACHE FILEPATH "" FORCE) + +set (CMAKE_C_FLAGS_INIT "${CMAKE_C_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") +set (CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") +set (CMAKE_ASM_FLAGS_INIT "${CMAKE_ASM_FLAGS} --gcc-toolchain=${TOOLCHAIN_PATH}") + +set (LINKER_NAME "ld.lld" CACHE STRING "" FORCE) + +set (CMAKE_EXE_LINKER_FLAGS_INIT "-fuse-ld=lld") +set (CMAKE_SHARED_LINKER_FLAGS_INIT "-fuse-ld=lld") + +set (HAS_PRE_1970_EXITCODE "0" CACHE STRING "Result from TRY_RUN" FORCE) +set (HAS_PRE_1970_EXITCODE__TRYRUN_OUTPUT "" CACHE STRING "Output from TRY_RUN" FORCE) + +set (HAS_POST_2038_EXITCODE "0" CACHE STRING "Result from TRY_RUN" FORCE) +set (HAS_POST_2038_EXITCODE__TRYRUN_OUTPUT "" CACHE STRING "Output from TRY_RUN" FORCE) From cb9bdf9666b8e1efac8b1d96e62359622c5bfd65 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 02:07:03 +0300 Subject: [PATCH 226/264] Minor change --- cmake/target.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/target.cmake b/cmake/target.cmake index 872202f2f29..e8932a893c0 100644 --- a/cmake/target.cmake +++ b/cmake/target.cmake @@ -55,7 +55,7 @@ if (CMAKE_CROSSCOMPILING) endif () # Don't know why but CXX_STANDARD doesn't work for cross-compilation - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20") message (STATUS "Cross-compiling for target: ${CMAKE_CXX_COMPILE_TARGET}") endif () From 75547e64a5ce564bcac8fd1446af5155f6a25822 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 02:10:58 +0300 Subject: [PATCH 227/264] Add to packager --- docker/packager/packager | 9 +++++++-- tests/ci/ci_config.json | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docker/packager/packager b/docker/packager/packager index f8e5fd717cf..ae7b99200ee 100755 --- a/docker/packager/packager +++ b/docker/packager/packager @@ -61,6 +61,7 @@ def parse_env_variables(build_type, compiler, sanitizer, package_type, image_typ DARWIN_ARM_SUFFIX = "-darwin-aarch64" ARM_SUFFIX = "-aarch64" FREEBSD_SUFFIX = "-freebsd" + PPC_SUFFIX = '-ppc64le' result = [] cmake_flags = ['$CMAKE_FLAGS', '-DADD_GDB_INDEX_FOR_GOLD=1'] @@ -69,8 +70,9 @@ def parse_env_variables(build_type, compiler, sanitizer, package_type, image_typ is_cross_darwin = compiler.endswith(DARWIN_SUFFIX) is_cross_darwin_arm = compiler.endswith(DARWIN_ARM_SUFFIX) is_cross_arm = compiler.endswith(ARM_SUFFIX) + is_cross_ppc = compiler.endswith(PPC_SUFFIX) is_cross_freebsd = compiler.endswith(FREEBSD_SUFFIX) - is_cross_compile = is_cross_darwin or is_cross_darwin_arm or is_cross_arm or is_cross_freebsd + is_cross_compile = is_cross_darwin or is_cross_darwin_arm or is_cross_arm or is_cross_freebsd or is_cross_ppc # Explicitly use LLD with Clang by default. # Don't force linker for cross-compilation. @@ -97,6 +99,9 @@ def parse_env_variables(build_type, compiler, sanitizer, package_type, image_typ elif is_cross_freebsd: cc = compiler[:-len(FREEBSD_SUFFIX)] cmake_flags.append("-DCMAKE_TOOLCHAIN_FILE=/build/cmake/freebsd/toolchain-x86_64.cmake") + elif is_cross_ppc: + cc = compiler[:-len(PPC_SUFFIX)] + cmake_flags.append("-DCMAKE_TOOLCHAIN_FILE=/build/cmake/linux/toolchain-ppc64le.cmake") else: cc = compiler @@ -205,7 +210,7 @@ if __name__ == "__main__": parser.add_argument("--build-type", choices=("debug", ""), default="") parser.add_argument("--compiler", choices=("clang-11", "clang-11-darwin", "clang-11-darwin-aarch64", "clang-11-aarch64", "clang-12", "clang-12-darwin", "clang-12-darwin-aarch64", "clang-12-aarch64", - "clang-13", "clang-13-darwin", "clang-13-darwin-aarch64", "clang-13-aarch64", + "clang-13", "clang-13-darwin", "clang-13-darwin-aarch64", "clang-13-aarch64", "clang-13-ppc64le", "clang-11-freebsd", "clang-12-freebsd", "clang-13-freebsd", "gcc-11"), default="clang-13") parser.add_argument("--sanitizer", choices=("address", "thread", "memory", "undefined", ""), default="") parser.add_argument("--unbundled", action="store_true") diff --git a/tests/ci/ci_config.json b/tests/ci/ci_config.json index 6222e4f61bc..4feae56b93c 100644 --- a/tests/ci/ci_config.json +++ b/tests/ci/ci_config.json @@ -162,6 +162,16 @@ "splitted": "unsplitted", "tidy": "disable", "with_coverage": false + }, + { + "compiler": "clang-13-ppc64le", + "build-type": "", + "sanitizer": "", + "package-type": "binary", + "bundled": "bundled", + "splitted": "unsplitted", + "tidy": "disable", + "with_coverage": false } ], "tests_config": { From 0d076468666df08c950c7630d8b126d693bfc32e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 03:17:35 +0300 Subject: [PATCH 228/264] Fix strange code --- cmake/find/ssl.cmake | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/cmake/find/ssl.cmake b/cmake/find/ssl.cmake index fd6ed56dcdb..fdc0bfb27d3 100644 --- a/cmake/find/ssl.cmake +++ b/cmake/find/ssl.cmake @@ -53,12 +53,7 @@ endif () if (NOT OPENSSL_FOUND AND NOT MISSING_INTERNAL_SSL_LIBRARY) set (USE_INTERNAL_SSL_LIBRARY 1) set (OPENSSL_ROOT_DIR "${ClickHouse_SOURCE_DIR}/contrib/boringssl") - - if (ARCH_AMD64) - set (OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include") - elseif (ARCH_AARCH64) - set (OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include") - endif () + set (OPENSSL_INCLUDE_DIR "${OPENSSL_ROOT_DIR}/include") set (OPENSSL_CRYPTO_LIBRARY crypto) set (OPENSSL_SSL_LIBRARY ssl) set (OPENSSL_FOUND 1) From 5ba876cad29686a3c8c0aee68b65219223b2f140 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 05:46:19 +0300 Subject: [PATCH 229/264] Build protoc for host architecture during cross-compilation --- .../grpc-cmake/protobuf_generate_grpc.cmake | 4 +- contrib/protobuf-cmake/CMakeLists.txt | 49 ++++++++++++++++++- .../protobuf-cmake/protobuf_generate.cmake | 4 +- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/contrib/grpc-cmake/protobuf_generate_grpc.cmake b/contrib/grpc-cmake/protobuf_generate_grpc.cmake index 726428a7597..71ee69caf3e 100644 --- a/contrib/grpc-cmake/protobuf_generate_grpc.cmake +++ b/contrib/grpc-cmake/protobuf_generate_grpc.cmake @@ -187,12 +187,12 @@ function(protobuf_generate_grpc) add_custom_command( OUTPUT ${_generated_srcs} - COMMAND $ + COMMAND $ ARGS --${protobuf_generate_grpc_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_grpc_PROTOC_OUT_DIR} --grpc_out ${_dll_export_decl}${protobuf_generate_grpc_PROTOC_OUT_DIR} --plugin=protoc-gen-grpc=$ ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${_abs_file} protobuf::protoc ${protobuf_generate_grpc_PLUGIN} + DEPENDS ${_abs_file} protoc ${protobuf_generate_grpc_PLUGIN} COMMENT "Running ${protobuf_generate_grpc_LANGUAGE} protocol buffer compiler on ${_proto}" VERBATIM) endforeach() diff --git a/contrib/protobuf-cmake/CMakeLists.txt b/contrib/protobuf-cmake/CMakeLists.txt index a4993030d04..10ef7df26b1 100644 --- a/contrib/protobuf-cmake/CMakeLists.txt +++ b/contrib/protobuf-cmake/CMakeLists.txt @@ -10,8 +10,55 @@ else () set(protobuf_BUILD_SHARED_LIBS ON CACHE INTERNAL "" FORCE) endif () +if (CMAKE_CROSSCOMPILING) + # Will build 'protoc' for host arch instead of cross-compiling + set(protobuf_BUILD_PROTOC_BINARIES OFF CACHE INTERNAL "" FORCE) +endif () + add_subdirectory("${protobuf_SOURCE_DIR}/cmake" "${protobuf_BINARY_DIR}") # We don't want to stop compilation on warnings in protobuf's headers. -# The following line overrides the value assigned by the command target_include_directories() in libprotobuf.cmake +# The following line overrides the value assigned by the command target_include_directories() in libprotobuf.cmake set_property(TARGET libprotobuf PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${protobuf_SOURCE_DIR}/src") + +if (CMAKE_CROSSCOMPILING) + # Build 'protoc' for host arch + set (PROTOC_BUILD_DIR "${protobuf_BINARY_DIR}/build") + + add_custom_command ( + OUTPUT ${PROTOC_BUILD_DIR} + COMMAND mkdir -p ${PROTOC_BUILD_DIR}) + + add_custom_command ( + OUTPUT "${PROTOC_BUILD_DIR}/CMakeCache.txt" + + COMMAND ${CMAKE_COMMAND} + -G"${CMAKE_GENERATOR}" + -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}" + -DCMAKE_C_COMPILER="${CMAKE_C_COMPILER}" + -DCMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}" + -Dprotobuf_BUILD_TESTS=0 + -Dprotobuf_BUILD_CONFORMANCE=0 + -Dprotobuf_BUILD_EXAMPLES=0 + -Dprotobuf_BUILD_PROTOC_BINARIES=1 + "${protobuf_SOURCE_DIR}/cmake" + + DEPENDS "${PROTOC_BUILD_DIR}" + WORKING_DIRECTORY "${PROTOC_BUILD_DIR}" + COMMENT "Configuring 'protoc' for host architecture.") + + add_custom_command ( + OUTPUT "${PROTOC_BUILD_DIR}/protoc" + COMMAND ${CMAKE_COMMAND} --build "${PROTOC_BUILD_DIR}" + DEPENDS "${PROTOC_BUILD_DIR}/CMakeCache.txt" + COMMENT "Building 'protoc' for host architecture.") + + #add_custom_target (protoc DEPENDS "${PROTOC_BUILD_DIR}/protoc") + #set_target_properties (protoc PROPERTIES TARGET_FILE "${PROTOC_BUILD_DIR}/protoc") + + add_executable(protoc IMPORTED GLOBAL) + set_target_properties (protoc PROPERTIES IMPORTED_LOCATION "${PROTOC_BUILD_DIR}/protoc") + add_dependencies(protoc "${PROTOC_BUILD_DIR}/protoc") + + #add_executable(protobuf::protoc ALIAS protoc) +endif () diff --git a/contrib/protobuf-cmake/protobuf_generate.cmake b/contrib/protobuf-cmake/protobuf_generate.cmake index c444162dd1e..3e30b4e40fd 100644 --- a/contrib/protobuf-cmake/protobuf_generate.cmake +++ b/contrib/protobuf-cmake/protobuf_generate.cmake @@ -181,9 +181,9 @@ function(protobuf_generate) add_custom_command( OUTPUT ${_generated_srcs} - COMMAND $ + COMMAND $ ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_dll_desc_out} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${_abs_file} protobuf::protoc + DEPENDS ${_abs_file} protoc COMMENT "Running ${protobuf_generate_LANGUAGE} protocol buffer compiler on ${_proto}" VERBATIM) endforeach() From 12168e7762712f9e68544d49076e34befa11affd Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 05:46:50 +0300 Subject: [PATCH 230/264] Enable Protobuf, Arrow, ORC, Parquet for AArch64 and Darwin --- cmake/target.cmake | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/cmake/target.cmake b/cmake/target.cmake index d1a0b8f9cbf..683deab1c33 100644 --- a/cmake/target.cmake +++ b/cmake/target.cmake @@ -20,24 +20,14 @@ endif () if (CMAKE_CROSSCOMPILING) if (OS_DARWIN) # FIXME: broken dependencies - set (ENABLE_PROTOBUF OFF CACHE INTERNAL "") set (ENABLE_GRPC OFF CACHE INTERNAL "") # no protobuf -> no grpc - set (USE_SNAPPY OFF CACHE INTERNAL "") - set (ENABLE_PARQUET OFF CACHE INTERNAL "") # no snappy and protobuf -> no parquet - set (ENABLE_ORC OFF CACHE INTERNAL "") # no arrow (parquet) -> no orc - set (ENABLE_ICU OFF CACHE INTERNAL "") set (ENABLE_FASTOPS OFF CACHE INTERNAL "") elseif (OS_LINUX OR OS_ANDROID) if (ARCH_AARCH64) # FIXME: broken dependencies - set (ENABLE_PROTOBUF OFF CACHE INTERNAL "") set (ENABLE_GRPC OFF CACHE INTERNAL "") - - set (ENABLE_PARQUET OFF CACHE INTERNAL "") - set (ENABLE_ORC OFF CACHE INTERNAL "") - set (ENABLE_MYSQL OFF CACHE INTERNAL "") endif () elseif (OS_FREEBSD) From 3a8e65f01e31baa24c6ccc0c81168a128c679b61 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 06:28:05 +0300 Subject: [PATCH 231/264] Another try --- contrib/protobuf-cmake/CMakeLists.txt | 79 ++++++++++++++++++--------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/contrib/protobuf-cmake/CMakeLists.txt b/contrib/protobuf-cmake/CMakeLists.txt index 10ef7df26b1..0ceb72cfbd6 100644 --- a/contrib/protobuf-cmake/CMakeLists.txt +++ b/contrib/protobuf-cmake/CMakeLists.txt @@ -25,40 +25,67 @@ if (CMAKE_CROSSCOMPILING) # Build 'protoc' for host arch set (PROTOC_BUILD_DIR "${protobuf_BINARY_DIR}/build") - add_custom_command ( - OUTPUT ${PROTOC_BUILD_DIR} - COMMAND mkdir -p ${PROTOC_BUILD_DIR}) + if (NOT EXISTS "${PROTOC_BUILD_DIR}/protoc") - add_custom_command ( - OUTPUT "${PROTOC_BUILD_DIR}/CMakeCache.txt" + # This is quite ugly but I cannot make dependencies work propery. - COMMAND ${CMAKE_COMMAND} - -G"${CMAKE_GENERATOR}" - -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}" - -DCMAKE_C_COMPILER="${CMAKE_C_COMPILER}" - -DCMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}" - -Dprotobuf_BUILD_TESTS=0 - -Dprotobuf_BUILD_CONFORMANCE=0 - -Dprotobuf_BUILD_EXAMPLES=0 - -Dprotobuf_BUILD_PROTOC_BINARIES=1 - "${protobuf_SOURCE_DIR}/cmake" + execute_process( + COMMAND mkdir -p ${PROTOC_BUILD_DIR} + COMMAND_ECHO STDOUT) - DEPENDS "${PROTOC_BUILD_DIR}" - WORKING_DIRECTORY "${PROTOC_BUILD_DIR}" - COMMENT "Configuring 'protoc' for host architecture.") + execute_process( + COMMAND ${CMAKE_COMMAND} + "-G${CMAKE_GENERATOR}" + "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}" + "-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}" + "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}" + "-Dprotobuf_BUILD_TESTS=0" + "-Dprotobuf_BUILD_CONFORMANCE=0" + "-Dprotobuf_BUILD_EXAMPLES=0" + "-Dprotobuf_BUILD_PROTOC_BINARIES=1" + "${protobuf_SOURCE_DIR}/cmake" + WORKING_DIRECTORY "${PROTOC_BUILD_DIR}" + COMMAND_ECHO STDOUT) - add_custom_command ( - OUTPUT "${PROTOC_BUILD_DIR}/protoc" - COMMAND ${CMAKE_COMMAND} --build "${PROTOC_BUILD_DIR}" - DEPENDS "${PROTOC_BUILD_DIR}/CMakeCache.txt" - COMMENT "Building 'protoc' for host architecture.") + execute_process( + COMMAND ${CMAKE_COMMAND} --build "${PROTOC_BUILD_DIR}" + COMMAND_ECHO STDOUT) + endif () - #add_custom_target (protoc DEPENDS "${PROTOC_BUILD_DIR}/protoc") - #set_target_properties (protoc PROPERTIES TARGET_FILE "${PROTOC_BUILD_DIR}/protoc") +# add_custom_command ( +# OUTPUT ${PROTOC_BUILD_DIR} +# COMMAND mkdir -p ${PROTOC_BUILD_DIR}) +# +# add_custom_command ( +# OUTPUT "${PROTOC_BUILD_DIR}/CMakeCache.txt" +# +# COMMAND ${CMAKE_COMMAND} +# -G"${CMAKE_GENERATOR}" +# -DCMAKE_MAKE_PROGRAM="${CMAKE_MAKE_PROGRAM}" +# -DCMAKE_C_COMPILER="${CMAKE_C_COMPILER}" +# -DCMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}" +# -Dprotobuf_BUILD_TESTS=0 +# -Dprotobuf_BUILD_CONFORMANCE=0 +# -Dprotobuf_BUILD_EXAMPLES=0 +# -Dprotobuf_BUILD_PROTOC_BINARIES=1 +# "${protobuf_SOURCE_DIR}/cmake" +# +# DEPENDS "${PROTOC_BUILD_DIR}" +# WORKING_DIRECTORY "${PROTOC_BUILD_DIR}" +# COMMENT "Configuring 'protoc' for host architecture." +# USES_TERMINAL) +# +# add_custom_command ( +# OUTPUT "${PROTOC_BUILD_DIR}/protoc" +# COMMAND ${CMAKE_COMMAND} --build "${PROTOC_BUILD_DIR}" +# DEPENDS "${PROTOC_BUILD_DIR}/CMakeCache.txt" +# COMMENT "Building 'protoc' for host architecture." +# USES_TERMINAL) +# +# add_custom_target (protoc-host DEPENDS "${PROTOC_BUILD_DIR}/protoc") add_executable(protoc IMPORTED GLOBAL) set_target_properties (protoc PROPERTIES IMPORTED_LOCATION "${PROTOC_BUILD_DIR}/protoc") add_dependencies(protoc "${PROTOC_BUILD_DIR}/protoc") - #add_executable(protobuf::protoc ALIAS protoc) endif () From b5d69d599e3b9f7fd8654a8e5cbd2d1dba374273 Mon Sep 17 00:00:00 2001 From: feng lv Date: Tue, 12 Oct 2021 04:13:02 +0000 Subject: [PATCH 232/264] fix sample by tuple() add tests fix fix fix --- src/Storages/MergeTree/MergeTreeData.cpp | 4 ++++ tests/queries/0_stateless/02096_sample_by_tuple.reference | 0 tests/queries/0_stateless/02096_sample_by_tuple.sql | 7 +++++++ 3 files changed, 11 insertions(+) create mode 100644 tests/queries/0_stateless/02096_sample_by_tuple.reference create mode 100644 tests/queries/0_stateless/02096_sample_by_tuple.sql diff --git a/src/Storages/MergeTree/MergeTreeData.cpp b/src/Storages/MergeTree/MergeTreeData.cpp index c04e0d2e38f..51b68eed951 100644 --- a/src/Storages/MergeTree/MergeTreeData.cpp +++ b/src/Storages/MergeTree/MergeTreeData.cpp @@ -132,10 +132,14 @@ namespace ErrorCodes extern const int ALTER_OF_COLUMN_IS_FORBIDDEN; extern const int SUPPORT_IS_DISABLED; extern const int TOO_MANY_SIMULTANEOUS_QUERIES; + extern const int INCORRECT_QUERY; } static void checkSampleExpression(const StorageInMemoryMetadata & metadata, bool allow_sampling_expression_not_in_primary_key, bool check_sample_column_is_correct) { + if (metadata.sampling_key.column_names.empty()) + throw Exception("There are no columns in sampling expression", ErrorCodes::INCORRECT_QUERY); + const auto & pk_sample_block = metadata.getPrimaryKey().sample_block; if (!pk_sample_block.has(metadata.sampling_key.column_names[0]) && !allow_sampling_expression_not_in_primary_key) throw Exception("Sampling expression must be present in the primary key", ErrorCodes::BAD_ARGUMENTS); diff --git a/tests/queries/0_stateless/02096_sample_by_tuple.reference b/tests/queries/0_stateless/02096_sample_by_tuple.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/02096_sample_by_tuple.sql b/tests/queries/0_stateless/02096_sample_by_tuple.sql new file mode 100644 index 00000000000..4996c9b8384 --- /dev/null +++ b/tests/queries/0_stateless/02096_sample_by_tuple.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS t; + +CREATE TABLE t (n UInt8) ENGINE=MergeTree ORDER BY n SAMPLE BY tuple(); -- { serverError 80 } + +CREATE TABLE t (n UInt8) ENGINE=MergeTree ORDER BY tuple(); + +ALTER TABLE t MODIFY SAMPLE BY tuple(); -- { serverError 80 } From ee1fd495ea77015db254a42108b630175c5930af Mon Sep 17 00:00:00 2001 From: feng lv Date: Tue, 12 Oct 2021 05:30:35 +0000 Subject: [PATCH 233/264] remove redundant dot in exception message --- src/Interpreters/InterpreterCreateQuery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interpreters/InterpreterCreateQuery.cpp b/src/Interpreters/InterpreterCreateQuery.cpp index 3965945b3ca..c098c6e0506 100644 --- a/src/Interpreters/InterpreterCreateQuery.cpp +++ b/src/Interpreters/InterpreterCreateQuery.cpp @@ -999,7 +999,7 @@ bool InterpreterCreateQuery::doCreateTable(ASTCreateQuery & create, } else throw Exception(storage_already_exists_error_code, - "{} {}.{} already exists.", storage_name, backQuoteIfNeed(create.database), backQuoteIfNeed(create.table)); + "{} {}.{} already exists", storage_name, backQuoteIfNeed(create.database), backQuoteIfNeed(create.table)); } data_path = database->getTableDataPath(create); From c15b67c18264919df7c8048ea36ea5058a185d36 Mon Sep 17 00:00:00 2001 From: Maksim Kita Date: Tue, 12 Oct 2021 11:42:24 +0300 Subject: [PATCH 234/264] Fix naming --- src/Storages/MergeTree/MergeTreeData.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Storages/MergeTree/MergeTreeData.cpp b/src/Storages/MergeTree/MergeTreeData.cpp index 1ede7669832..f9c26225440 100644 --- a/src/Storages/MergeTree/MergeTreeData.cpp +++ b/src/Storages/MergeTree/MergeTreeData.cpp @@ -3006,7 +3006,7 @@ void MergeTreeData::removePartContributionToColumnAndSecondaryIndexSizes(const D for (const auto & column : part->getColumns()) { ColumnSize & total_column_size = column_sizes[column.name]; - ColumnSize part_secondary_index_size = part->getColumnSize(column.name, *column.type); + ColumnSize part_column_size = part->getColumnSize(column.name, *column.type); auto log_subtract = [&](size_t & from, size_t value, const char * field) { @@ -3017,9 +3017,9 @@ void MergeTreeData::removePartContributionToColumnAndSecondaryIndexSizes(const D from -= value; }; - log_subtract(total_column_size.data_compressed, part_secondary_index_size.data_compressed, ".data_compressed"); - log_subtract(total_column_size.data_uncompressed, part_secondary_index_size.data_uncompressed, ".data_uncompressed"); - log_subtract(total_column_size.marks, part_secondary_index_size.marks, ".marks"); + log_subtract(total_column_size.data_compressed, part_column_size.data_compressed, ".data_compressed"); + log_subtract(total_column_size.data_uncompressed, part_column_size.data_uncompressed, ".data_uncompressed"); + log_subtract(total_column_size.marks, part_column_size.marks, ".marks"); } auto indexes_descriptions = getInMemoryMetadataPtr()->secondary_indices; From cb176cf9addf71b94b58cbe23b2c542d7417896d Mon Sep 17 00:00:00 2001 From: Vladimir C Date: Tue, 12 Oct 2021 12:33:54 +0300 Subject: [PATCH 235/264] Add `long` tag to 02033_join_engine_deadlock_long --- tests/queries/0_stateless/02033_join_engine_deadlock_long.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/queries/0_stateless/02033_join_engine_deadlock_long.sh b/tests/queries/0_stateless/02033_join_engine_deadlock_long.sh index f4ae564e2a7..2a887cbbcae 100755 --- a/tests/queries/0_stateless/02033_join_engine_deadlock_long.sh +++ b/tests/queries/0_stateless/02033_join_engine_deadlock_long.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Tags: deadlock +# Tags: long, deadlock CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) # shellcheck source=../shell_config.sh From b2f8cd07e68107db07ffe79abdf7948d48f2f90d Mon Sep 17 00:00:00 2001 From: Kseniia Sumarokova <54203879+kssenii@users.noreply.github.com> Date: Tue, 12 Oct 2021 12:54:02 +0300 Subject: [PATCH 236/264] Update normalizeString.cpp --- src/Functions/normalizeString.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Functions/normalizeString.cpp b/src/Functions/normalizeString.cpp index 5beca566cd1..2b3a869e452 100644 --- a/src/Functions/normalizeString.cpp +++ b/src/Functions/normalizeString.cpp @@ -10,9 +10,9 @@ #include #include #include -#include "common/logger_useful.h" -#include "Columns/ColumnString.h" -#include "Parsers/IAST_fwd.h" +#include +#include +#include namespace DB { From 5bf64c62c271cef95f5cfda1796eef82311c6bdd Mon Sep 17 00:00:00 2001 From: Nikita Mikhaylov Date: Tue, 12 Oct 2021 10:19:21 +0000 Subject: [PATCH 237/264] Delete test --- src/Functions/tests/gtest_abtesting.cpp | 105 ------------------------ 1 file changed, 105 deletions(-) delete mode 100644 src/Functions/tests/gtest_abtesting.cpp diff --git a/src/Functions/tests/gtest_abtesting.cpp b/src/Functions/tests/gtest_abtesting.cpp deleted file mode 100644 index e7ef5b5c3cf..00000000000 --- a/src/Functions/tests/gtest_abtesting.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include - -#if !defined(ARCADIA_BUILD) && USE_STATS - -# include - -using namespace DB; - -Variants test_bayesab(std::string dist, PODArray xs, PODArray ys, size_t & max, size_t & min) -{ - Variants variants; - - //std::cout << std::fixed; - if (dist == "beta") - { -/* std::cout << dist << "\nclicks: "; - for (auto x : xs) - std::cout << x << " "; - - std::cout <<"\tconversions: "; - for (auto y : ys) - std::cout << y << " "; - - std::cout << "\n";*/ - - variants = bayesian_ab_test(dist, xs, ys); - } - else if (dist == "gamma") - { -/* std::cout << dist << "\nclicks: "; - for (auto x : xs) - std::cout << x << " "; - - std::cout <<"\tcost: "; - for (auto y : ys) - std::cout << y << " "; - - std::cout << "\n";*/ - - variants = bayesian_ab_test(dist, xs, ys); - } - -/* for (size_t i = 0; i < variants.size(); ++i) - std::cout << i << " beats 0: " << variants[i].beats_control << std::endl; - - for (size_t i = 0; i < variants.size(); ++i) - std::cout << i << " to be best: " << variants[i].best << std::endl; - - std::cout << convertToJson({"0", "1", "2"}, variants) << std::endl; -*/ - Float64 max_val = 0.0, min_val = 2.0; - for (size_t i = 0; i < variants.size(); ++i) - { - if (variants[i].best > max_val) - { - max_val = variants[i].best; - max = i; - } - - if (variants[i].best < min_val) - { - min_val = variants[i].best; - min = i; - } - } - - return variants; -} - - -TEST(BayesAB, beta) -{ - size_t max = 0, min = 0; - - auto variants = test_bayesab("beta", {10000, 1000, 900}, {600, 110, 90}, max, min); - ASSERT_EQ(1, max); - - variants = test_bayesab("beta", {3000, 3000, 3000}, {600, 100, 90}, max, min); - ASSERT_EQ(0, max); - - variants = test_bayesab("beta", {3000, 3000, 3000}, {100, 90, 110}, max, min); - ASSERT_EQ(2, max); - - variants = test_bayesab("beta", {3000, 3000, 3000}, {110, 90, 100}, max, min); - ASSERT_EQ(0, max); -} - - -TEST(BayesAB, gamma) -{ - size_t max = 0, min = 0; - auto variants = test_bayesab("gamma", {10000, 1000, 900}, {600, 110, 90}, max, min); - ASSERT_EQ(1, max); - - variants = test_bayesab("gamma", {3000, 3000, 3000}, {600, 100, 90}, max, min); - ASSERT_EQ(0, max); - - variants = test_bayesab("gamma", {3000, 3000, 3000}, {100, 90, 110}, max, min); - ASSERT_EQ(2, max); - - variants = test_bayesab("gamma", {3000, 3000, 3000}, {110, 90, 100}, max, min); - ASSERT_EQ(0, max); -} - -#endif From f3c9f4be6cd2a7e3d65cc9766c791111ce8159e5 Mon Sep 17 00:00:00 2001 From: tavplubix Date: Tue, 12 Oct 2021 14:38:41 +0300 Subject: [PATCH 238/264] Update run.sh --- docker/test/stateless/run.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/docker/test/stateless/run.sh b/docker/test/stateless/run.sh index ed721690281..2002fd2cbff 100755 --- a/docker/test/stateless/run.sh +++ b/docker/test/stateless/run.sh @@ -114,12 +114,6 @@ grep -Fa "Fatal" /var/log/clickhouse-server/clickhouse-server.log ||: pigz < /var/log/clickhouse-server/clickhouse-server.log > /test_output/clickhouse-server.log.gz & clickhouse-client -q "select * from system.query_log format TSVWithNamesAndTypes" | pigz > /test_output/query-log.tsv.gz & clickhouse-client -q "select * from system.query_thread_log format TSVWithNamesAndTypes" | pigz > /test_output/query-thread-log.tsv.gz & -clickhouse-client --allow_introspection_functions=1 -q " - WITH - arrayMap(x -> concat(demangle(addressToSymbol(x)), ':', addressToLine(x)), trace) AS trace_array, - arrayStringConcat(trace_array, '\n') AS trace_string - SELECT * EXCEPT(trace), trace_string FROM system.trace_log FORMAT TSVWithNamesAndTypes -" | pigz > /test_output/trace-log.tsv.gz & # Also export trace log in flamegraph-friendly format. for trace_type in CPU Memory Real @@ -146,6 +140,7 @@ fi tar -chf /test_output/text_log_dump.tar /var/lib/clickhouse/data/system/text_log ||: tar -chf /test_output/query_log_dump.tar /var/lib/clickhouse/data/system/query_log ||: tar -chf /test_output/zookeeper_log_dump.tar /var/lib/clickhouse/data/system/zookeeper_log ||: +tar -chf /test_output/trace_log_dump.tar /var/lib/clickhouse/data/system/trace_log ||: tar -chf /test_output/coordination.tar /var/lib/clickhouse/coordination ||: if [[ -n "$USE_DATABASE_REPLICATED" ]] && [[ "$USE_DATABASE_REPLICATED" -eq 1 ]]; then From dca1f8e7f5c017ebaf263af542f2075e437412c4 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 12 Oct 2021 15:38:40 +0300 Subject: [PATCH 239/264] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d024100a27e..e12238577a7 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ [![ClickHouse — open source distributed column-oriented DBMS](https://github.com/ClickHouse/ClickHouse/raw/master/website/images/logo-400x240.png)](https://clickhouse.com) -ClickHouse® is an open-source column-oriented database management system that allows generating analytical data reports in real time. +ClickHouse® is an open-source column-oriented database management system that allows generating analytical data reports in real-time. ## Useful Links -* [Official website](https://clickhouse.com/) has quick high-level overview of ClickHouse on main page. -* [Tutorial](https://clickhouse.com/docs/en/getting_started/tutorial/) shows how to set up and query small ClickHouse cluster. +* [Official website](https://clickhouse.com/) has a quick high-level overview of ClickHouse on the main page. +* [Tutorial](https://clickhouse.com/docs/en/getting_started/tutorial/) shows how to set up and query a small ClickHouse cluster. * [Documentation](https://clickhouse.com/docs/en/) provides more in-depth information. * [YouTube channel](https://www.youtube.com/c/ClickHouseDB) has a lot of content about ClickHouse in video format. -* [Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-rxm3rdrk-lIUmhLC3V8WTaL0TGxsOmg) and [Telegram](https://telegram.me/clickhouse_en) allow to chat with ClickHouse users in real-time. +* [Slack](https://join.slack.com/t/clickhousedb/shared_invite/zt-rxm3rdrk-lIUmhLC3V8WTaL0TGxsOmg) and [Telegram](https://telegram.me/clickhouse_en) allow chatting with ClickHouse users in real-time. * [Blog](https://clickhouse.com/blog/en/) contains various ClickHouse-related articles, as well as announcements and reports about events. * [Code Browser](https://clickhouse.com/codebrowser/html_report/ClickHouse/index.html) with syntax highlight and navigation. * [Contacts](https://clickhouse.com/company/#contact) can help to get your questions answered if there are any. From 89ecbfdfe78dd5d02de2fd006b0d882db4259567 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 12 Oct 2021 15:51:19 +0300 Subject: [PATCH 240/264] Update distinctive-features.md --- docs/en/introduction/distinctive-features.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/en/introduction/distinctive-features.md b/docs/en/introduction/distinctive-features.md index 34ba4b89415..daf43dc0da8 100644 --- a/docs/en/introduction/distinctive-features.md +++ b/docs/en/introduction/distinctive-features.md @@ -39,9 +39,9 @@ In ClickHouse, data can reside on different shards. Each shard can be a group of ClickHouse supports a [declarative query language based on SQL](../sql-reference/index.md) that is identical to the ANSI SQL standard in [many cases](../sql-reference/ansi.md). -Supported queries include [GROUP BY](../sql-reference/statements/select/group-by.md), [ORDER BY](../sql-reference/statements/select/order-by.md), subqueries in [FROM](../sql-reference/statements/select/from.md), [JOIN](../sql-reference/statements/select/join.md) clause, [IN](../sql-reference/operators/in.md) operator, and scalar subqueries. +Supported queries include [GROUP BY](../sql-reference/statements/select/group-by.md), [ORDER BY](../sql-reference/statements/select/order-by.md), subqueries in [FROM](../sql-reference/statements/select/from.md), [JOIN](../sql-reference/statements/select/join.md) clause, [IN](../sql-reference/operators/in.md) operator, [window functions](../sql-reference/window-functions.md) and scalar subqueries. -Correlated (dependent) subqueries and window functions are not supported at the time of writing but might become available in the future. +Correlated (dependent) subqueries are not supported at the time of writing but might become available in the future. ## Vector Computation Engine {#vector-engine} From b3610134fdfa41590fbd5b4b1850bab8c47db8b8 Mon Sep 17 00:00:00 2001 From: olgarev <56617294+olgarev@users.noreply.github.com> Date: Tue, 12 Oct 2021 16:31:51 +0300 Subject: [PATCH 241/264] Update docs/ru/sql-reference/statements/select/prewhere.md Co-authored-by: gyuton <40863448+gyuton@users.noreply.github.com> --- docs/ru/sql-reference/statements/select/prewhere.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/sql-reference/statements/select/prewhere.md b/docs/ru/sql-reference/statements/select/prewhere.md index 84f8869b41e..4376cbeb295 100644 --- a/docs/ru/sql-reference/statements/select/prewhere.md +++ b/docs/ru/sql-reference/statements/select/prewhere.md @@ -14,7 +14,7 @@ Prewhere — это оптимизация для более эффективн В запросе может быть одновременно указаны и `PREWHERE`, и `WHERE`. В этом случае `PREWHERE` предшествует `WHERE`. -Если значение параметра [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) равно 0, эвристика по автоматическому перемещнию части выражений из `WHERE` к `PREWHERE` отключается. +Если значение параметра [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) равно 0, эвристика по автоматическому перемещению части выражений из `WHERE` к `PREWHERE` отключается. Если в запросе есть модификатор [FINAL](from.md#select-from-final), оптимизация `PREWHERE` не всегда корректна. Она действует только если включены обе настройки [optimize_move_to_prewhere](../../../operations/settings/settings.md#optimize_move_to_prewhere) и [optimize_move_to_prewhere_if_final](../../../operations/settings/settings.md#optimize_move_to_prewhere_if_final). From 0cfaf9c50861aa931b1b01e90d7e0fcc8a700472 Mon Sep 17 00:00:00 2001 From: olgarev Date: Tue, 12 Oct 2021 13:44:00 +0000 Subject: [PATCH 242/264] Unnecessary links removed --- docs/en/operations/settings/settings.md | 6 ------ docs/ru/operations/settings/settings.md | 6 ------ 2 files changed, 12 deletions(-) diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 0491674b701..aa70eb4f721 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -3798,10 +3798,6 @@ Possible values: Default value: `1`. -**See Also** - -- [PREWHERE](../../sql-reference/statements/select/prewhere.md) clause in `SELECT` queries - ## optimize_move_to_prewhere_if_final {#optimize_move_to_prewhere_if_final} Enables or disables automatic [PREWHERE](../../sql-reference/statements/select/prewhere.md) optimization in [SELECT](../../sql-reference/statements/select/index.md) queries with [FINAL](../../sql-reference/statements/select/from.md#select-from-final) modifier. @@ -3817,6 +3813,4 @@ Default value: `0`. **See Also** -- [PREWHERE](../../sql-reference/statements/select/prewhere.md) clause in `SELECT` queries -- [FINAL](../../sql-reference/statements/select/from.md#select-from-final) modifier in `SELECT` queries - [optimize_move_to_prewhere](#optimize_move_to_prewhere) setting \ No newline at end of file diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 887c59c3b09..bccbbf69e39 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -3587,10 +3587,6 @@ SELECT * FROM positional_arguments ORDER BY 2,3; Значение по умолчанию: `1`. -**См. также** - -- секция [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах `SELECT` - ## optimize_move_to_prewhere_if_final {#optimize_move_to_prewhere_if_final} Включает или отключает автоматическую оптимизацию [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах [SELECT](../../sql-reference/statements/select/index.md) с модификатором [FINAL](../../sql-reference/statements/select/from.md#select-from-final). @@ -3606,6 +3602,4 @@ SELECT * FROM positional_arguments ORDER BY 2,3; **См. также** -- секция [PREWHERE](../../sql-reference/statements/select/prewhere.md) в запросах `SELECT` -- модификатор [FINAL](../../sql-reference/statements/select/from.md#select-from-final) в запросах `SELECT` - настройка [optimize_move_to_prewhere](#optimize_move_to_prewhere) \ No newline at end of file From 63cfc2311bb564aebfd3bb0804aca9fd20b7bfff Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Tue, 12 Oct 2021 19:38:17 +0300 Subject: [PATCH 243/264] Update distinctive-features.md --- docs/en/introduction/distinctive-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/introduction/distinctive-features.md b/docs/en/introduction/distinctive-features.md index daf43dc0da8..951a8a9d3e5 100644 --- a/docs/en/introduction/distinctive-features.md +++ b/docs/en/introduction/distinctive-features.md @@ -39,7 +39,7 @@ In ClickHouse, data can reside on different shards. Each shard can be a group of ClickHouse supports a [declarative query language based on SQL](../sql-reference/index.md) that is identical to the ANSI SQL standard in [many cases](../sql-reference/ansi.md). -Supported queries include [GROUP BY](../sql-reference/statements/select/group-by.md), [ORDER BY](../sql-reference/statements/select/order-by.md), subqueries in [FROM](../sql-reference/statements/select/from.md), [JOIN](../sql-reference/statements/select/join.md) clause, [IN](../sql-reference/operators/in.md) operator, [window functions](../sql-reference/window-functions.md) and scalar subqueries. +Supported queries include [GROUP BY](../sql-reference/statements/select/group-by.md), [ORDER BY](../sql-reference/statements/select/order-by.md), subqueries in [FROM](../sql-reference/statements/select/from.md), [JOIN](../sql-reference/statements/select/join.md) clause, [IN](../sql-reference/operators/in.md) operator, [window functions](../sql-reference/window-functions/index.md) and scalar subqueries. Correlated (dependent) subqueries are not supported at the time of writing but might become available in the future. From 4d5b793f2b6d98d34cc90e7038e89b7d187c6f58 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 22:22:49 +0300 Subject: [PATCH 244/264] Update submodule --- contrib/boost | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/boost b/contrib/boost index 311cfd49896..79358a3106a 160000 --- a/contrib/boost +++ b/contrib/boost @@ -1 +1 @@ -Subproject commit 311cfd498966d4f77742703d605d9c2e7b4cc6a8 +Subproject commit 79358a3106aab6af464430ed67c7efafebf5cd6f From 8d6126fd911c27d64e431bcfa74622346b4225ce Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 22:25:45 +0300 Subject: [PATCH 245/264] Fix build --- cmake/target.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/target.cmake b/cmake/target.cmake index 08a27160985..c1a34d0df13 100644 --- a/cmake/target.cmake +++ b/cmake/target.cmake @@ -34,6 +34,8 @@ if (CMAKE_CROSSCOMPILING) endif () elseif (OS_FREEBSD) # FIXME: broken dependencies + set (ENABLE_PARQUET OFF CACHE INTERNAL "") + set (ENABLE_ORC OFF CACHE INTERNAL "") set (ENABLE_GRPC OFF CACHE INTERNAL "") else () message (FATAL_ERROR "Trying to cross-compile to unsupported system: ${CMAKE_SYSTEM_NAME}!") From 65b63a67da556ca671ad7c8c1a3c28a305097b1d Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 23:03:20 +0300 Subject: [PATCH 246/264] Add a script for convenient install on multiple OS --- docs/_includes/install/universal.sh | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100755 docs/_includes/install/universal.sh diff --git a/docs/_includes/install/universal.sh b/docs/_includes/install/universal.sh new file mode 100755 index 00000000000..b5f833b19a6 --- /dev/null +++ b/docs/_includes/install/universal.sh @@ -0,0 +1,59 @@ +#!/bin/sh -e + +OS=$(uname -s) +ARCH=$(uname -m) + +DIR= + +if [ "${OS}" = "Linux" ] +then + if [ "${ARCH}" = "x86_64" ] + then + DIR="amd64" + elif [ "${ARCH}" = "aarch64" ] + then + DIR="aarch64" + elif [ "${ARCH}" = "powerpc64le" ] + then + DIR="powerpc64le" + fi +elif [ "${OS}" = "FreeBSD" ] +then + if [ "${ARCH}" = "x86_64" ] + then + DIR="freebsd" + elif [ "${ARCH}" = "aarch64" ] + then + #DIR="freebsd-aarch64" + elif [ "${ARCH}" = "powerpc64le" ] + then + #DIR="freebsd-powerpc64le" + fi +elif [ "${OS}" = "Darwin" ] +then + if [ "${ARCH}" = "x86_64" ] + then + DIR="macos" + elif [ "${ARCH}" = "aarch64" ] + then + DIR="macos-aarch64" + fi +fi + +if [ -z "${DIR}" ] +then + echo "The '${OS}' operating system with the '${ARCH}' architecture is not supported." + exit 1 +fi + +URL="https://builds.clickhouse.com/master/${DIR}/clickhouse" +echo "Will download ${URL}" +curl -O "${URL}" && chmod a+x clickhouse && +echo "Successfully downloaded the ClickHouse binary, you can run it as: + ./clickhouse" + +if [ "${OS}" = "Linux" ] +then + echo "You can also install it: + ./clickhouse install" +fi From ac403b1df259df7084c89d57ea77bfad4c914783 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 12 Oct 2021 23:09:26 +0300 Subject: [PATCH 247/264] Publish the install script --- docs/_includes/install/universal.sh | 2 +- docs/tools/website.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/_includes/install/universal.sh b/docs/_includes/install/universal.sh index b5f833b19a6..db1072f149f 100755 --- a/docs/_includes/install/universal.sh +++ b/docs/_includes/install/universal.sh @@ -55,5 +55,5 @@ echo "Successfully downloaded the ClickHouse binary, you can run it as: if [ "${OS}" = "Linux" ] then echo "You can also install it: - ./clickhouse install" + sudo ./clickhouse install" fi diff --git a/docs/tools/website.py b/docs/tools/website.py index 5e4f48e3441..54804ae3f36 100644 --- a/docs/tools/website.py +++ b/docs/tools/website.py @@ -156,6 +156,11 @@ def build_website(args): os.path.join(args.src_dir, 'utils', 'list-versions', 'version_date.tsv'), os.path.join(args.output_dir, 'data', 'version_date.tsv')) + # This file can be requested to install ClickHouse. + shutil.copy2( + os.path.join(args.src_dir, 'docs', '_includes', 'install', 'universal.sh'), + os.path.join(args.output_dir, 'data', 'install.sh')) + for root, _, filenames in os.walk(args.output_dir): for filename in filenames: if filename == 'main.html': @@ -218,7 +223,7 @@ def minify_file(path, css_digest, js_digest): # TODO: restore cssmin # elif path.endswith('.css'): # content = cssmin.cssmin(content) -# TODO: restore jsmin +# TODO: restore jsmin # elif path.endswith('.js'): # content = jsmin.jsmin(content) with open(path, 'wb') as f: From a30573fc0a8ceb3b9deae5d667f886f819bdac1f Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Thu, 30 Sep 2021 18:44:30 +0300 Subject: [PATCH 248/264] Add FAIL message to test_results.tsv --- .../util/process_functional_tests_result.py | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/docker/test/util/process_functional_tests_result.py b/docker/test/util/process_functional_tests_result.py index e60424ad4d1..ae8d49836d8 100755 --- a/docker/test/util/process_functional_tests_result.py +++ b/docker/test/util/process_functional_tests_result.py @@ -49,19 +49,24 @@ def process_test_log(log_path): total += 1 if TIMEOUT_SIGN in line: failed += 1 - test_results.append((test_name, "Timeout", test_time)) + test_results.append((test_name, "Timeout", test_time, [])) elif FAIL_SIGN in line: failed += 1 - test_results.append((test_name, "FAIL", test_time)) + test_results.append((test_name, "FAIL", test_time, [])) elif UNKNOWN_SIGN in line: unknown += 1 - test_results.append((test_name, "FAIL", test_time)) + test_results.append((test_name, "FAIL", test_time, [])) elif SKIPPED_SIGN in line: skipped += 1 - test_results.append((test_name, "SKIPPED", test_time)) + test_results.append((test_name, "SKIPPED", test_time, [])) else: success += int(OK_SIGN in line) - test_results.append((test_name, "OK", test_time)) + test_results.append((test_name, "OK", test_time, [])) + elif len(test_results) > 0 and test_results[-1][1] == "FAIL": + test_results[-1][3].append(line) + + test_results = [(test[0], test[1], test[2], ''.join(test[3])) for test in test_results] + return total, skipped, unknown, failed, success, hung, task_timeout, retries, test_results def process_result(result_path): @@ -89,14 +94,14 @@ def process_result(result_path): if hung: description = "Some queries hung, " state = "failure" - test_results.append(("Some queries hung", "FAIL", "0")) + test_results.append(("Some queries hung", "FAIL", "0", "")) elif task_timeout: description = "Timeout, " state = "failure" - test_results.append(("Timeout", "FAIL", "0")) + test_results.append(("Timeout", "FAIL", "0", "")) elif retries: description = "Some tests restarted, " - test_results.append(("Some tests restarted", "SKIPPED", "0")) + test_results.append(("Some tests restarted", "SKIPPED", "0", "")) else: description = "" From 05073910104801c2a40e3fba33932422abc15ae3 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Wed, 6 Oct 2021 23:07:30 +0300 Subject: [PATCH 249/264] Do not stop CI tests processing if clickhouse-test return 1 --- docker/test/fasttest/run.sh | 2 ++ docker/test/stateful/run.sh | 2 ++ docker/test/stateless/run.sh | 2 ++ 3 files changed, 6 insertions(+) diff --git a/docker/test/fasttest/run.sh b/docker/test/fasttest/run.sh index c8a3ad7c998..f4b99603554 100755 --- a/docker/test/fasttest/run.sh +++ b/docker/test/fasttest/run.sh @@ -262,11 +262,13 @@ function run_tests start_server + set +e time clickhouse-test --hung-check -j 8 --order=random \ --fast-tests-only --no-long --testname --shard --zookeeper \ -- "$FASTTEST_FOCUS" 2>&1 \ | ts '%Y-%m-%d %H:%M:%S' \ | tee "$FASTTEST_OUTPUT/test_result.txt" + set -e } case "$stage" in diff --git a/docker/test/stateful/run.sh b/docker/test/stateful/run.sh index dd5984fd7b5..69b435857d9 100755 --- a/docker/test/stateful/run.sh +++ b/docker/test/stateful/run.sh @@ -108,8 +108,10 @@ function run_tests() ADDITIONAL_OPTIONS+=('--replicated-database') fi + set +e clickhouse-test --testname --shard --zookeeper --no-stateless --hung-check --print-time "${ADDITIONAL_OPTIONS[@]}" \ "$SKIP_TESTS_OPTION" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee test_output/test_result.txt + set -e } export -f run_tests diff --git a/docker/test/stateless/run.sh b/docker/test/stateless/run.sh index ed721690281..97e1ea955b1 100755 --- a/docker/test/stateless/run.sh +++ b/docker/test/stateless/run.sh @@ -96,10 +96,12 @@ function run_tests() ADDITIONAL_OPTIONS+=('8') fi + set +e clickhouse-test --testname --shard --zookeeper --hung-check --print-time \ --test-runs "$NUM_TRIES" "${ADDITIONAL_OPTIONS[@]}" 2>&1 \ | ts '%Y-%m-%d %H:%M:%S' \ | tee -a test_output/test_result.txt + set -e } export -f run_tests From fa9cdd5c5fba6719cf21f1b31d805ff9233a2b93 Mon Sep 17 00:00:00 2001 From: Dmitry Novik Date: Thu, 7 Oct 2021 12:49:41 +0300 Subject: [PATCH 250/264] Use original whitespaces in test_results.tsv --- docker/test/util/process_functional_tests_result.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker/test/util/process_functional_tests_result.py b/docker/test/util/process_functional_tests_result.py index ae8d49836d8..82df170686d 100755 --- a/docker/test/util/process_functional_tests_result.py +++ b/docker/test/util/process_functional_tests_result.py @@ -28,6 +28,7 @@ def process_test_log(log_path): test_results = [] with open(log_path, 'r') as test_file: for line in test_file: + original_line = line line = line.strip() if any(s in line for s in NO_TASK_TIMEOUT_SIGNS): task_timeout = False @@ -63,7 +64,7 @@ def process_test_log(log_path): success += int(OK_SIGN in line) test_results.append((test_name, "OK", test_time, [])) elif len(test_results) > 0 and test_results[-1][1] == "FAIL": - test_results[-1][3].append(line) + test_results[-1][3].append(original_line) test_results = [(test[0], test[1], test[2], ''.join(test[3])) for test in test_results] From e9ce859b022751d7511da4730432db0f592eb96d Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Tue, 12 Oct 2021 23:45:23 +0300 Subject: [PATCH 251/264] Fix race between MOVE PARTITION and merges/mutations for MergeTree From time to time 00975_move_partition_merge_tree test got failed, the reason is that there is merge in progress that writes data to the source table again:
2021.10.12 13:20:40.243839 [ 26955 ] {2dbfea50-639e-49ac-9e82-933a00ea04a3} executeQuery: (from [::1]:38060) (comment: 00975_move_partition_merge_tree.sql) ALTER TABLE test_move_partition_src MOVE PARTITION 1 TO TABLE test_move_partition_dest; 2021.10.12 13:20:40.244482 [ 26955 ] {2dbfea50-639e-49ac-9e82-933a00ea04a3} test_t1tzb2.test_move_partition_dest (cab3b005-d54b-4cdc-8ab3-b005d54becdc): Cloning part /var/lib/clickhouse/store/467/467d7145-b47e-444e-867d-7145b47ea44e/1_2_2_0/ to /var/lib/clickhouse/store/cab/cab3b005-d54b-4cdc-8ab3-b005d54becdc/tmp_move_from_1_21_21_0 ... 2021.10.12 13:20:40.373487 [ 378 ] {} test_t1tzb2.test_move_partition_src (467d7145-b47e-444e-867d-7145b47ea44e) (MergerMutator): Merged 6 parts: from 1_2_2_0 to 1_11_11_0 ... 2021.10.12 13:20:40.379750 [ 26955 ] {2dbfea50-639e-49ac-9e82-933a00ea04a3} test_t1tzb2.test_move_partition_dest (cab3b005-d54b-4cdc-8ab3-b005d54becdc): Cloning part /var/lib/clickhouse/store/467/467d7145-b47e-444e-867d-7145b47ea44e/1_15_15_0/ to /var/lib/clickhouse/store/cab/cab3b005-d54b-4cdc-8ab3-b005d54becdc/tmp_move_from_1_28_28_0
And also remove cleaning of mutations since this will cause deadlock after doing MOVE PARTITION under currently_processing_in_background_mutex. CI: https://clickhouse-test-reports.s3.yandex.net/0/a59c6b1c8eb47ebf77189a491ee0c3980b38e91c/functional_stateless_tests_ Fixes: 00975_move_partition_merge_tree --- src/Storages/StorageMergeTree.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Storages/StorageMergeTree.cpp b/src/Storages/StorageMergeTree.cpp index b710965271e..ab42da1dfa0 100644 --- a/src/Storages/StorageMergeTree.cpp +++ b/src/Storages/StorageMergeTree.cpp @@ -1447,6 +1447,11 @@ void StorageMergeTree::replacePartitionFrom(const StoragePtr & source_table, con void StorageMergeTree::movePartitionToTable(const StoragePtr & dest_table, const ASTPtr & partition, ContextPtr local_context) { + /// MOVE PARTITION cannot be run in parallel with merges/mutations, + /// since otherwise there can be some merge/mutation in progress, + /// that will be created in the source table after MOVE PARTITION. + std::unique_lock background_lock(currently_processing_in_background_mutex); + auto lock1 = lockForShare(local_context->getCurrentQueryId(), local_context->getSettingsRef().lock_acquire_timeout); auto lock2 = dest_table->lockForShare(local_context->getCurrentQueryId(), local_context->getSettingsRef().lock_acquire_timeout); @@ -1509,7 +1514,6 @@ void StorageMergeTree::movePartitionToTable(const StoragePtr & dest_table, const transaction.commit(&lock); } - clearOldMutations(true); clearOldPartsFromFilesystem(); PartLog::addNewParts(getContext(), dst_parts, watch.elapsed()); From dea5b5529feb27302104331d9812772d2ac1544d Mon Sep 17 00:00:00 2001 From: Thom O'Connor Date: Tue, 12 Oct 2021 15:44:48 -0600 Subject: [PATCH 252/264] Updated adopters.md to include Sipfront --- docs/en/introduction/adopters.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/en/introduction/adopters.md b/docs/en/introduction/adopters.md index a6df18b323c..c511bd97a7c 100644 --- a/docs/en/introduction/adopters.md +++ b/docs/en/introduction/adopters.md @@ -115,6 +115,7 @@ toc_title: Adopters | seo.do | Analytics | Main product | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup35/CH%20Presentation-%20Metehan%20Çetinkaya.pdf) | | SGK | Government Social Security | Analytics | — | — | [Slides in English, November 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup35/ClickHouse%20Meetup-Ramazan%20POLAT.pdf) | | Sina | News | — | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/6.%20ClickHouse最佳实践%20高鹏_新浪.pdf) | +| Sipfront | Analytics | — | — | — | [Tweet, October 2021](https://twitter.com/andreasgranig/status/1446404332337913895?s=20) | | SMI2 | News | Analytics | — | — | [Blog Post in Russian, November 2017](https://habr.com/ru/company/smi2/blog/314558/) | | Spark New Zealand | Telecommunications | Security Operations | — | — | [Blog Post, Feb 2020](https://blog.n0p.me/2020/02/2020-02-05-dnsmonster/) | | Splitbee | Analytics | Main Product | — | — | [Blog Post, Mai 2021](https://splitbee.io/blog/new-pricing) | From 26dd0934d34782afcf22905d76b35740046f2546 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 13 Oct 2021 01:14:47 +0300 Subject: [PATCH 253/264] Update target.cmake --- cmake/target.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/target.cmake b/cmake/target.cmake index c1a34d0df13..3c02c4313f1 100644 --- a/cmake/target.cmake +++ b/cmake/target.cmake @@ -37,6 +37,7 @@ if (CMAKE_CROSSCOMPILING) set (ENABLE_PARQUET OFF CACHE INTERNAL "") set (ENABLE_ORC OFF CACHE INTERNAL "") set (ENABLE_GRPC OFF CACHE INTERNAL "") + set (ENABLE_EMBEDDED_COMPILER OFF CACHE INTERNAL "") else () message (FATAL_ERROR "Trying to cross-compile to unsupported system: ${CMAKE_SYSTEM_NAME}!") endif () From be5d49fd894351c150fe5e50c3d716cde0413a21 Mon Sep 17 00:00:00 2001 From: Cody Baker Date: Tue, 12 Oct 2021 16:16:23 -0600 Subject: [PATCH 254/264] Migrate changes in compiled css to sass source --- website/src/scss/components/_hero.scss | 28 ++++++++++++++++++++++++ website/src/scss/components/_navbar.scss | 8 ++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/website/src/scss/components/_hero.scss b/website/src/scss/components/_hero.scss index 7c3bab209e4..61b22b3e32b 100644 --- a/website/src/scss/components/_hero.scss +++ b/website/src/scss/components/_hero.scss @@ -28,3 +28,31 @@ margin-bottom: -160px; padding-bottom: 160px; } + +.base-hero { + height:22.5vw; + max-height:324px; + min-height:280px; +} +.index-hero { + background-image:url('/images/backgrounds/bg-hero-home.svg'); + height:68vw; + max-height:980px; + max-width:2448px; + width:170vw; +} +.other-hero { + background-image: url('/images/backgrounds/bg-hero.svg'); + max-width: 2448px; + width: 170vw; +} +.bg-footer-cta { + background-image:url('/images/backgrounds/bg-footer-cta.svg'); + width:2448px; +} +.quickstart-bg { + background-image:url('/images/backgrounds/bg-quick-start.svg'); + height:40vw; + top:220px; + width:170vw; +} diff --git a/website/src/scss/components/_navbar.scss b/website/src/scss/components/_navbar.scss index 179e4ff1f60..53a834d2ed7 100644 --- a/website/src/scss/components/_navbar.scss +++ b/website/src/scss/components/_navbar.scss @@ -1,11 +1,13 @@ -.navbar { +.navbar-clickhouse { border-bottom: 4px solid $gray-100; height: 142px; > .container { flex-wrap: wrap; } +} +.navbar { &-super { flex-shrink: 0; width: 100%; @@ -38,8 +40,8 @@ } } - &-brand { - background: no-repeat url(#{"../images/logo.svg"}); + &-brand-clickhouse { + background: no-repeat url(#{"../images/logo-clickhouse.svg"}); background-size: contain; flex-shrink: 0; height: 28px; From f7091c4adb8ed89ff6fbd11627134fe10a6ab4cb Mon Sep 17 00:00:00 2001 From: Cody Baker Date: Tue, 12 Oct 2021 16:16:39 -0600 Subject: [PATCH 255/264] Add greenhouse careers page --- docs/tools/webpack.config.js | 1 + docs/tools/website.py | 8 +- website/careers/index.html | 26 + website/css/bootstrap.css | 16035 +------------------- website/css/greenhouse.css | 1 + website/css/main.css | 1040 +- website/js/main.js | 159 +- website/src/js/main.js | 1 + website/src/js/utilities/greenhouse.js | 16 + website/src/scss/greenhouse.scss | 27 + website/templates/careers/greenhouse.html | 8 + website/templates/careers/hero.html | 10 + website/templates/careers/overview.html | 11 + website/templates/company/team.html | 2 +- 14 files changed, 112 insertions(+), 17233 deletions(-) create mode 100644 website/careers/index.html create mode 100644 website/css/greenhouse.css create mode 100644 website/src/js/utilities/greenhouse.js create mode 100644 website/src/scss/greenhouse.scss create mode 100644 website/templates/careers/greenhouse.html create mode 100644 website/templates/careers/hero.html create mode 100644 website/templates/careers/overview.html diff --git a/docs/tools/webpack.config.js b/docs/tools/webpack.config.js index e0dea964101..fcb3e7bf32d 100644 --- a/docs/tools/webpack.config.js +++ b/docs/tools/webpack.config.js @@ -14,6 +14,7 @@ module.exports = { entry: [ path.resolve(scssPath, 'bootstrap.scss'), + path.resolve(scssPath, 'greenhouse.scss'), path.resolve(scssPath, 'main.scss'), path.resolve(jsPath, 'main.js'), ], diff --git a/docs/tools/website.py b/docs/tools/website.py index 5e4f48e3441..4389ae9af3b 100644 --- a/docs/tools/website.py +++ b/docs/tools/website.py @@ -218,7 +218,7 @@ def minify_file(path, css_digest, js_digest): # TODO: restore cssmin # elif path.endswith('.css'): # content = cssmin.cssmin(content) -# TODO: restore jsmin +# TODO: restore jsmin # elif path.endswith('.js'): # content = jsmin.jsmin(content) with open(path, 'wb') as f: @@ -226,6 +226,12 @@ def minify_file(path, css_digest, js_digest): def minify_website(args): + # Output greenhouse css separately from main bundle to be included via the greenhouse iframe + command = f"cat '{args.website_dir}/css/greenhouse.css' > '{args.output_dir}/css/greenhouse.css'" + logging.info(command) + output = subprocess.check_output(command, shell=True) + logging.debug(output) + css_in = ' '.join(get_css_in(args)) css_out = f'{args.output_dir}/css/base.css' if args.minify: diff --git a/website/careers/index.html b/website/careers/index.html new file mode 100644 index 00000000000..14e23e3357c --- /dev/null +++ b/website/careers/index.html @@ -0,0 +1,26 @@ +{% set prefetch_items = [ + ('/docs/en/', 'document') +] %} + +{% extends "templates/base.html" %} + +{% block extra_meta %} +{% include "templates/common_fonts.html" %} +{% endblock %} + +{% block nav %} + +{% include "templates/global/nav.html" %} + +{% endblock %} + +{% block content %} + +{% include "templates/careers/hero.html" %} +{% include "templates/careers/overview.html" %} +{% include "templates/careers/greenhouse.html" %} + +{% include "templates/global/newsletter.html" %} +{% include "templates/global/github_stars.html" %} + +{% endblock %} diff --git a/website/css/bootstrap.css b/website/css/bootstrap.css index 92e98ef2c66..b65cbbfed01 100644 --- a/website/css/bootstrap.css +++ b/website/css/bootstrap.css @@ -1,16039 +1,6 @@ -@charset "UTF-8"; /*! * Bootstrap v4.4.1 (https://getbootstrap.com/) * Copyright 2011-2019 The Bootstrap Authors * Copyright 2011-2019 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ -:root { - --blue: #007bff; - --indigo: #6610f2; - --purple: #6f42c1; - --pink: #e83e8c; - --red: #dc3545; - --orange: #fd7e14; - --yellow: #ffc107; - --green: #28a745; - --teal: #20c997; - --cyan: #17a2b8; - --white: #fff; - --gray: #6c757d; - --gray-dark: #343a40; - --brand-primary: #ffcc00; - --brand-secondary: #ff3939; - --primary-accent-yellow: #ffcc00; - --primary-accent-light-yellow: #fffaf0; - --primary-accent-blue: #257af4; - --primary-accent-light-blue: #e3f1fe; - --secondary-accent-orange: #ff8c00; - --secondary-accent-light-orange: #ffe4b5; - --secondary-accent-red: #ff3939; - --secondary-accent-light-red: #ffe4e1; - --primary: #ffcc00; - --secondary: #212529; - --success: #28a745; - --info: #17a2b8; - --warning: #ffc107; - --danger: #dc3545; - --light: #f1f6f9; - --dark: #495057; - --primary-light: #fffaf0; - --secondary-light: #fff; - --tertiary: #257af4; - --tertiary-light: #e3f1fe; - --white: #fff; - --black: #212529; - --blue: #257af4; - --light-blue: #e3f1fe; - --yellow: #ffcc00; - --light-yellow: #fffaf0; - --orange: #ff8c00; - --light-orange: #ffe4b5; - --red: #ff3939; - --light-red: #ffe4e1; - --medium: #d6dbdf; - --breakpoint-xxs: 0; - --breakpoint-xs: 400px; - --breakpoint-sm: 616px; - --breakpoint-md: 768px; - --breakpoint-lg: 980px; - --breakpoint-xl: 1240px; - --font-family-sans-serif: "Noto Sans", sans-serif; - --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; -} - -*, -*::before, -*::after { - box-sizing: border-box; -} - -html { - font-family: sans-serif; - line-height: 1.15; - -webkit-text-size-adjust: 100%; - -webkit-tap-highlight-color: rgba(33, 37, 41, 0); -} - -article, aside, figcaption, figure, footer, header, hgroup, main, nav, section { - display: block; -} - -body { - margin: 0; - font-family: "Noto Sans", sans-serif; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #212529; - text-align: left; - background-color: #fff; -} - -[tabindex="-1"]:focus:not(:focus-visible) { - outline: 0 !important; -} - -hr { - box-sizing: content-box; - height: 0; - overflow: visible; -} - -h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: 16px; -} - -p { - margin-top: 0; - margin-bottom: 1rem; -} - -abbr[title], -abbr[data-original-title] { - text-decoration: underline; - -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; - cursor: help; - border-bottom: 0; - -webkit-text-decoration-skip-ink: none; - text-decoration-skip-ink: none; -} - -address { - margin-bottom: 1rem; - font-style: normal; - line-height: inherit; -} - -ol, -ul, -dl { - margin-top: 0; - margin-bottom: 1rem; -} - -ol ol, -ul ul, -ol ul, -ul ol { - margin-bottom: 0; -} - -dt { - font-weight: 700; -} - -dd { - margin-bottom: 0.5rem; - margin-left: 0; -} - -blockquote { - margin: 0 0 1rem; -} - -b, -strong { - font-weight: bolder; -} - -small { - font-size: 80%; -} - -sub, -sup { - position: relative; - font-size: 75%; - line-height: 0; - vertical-align: baseline; -} - -sub { - bottom: -0.25em; -} - -sup { - top: -0.5em; -} - -a { - color: #ff8c00; - text-decoration: none; - background-color: transparent; -} -a:hover { - color: #ff8c00; - text-decoration: underline; -} - -a:not([href]) { - color: inherit; - text-decoration: none; -} -a:not([href]):hover { - color: inherit; - text-decoration: none; -} - -pre, -code, -kbd, -samp { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; - font-size: 1em; -} - -pre { - margin-top: 0; - margin-bottom: 1rem; - overflow: auto; -} - -figure { - margin: 0 0 1rem; -} - -img { - vertical-align: middle; - border-style: none; -} - -svg { - overflow: hidden; - vertical-align: middle; -} - -table { - border-collapse: collapse; -} - -caption { - padding-top: 0.75rem; - padding-bottom: 0.75rem; - color: #6c757d; - text-align: left; - caption-side: bottom; -} - -th { - text-align: inherit; -} - -label { - display: inline-block; - margin-bottom: 0.5rem; -} - -button { - border-radius: 0; -} - -button:focus { - outline: 1px dotted; - outline: 5px auto -webkit-focus-ring-color; -} - -input, -button, -select, -optgroup, -textarea { - margin: 0; - font-family: inherit; - font-size: inherit; - line-height: inherit; -} - -button, -input { - overflow: visible; -} - -button, -select { - text-transform: none; -} - -select { - word-wrap: normal; -} - -button, -[type=button], -[type=reset], -[type=submit] { - -webkit-appearance: button; -} - -button:not(:disabled), -[type=button]:not(:disabled), -[type=reset]:not(:disabled), -[type=submit]:not(:disabled) { - cursor: pointer; -} - -button::-moz-focus-inner, -[type=button]::-moz-focus-inner, -[type=reset]::-moz-focus-inner, -[type=submit]::-moz-focus-inner { - padding: 0; - border-style: none; -} - -input[type=radio], -input[type=checkbox] { - box-sizing: border-box; - padding: 0; -} - -input[type=date], -input[type=time], -input[type=datetime-local], -input[type=month] { - -webkit-appearance: listbox; -} - -textarea { - overflow: auto; - resize: vertical; -} - -fieldset { - min-width: 0; - padding: 0; - margin: 0; - border: 0; -} - -legend { - display: block; - width: 100%; - max-width: 100%; - padding: 0; - margin-bottom: 0.5rem; - font-size: 1.5rem; - line-height: inherit; - color: inherit; - white-space: normal; -} -@media (max-width: 1200px) { - legend { - font-size: calc(1.275rem + 0.3vw); - } -} - -progress { - vertical-align: baseline; -} - -[type=number]::-webkit-inner-spin-button, -[type=number]::-webkit-outer-spin-button { - height: auto; -} - -[type=search] { - outline-offset: -2px; - -webkit-appearance: none; -} - -[type=search]::-webkit-search-decoration { - -webkit-appearance: none; -} - -::-webkit-file-upload-button { - font: inherit; - -webkit-appearance: button; -} - -output { - display: inline-block; -} - -summary { - display: list-item; - cursor: pointer; -} - -template { - display: none; -} - -[hidden] { - display: none !important; -} - -h1, h2, h3, h4, h5, h6, -.h1, .h2, .h3, .h4, .h5, .h6 { - margin-bottom: 16px; - font-family: "Hind Siliguri", sans-serif; - font-weight: 500; - line-height: 1.125; -} - -h1, .h1 { - font-size: 2.5rem; -} -@media (max-width: 1200px) { - h1, .h1 { - font-size: calc(1.375rem + 1.5vw); - } -} - -h2, .h2 { - font-size: 2rem; -} -@media (max-width: 1200px) { - h2, .h2 { - font-size: calc(1.325rem + 0.9vw); - } -} - -h3, .h3 { - font-size: 1.75rem; -} -@media (max-width: 1200px) { - h3, .h3 { - font-size: calc(1.3rem + 0.6vw); - } -} - -h4, .h4 { - font-size: 1.5rem; -} -@media (max-width: 1200px) { - h4, .h4 { - font-size: calc(1.275rem + 0.3vw); - } -} - -h5, .h5 { - font-size: 1.125rem; -} - -h6, .h6 { - font-size: 0.875rem; -} - -.lead { - font-size: 1.375rem; - font-weight: 400; -} -@media (max-width: 1200px) { - .lead { - font-size: calc(1.2625rem + 0.15vw); - } -} - -.display-1 { - font-size: 4rem; - font-weight: 600; - line-height: 1.125; -} -@media (max-width: 1200px) { - .display-1 { - font-size: calc(1.525rem + 3.3vw); - } -} - -.display-2 { - font-size: 2.5rem; - font-weight: 600; - line-height: 1.125; -} -@media (max-width: 1200px) { - .display-2 { - font-size: calc(1.375rem + 1.5vw); - } -} - -.display-3 { - font-size: 2rem; - font-weight: 500; - line-height: 1.125; -} -@media (max-width: 1200px) { - .display-3 { - font-size: calc(1.325rem + 0.9vw); - } -} - -.display-4 { - font-size: 1.75rem; - font-weight: 500; - line-height: 1.125; -} -@media (max-width: 1200px) { - .display-4 { - font-size: calc(1.3rem + 0.6vw); - } -} - -hr { - margin-top: 8px; - margin-bottom: 8px; - border: 0; - border-top: 1px solid rgba(33, 37, 41, 0.1); -} - -small, -.small { - font-size: 80%; - font-weight: 400; -} - -mark, -.mark { - padding: 0.2em; - background-color: #fcf8e3; -} - -.list-unstyled { - padding-left: 0; - list-style: none; -} - -.list-inline { - padding-left: 0; - list-style: none; -} - -.list-inline-item { - display: inline-block; -} -.list-inline-item:not(:last-child) { - margin-right: 0.5rem; -} - -.initialism { - font-size: 90%; - text-transform: uppercase; -} - -.blockquote { - margin-bottom: 8px; - font-size: 1.25rem; -} - -.blockquote-footer { - display: block; - font-size: 80%; - color: #6c757d; -} -.blockquote-footer::before { - content: "— "; -} - -.img-fluid { - max-width: 100%; - height: auto; -} - -.img-thumbnail { - padding: 0.25rem; - background-color: #fff; - border: 1px solid #dee2e6; - border-radius: 8px; - max-width: 100%; - height: auto; -} - -.figure { - display: inline-block; -} - -.figure-img { - margin-bottom: 4px; - line-height: 1; -} - -.figure-caption { - font-size: 90%; - color: #6c757d; -} - -code { - font-size: 87.5%; - color: #e83e8c; - word-wrap: break-word; -} -a > code { - color: inherit; -} - -kbd { - padding: 0.2rem 0.4rem; - font-size: 87.5%; - color: #fff; - background-color: #495057; - border-radius: 8px; -} -kbd kbd { - padding: 0; - font-size: 100%; - font-weight: 700; -} - -pre { - display: block; - font-size: 87.5%; - color: #495057; -} -pre code { - font-size: inherit; - color: inherit; - word-break: normal; -} - -.pre-scrollable { - max-height: 340px; - overflow-y: scroll; -} - -.container { - width: 100%; - padding-right: 20px; - padding-left: 20px; - margin-right: auto; - margin-left: auto; -} -@media (min-width: 400px) { - .container { - max-width: 576px; - } -} -@media (min-width: 616px) { - .container { - max-width: 576px; - } -} -@media (min-width: 768px) { - .container { - max-width: 958px; - } -} -@media (min-width: 980px) { - .container { - max-width: 1008px; - } -} -@media (min-width: 1240px) { - .container { - max-width: 1118px; - } -} - -.container-fluid, .container-xl, .container-lg, .container-md, .container-sm, .container-xs { - width: 100%; - padding-right: 20px; - padding-left: 20px; - margin-right: auto; - margin-left: auto; -} - -@media (min-width: 400px) { - .container-xs, .container { - max-width: 576px; - } -} -@media (min-width: 616px) { - .container-sm, .container-xs, .container { - max-width: 576px; - } -} -@media (min-width: 768px) { - .container-md, .container-sm, .container-xs, .container { - max-width: 958px; - } -} -@media (min-width: 980px) { - .container-lg, .container-md, .container-sm, .container-xs, .container { - max-width: 1008px; - } -} -@media (min-width: 1240px) { - .container-xl, .container-lg, .container-md, .container-sm, .container-xs, .container { - max-width: 1118px; - } -} -.row { - display: flex; - flex-wrap: wrap; - margin-right: -20px; - margin-left: -20px; -} - -.no-gutters { - margin-right: 0; - margin-left: 0; -} -.no-gutters > .col, -.no-gutters > [class*=col-] { - padding-right: 0; - padding-left: 0; -} - -.col-xl, -.col-xl-auto, .col-xl-12, .col-xl-11, .col-xl-10, .col-xl-9, .col-xl-8, .col-xl-7, .col-xl-6, .col-xl-5, .col-xl-4, .col-xl-3, .col-xl-2, .col-xl-1, .col-lg, -.col-lg-auto, .col-lg-12, .col-lg-11, .col-lg-10, .col-lg-9, .col-lg-8, .col-lg-7, .col-lg-6, .col-lg-5, .col-lg-4, .col-lg-3, .col-lg-2, .col-lg-1, .col-md, -.col-md-auto, .col-md-12, .col-md-11, .col-md-10, .col-md-9, .col-md-8, .col-md-7, .col-md-6, .col-md-5, .col-md-4, .col-md-3, .col-md-2, .col-md-1, .col-sm, -.col-sm-auto, .col-sm-12, .col-sm-11, .col-sm-10, .col-sm-9, .col-sm-8, .col-sm-7, .col-sm-6, .col-sm-5, .col-sm-4, .col-sm-3, .col-sm-2, .col-sm-1, .col-xs, -.col-xs-auto, .col-xs-12, .col-xs-11, .col-xs-10, .col-xs-9, .col-xs-8, .col-xs-7, .col-xs-6, .col-xs-5, .col-xs-4, .col-xs-3, .col-xs-2, .col-xs-1, .col, -.col-auto, .col-12, .col-11, .col-10, .col-9, .col-8, .col-7, .col-6, .col-5, .col-4, .col-3, .col-2, .col-1 { - position: relative; - width: 100%; - padding-right: 20px; - padding-left: 20px; -} - -.col { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; -} - -.row-cols-1 > * { - flex: 0 0 100%; - max-width: 100%; -} - -.row-cols-2 > * { - flex: 0 0 50%; - max-width: 50%; -} - -.row-cols-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; -} - -.row-cols-4 > * { - flex: 0 0 25%; - max-width: 25%; -} - -.row-cols-5 > * { - flex: 0 0 20%; - max-width: 20%; -} - -.row-cols-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; -} - -.col-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; -} - -.col-1 { - flex: 0 0 8.3333333333%; - max-width: 8.3333333333%; -} - -.col-2 { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; -} - -.col-3 { - flex: 0 0 25%; - max-width: 25%; -} - -.col-4 { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; -} - -.col-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; -} - -.col-6 { - flex: 0 0 50%; - max-width: 50%; -} - -.col-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; -} - -.col-8 { - flex: 0 0 66.6666666667%; - max-width: 66.6666666667%; -} - -.col-9 { - flex: 0 0 75%; - max-width: 75%; -} - -.col-10 { - flex: 0 0 83.3333333333%; - max-width: 83.3333333333%; -} - -.col-11 { - flex: 0 0 91.6666666667%; - max-width: 91.6666666667%; -} - -.col-12 { - flex: 0 0 100%; - max-width: 100%; -} - -.order-first { - order: -1; -} - -.order-last { - order: 13; -} - -.order-0 { - order: 0; -} - -.order-1 { - order: 1; -} - -.order-2 { - order: 2; -} - -.order-3 { - order: 3; -} - -.order-4 { - order: 4; -} - -.order-5 { - order: 5; -} - -.order-6 { - order: 6; -} - -.order-7 { - order: 7; -} - -.order-8 { - order: 8; -} - -.order-9 { - order: 9; -} - -.order-10 { - order: 10; -} - -.order-11 { - order: 11; -} - -.order-12 { - order: 12; -} - -.offset-1 { - margin-left: 8.3333333333%; -} - -.offset-2 { - margin-left: 16.6666666667%; -} - -.offset-3 { - margin-left: 25%; -} - -.offset-4 { - margin-left: 33.3333333333%; -} - -.offset-5 { - margin-left: 41.6666666667%; -} - -.offset-6 { - margin-left: 50%; -} - -.offset-7 { - margin-left: 58.3333333333%; -} - -.offset-8 { - margin-left: 66.6666666667%; -} - -.offset-9 { - margin-left: 75%; -} - -.offset-10 { - margin-left: 83.3333333333%; -} - -.offset-11 { - margin-left: 91.6666666667%; -} - -@media (min-width: 400px) { - .col-xs { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - .row-cols-xs-1 > * { - flex: 0 0 100%; - max-width: 100%; - } - - .row-cols-xs-2 > * { - flex: 0 0 50%; - max-width: 50%; - } - - .row-cols-xs-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .row-cols-xs-4 > * { - flex: 0 0 25%; - max-width: 25%; - } - - .row-cols-xs-5 > * { - flex: 0 0 20%; - max-width: 20%; - } - - .row-cols-xs-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-xs-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; - } - - .col-xs-1 { - flex: 0 0 8.3333333333%; - max-width: 8.3333333333%; - } - - .col-xs-2 { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-xs-3 { - flex: 0 0 25%; - max-width: 25%; - } - - .col-xs-4 { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .col-xs-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; - } - - .col-xs-6 { - flex: 0 0 50%; - max-width: 50%; - } - - .col-xs-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; - } - - .col-xs-8 { - flex: 0 0 66.6666666667%; - max-width: 66.6666666667%; - } - - .col-xs-9 { - flex: 0 0 75%; - max-width: 75%; - } - - .col-xs-10 { - flex: 0 0 83.3333333333%; - max-width: 83.3333333333%; - } - - .col-xs-11 { - flex: 0 0 91.6666666667%; - max-width: 91.6666666667%; - } - - .col-xs-12 { - flex: 0 0 100%; - max-width: 100%; - } - - .order-xs-first { - order: -1; - } - - .order-xs-last { - order: 13; - } - - .order-xs-0 { - order: 0; - } - - .order-xs-1 { - order: 1; - } - - .order-xs-2 { - order: 2; - } - - .order-xs-3 { - order: 3; - } - - .order-xs-4 { - order: 4; - } - - .order-xs-5 { - order: 5; - } - - .order-xs-6 { - order: 6; - } - - .order-xs-7 { - order: 7; - } - - .order-xs-8 { - order: 8; - } - - .order-xs-9 { - order: 9; - } - - .order-xs-10 { - order: 10; - } - - .order-xs-11 { - order: 11; - } - - .order-xs-12 { - order: 12; - } - - .offset-xs-0 { - margin-left: 0; - } - - .offset-xs-1 { - margin-left: 8.3333333333%; - } - - .offset-xs-2 { - margin-left: 16.6666666667%; - } - - .offset-xs-3 { - margin-left: 25%; - } - - .offset-xs-4 { - margin-left: 33.3333333333%; - } - - .offset-xs-5 { - margin-left: 41.6666666667%; - } - - .offset-xs-6 { - margin-left: 50%; - } - - .offset-xs-7 { - margin-left: 58.3333333333%; - } - - .offset-xs-8 { - margin-left: 66.6666666667%; - } - - .offset-xs-9 { - margin-left: 75%; - } - - .offset-xs-10 { - margin-left: 83.3333333333%; - } - - .offset-xs-11 { - margin-left: 91.6666666667%; - } -} -@media (min-width: 616px) { - .col-sm { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - .row-cols-sm-1 > * { - flex: 0 0 100%; - max-width: 100%; - } - - .row-cols-sm-2 > * { - flex: 0 0 50%; - max-width: 50%; - } - - .row-cols-sm-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .row-cols-sm-4 > * { - flex: 0 0 25%; - max-width: 25%; - } - - .row-cols-sm-5 > * { - flex: 0 0 20%; - max-width: 20%; - } - - .row-cols-sm-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-sm-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; - } - - .col-sm-1 { - flex: 0 0 8.3333333333%; - max-width: 8.3333333333%; - } - - .col-sm-2 { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-sm-3 { - flex: 0 0 25%; - max-width: 25%; - } - - .col-sm-4 { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .col-sm-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; - } - - .col-sm-6 { - flex: 0 0 50%; - max-width: 50%; - } - - .col-sm-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; - } - - .col-sm-8 { - flex: 0 0 66.6666666667%; - max-width: 66.6666666667%; - } - - .col-sm-9 { - flex: 0 0 75%; - max-width: 75%; - } - - .col-sm-10 { - flex: 0 0 83.3333333333%; - max-width: 83.3333333333%; - } - - .col-sm-11 { - flex: 0 0 91.6666666667%; - max-width: 91.6666666667%; - } - - .col-sm-12 { - flex: 0 0 100%; - max-width: 100%; - } - - .order-sm-first { - order: -1; - } - - .order-sm-last { - order: 13; - } - - .order-sm-0 { - order: 0; - } - - .order-sm-1 { - order: 1; - } - - .order-sm-2 { - order: 2; - } - - .order-sm-3 { - order: 3; - } - - .order-sm-4 { - order: 4; - } - - .order-sm-5 { - order: 5; - } - - .order-sm-6 { - order: 6; - } - - .order-sm-7 { - order: 7; - } - - .order-sm-8 { - order: 8; - } - - .order-sm-9 { - order: 9; - } - - .order-sm-10 { - order: 10; - } - - .order-sm-11 { - order: 11; - } - - .order-sm-12 { - order: 12; - } - - .offset-sm-0 { - margin-left: 0; - } - - .offset-sm-1 { - margin-left: 8.3333333333%; - } - - .offset-sm-2 { - margin-left: 16.6666666667%; - } - - .offset-sm-3 { - margin-left: 25%; - } - - .offset-sm-4 { - margin-left: 33.3333333333%; - } - - .offset-sm-5 { - margin-left: 41.6666666667%; - } - - .offset-sm-6 { - margin-left: 50%; - } - - .offset-sm-7 { - margin-left: 58.3333333333%; - } - - .offset-sm-8 { - margin-left: 66.6666666667%; - } - - .offset-sm-9 { - margin-left: 75%; - } - - .offset-sm-10 { - margin-left: 83.3333333333%; - } - - .offset-sm-11 { - margin-left: 91.6666666667%; - } -} -@media (min-width: 768px) { - .col-md { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - .row-cols-md-1 > * { - flex: 0 0 100%; - max-width: 100%; - } - - .row-cols-md-2 > * { - flex: 0 0 50%; - max-width: 50%; - } - - .row-cols-md-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .row-cols-md-4 > * { - flex: 0 0 25%; - max-width: 25%; - } - - .row-cols-md-5 > * { - flex: 0 0 20%; - max-width: 20%; - } - - .row-cols-md-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-md-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; - } - - .col-md-1 { - flex: 0 0 8.3333333333%; - max-width: 8.3333333333%; - } - - .col-md-2 { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-md-3 { - flex: 0 0 25%; - max-width: 25%; - } - - .col-md-4 { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .col-md-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; - } - - .col-md-6 { - flex: 0 0 50%; - max-width: 50%; - } - - .col-md-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; - } - - .col-md-8 { - flex: 0 0 66.6666666667%; - max-width: 66.6666666667%; - } - - .col-md-9 { - flex: 0 0 75%; - max-width: 75%; - } - - .col-md-10 { - flex: 0 0 83.3333333333%; - max-width: 83.3333333333%; - } - - .col-md-11 { - flex: 0 0 91.6666666667%; - max-width: 91.6666666667%; - } - - .col-md-12 { - flex: 0 0 100%; - max-width: 100%; - } - - .order-md-first { - order: -1; - } - - .order-md-last { - order: 13; - } - - .order-md-0 { - order: 0; - } - - .order-md-1 { - order: 1; - } - - .order-md-2 { - order: 2; - } - - .order-md-3 { - order: 3; - } - - .order-md-4 { - order: 4; - } - - .order-md-5 { - order: 5; - } - - .order-md-6 { - order: 6; - } - - .order-md-7 { - order: 7; - } - - .order-md-8 { - order: 8; - } - - .order-md-9 { - order: 9; - } - - .order-md-10 { - order: 10; - } - - .order-md-11 { - order: 11; - } - - .order-md-12 { - order: 12; - } - - .offset-md-0 { - margin-left: 0; - } - - .offset-md-1 { - margin-left: 8.3333333333%; - } - - .offset-md-2 { - margin-left: 16.6666666667%; - } - - .offset-md-3 { - margin-left: 25%; - } - - .offset-md-4 { - margin-left: 33.3333333333%; - } - - .offset-md-5 { - margin-left: 41.6666666667%; - } - - .offset-md-6 { - margin-left: 50%; - } - - .offset-md-7 { - margin-left: 58.3333333333%; - } - - .offset-md-8 { - margin-left: 66.6666666667%; - } - - .offset-md-9 { - margin-left: 75%; - } - - .offset-md-10 { - margin-left: 83.3333333333%; - } - - .offset-md-11 { - margin-left: 91.6666666667%; - } -} -@media (min-width: 980px) { - .col-lg { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - .row-cols-lg-1 > * { - flex: 0 0 100%; - max-width: 100%; - } - - .row-cols-lg-2 > * { - flex: 0 0 50%; - max-width: 50%; - } - - .row-cols-lg-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .row-cols-lg-4 > * { - flex: 0 0 25%; - max-width: 25%; - } - - .row-cols-lg-5 > * { - flex: 0 0 20%; - max-width: 20%; - } - - .row-cols-lg-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-lg-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; - } - - .col-lg-1 { - flex: 0 0 8.3333333333%; - max-width: 8.3333333333%; - } - - .col-lg-2 { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-lg-3 { - flex: 0 0 25%; - max-width: 25%; - } - - .col-lg-4 { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .col-lg-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; - } - - .col-lg-6 { - flex: 0 0 50%; - max-width: 50%; - } - - .col-lg-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; - } - - .col-lg-8 { - flex: 0 0 66.6666666667%; - max-width: 66.6666666667%; - } - - .col-lg-9 { - flex: 0 0 75%; - max-width: 75%; - } - - .col-lg-10 { - flex: 0 0 83.3333333333%; - max-width: 83.3333333333%; - } - - .col-lg-11 { - flex: 0 0 91.6666666667%; - max-width: 91.6666666667%; - } - - .col-lg-12 { - flex: 0 0 100%; - max-width: 100%; - } - - .order-lg-first { - order: -1; - } - - .order-lg-last { - order: 13; - } - - .order-lg-0 { - order: 0; - } - - .order-lg-1 { - order: 1; - } - - .order-lg-2 { - order: 2; - } - - .order-lg-3 { - order: 3; - } - - .order-lg-4 { - order: 4; - } - - .order-lg-5 { - order: 5; - } - - .order-lg-6 { - order: 6; - } - - .order-lg-7 { - order: 7; - } - - .order-lg-8 { - order: 8; - } - - .order-lg-9 { - order: 9; - } - - .order-lg-10 { - order: 10; - } - - .order-lg-11 { - order: 11; - } - - .order-lg-12 { - order: 12; - } - - .offset-lg-0 { - margin-left: 0; - } - - .offset-lg-1 { - margin-left: 8.3333333333%; - } - - .offset-lg-2 { - margin-left: 16.6666666667%; - } - - .offset-lg-3 { - margin-left: 25%; - } - - .offset-lg-4 { - margin-left: 33.3333333333%; - } - - .offset-lg-5 { - margin-left: 41.6666666667%; - } - - .offset-lg-6 { - margin-left: 50%; - } - - .offset-lg-7 { - margin-left: 58.3333333333%; - } - - .offset-lg-8 { - margin-left: 66.6666666667%; - } - - .offset-lg-9 { - margin-left: 75%; - } - - .offset-lg-10 { - margin-left: 83.3333333333%; - } - - .offset-lg-11 { - margin-left: 91.6666666667%; - } -} -@media (min-width: 1240px) { - .col-xl { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } - - .row-cols-xl-1 > * { - flex: 0 0 100%; - max-width: 100%; - } - - .row-cols-xl-2 > * { - flex: 0 0 50%; - max-width: 50%; - } - - .row-cols-xl-3 > * { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .row-cols-xl-4 > * { - flex: 0 0 25%; - max-width: 25%; - } - - .row-cols-xl-5 > * { - flex: 0 0 20%; - max-width: 20%; - } - - .row-cols-xl-6 > * { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-xl-auto { - flex: 0 0 auto; - width: auto; - max-width: 100%; - } - - .col-xl-1 { - flex: 0 0 8.3333333333%; - max-width: 8.3333333333%; - } - - .col-xl-2 { - flex: 0 0 16.6666666667%; - max-width: 16.6666666667%; - } - - .col-xl-3 { - flex: 0 0 25%; - max-width: 25%; - } - - .col-xl-4 { - flex: 0 0 33.3333333333%; - max-width: 33.3333333333%; - } - - .col-xl-5 { - flex: 0 0 41.6666666667%; - max-width: 41.6666666667%; - } - - .col-xl-6 { - flex: 0 0 50%; - max-width: 50%; - } - - .col-xl-7 { - flex: 0 0 58.3333333333%; - max-width: 58.3333333333%; - } - - .col-xl-8 { - flex: 0 0 66.6666666667%; - max-width: 66.6666666667%; - } - - .col-xl-9 { - flex: 0 0 75%; - max-width: 75%; - } - - .col-xl-10 { - flex: 0 0 83.3333333333%; - max-width: 83.3333333333%; - } - - .col-xl-11 { - flex: 0 0 91.6666666667%; - max-width: 91.6666666667%; - } - - .col-xl-12 { - flex: 0 0 100%; - max-width: 100%; - } - - .order-xl-first { - order: -1; - } - - .order-xl-last { - order: 13; - } - - .order-xl-0 { - order: 0; - } - - .order-xl-1 { - order: 1; - } - - .order-xl-2 { - order: 2; - } - - .order-xl-3 { - order: 3; - } - - .order-xl-4 { - order: 4; - } - - .order-xl-5 { - order: 5; - } - - .order-xl-6 { - order: 6; - } - - .order-xl-7 { - order: 7; - } - - .order-xl-8 { - order: 8; - } - - .order-xl-9 { - order: 9; - } - - .order-xl-10 { - order: 10; - } - - .order-xl-11 { - order: 11; - } - - .order-xl-12 { - order: 12; - } - - .offset-xl-0 { - margin-left: 0; - } - - .offset-xl-1 { - margin-left: 8.3333333333%; - } - - .offset-xl-2 { - margin-left: 16.6666666667%; - } - - .offset-xl-3 { - margin-left: 25%; - } - - .offset-xl-4 { - margin-left: 33.3333333333%; - } - - .offset-xl-5 { - margin-left: 41.6666666667%; - } - - .offset-xl-6 { - margin-left: 50%; - } - - .offset-xl-7 { - margin-left: 58.3333333333%; - } - - .offset-xl-8 { - margin-left: 66.6666666667%; - } - - .offset-xl-9 { - margin-left: 75%; - } - - .offset-xl-10 { - margin-left: 83.3333333333%; - } - - .offset-xl-11 { - margin-left: 91.6666666667%; - } -} -.table { - width: 100%; - margin-bottom: 8px; - color: #212529; -} -.table th, -.table td { - padding: 0.75rem; - vertical-align: top; - border-top: 1px solid #d6dbdf; -} -.table thead th { - vertical-align: bottom; - border-bottom: 2px solid #d6dbdf; -} -.table tbody + tbody { - border-top: 2px solid #d6dbdf; -} - -.table-sm th, -.table-sm td { - padding: 0.3rem; -} - -.table-bordered { - border: 1px solid #d6dbdf; -} -.table-bordered th, -.table-bordered td { - border: 1px solid #d6dbdf; -} -.table-bordered thead th, -.table-bordered thead td { - border-bottom-width: 2px; -} - -.table-borderless th, -.table-borderless td, -.table-borderless thead th, -.table-borderless tbody + tbody { - border: 0; -} - -.table-striped tbody tr:nth-of-type(odd) { - background-color: rgba(33, 37, 41, 0.05); -} - -.table-hover tbody tr:hover { - color: #212529; - background-color: rgba(33, 37, 41, 0.075); -} - -.table-primary, -.table-primary > th, -.table-primary > td { - background-color: #fff1b8; -} -.table-primary th, -.table-primary td, -.table-primary thead th, -.table-primary tbody + tbody { - border-color: #ffe47a; -} - -.table-hover .table-primary:hover { - background-color: #ffec9f; -} -.table-hover .table-primary:hover > td, -.table-hover .table-primary:hover > th { - background-color: #ffec9f; -} - -.table-secondary, -.table-secondary > th, -.table-secondary > td { - background-color: #c1c2c3; -} -.table-secondary th, -.table-secondary td, -.table-secondary thead th, -.table-secondary tbody + tbody { - border-color: #8c8e90; -} - -.table-hover .table-secondary:hover { - background-color: #b4b5b6; -} -.table-hover .table-secondary:hover > td, -.table-hover .table-secondary:hover > th { - background-color: #b4b5b6; -} - -.table-success, -.table-success > th, -.table-success > td { - background-color: #c3e6cb; -} -.table-success th, -.table-success td, -.table-success thead th, -.table-success tbody + tbody { - border-color: #8fd19e; -} - -.table-hover .table-success:hover { - background-color: #b1dfbb; -} -.table-hover .table-success:hover > td, -.table-hover .table-success:hover > th { - background-color: #b1dfbb; -} - -.table-info, -.table-info > th, -.table-info > td { - background-color: #bee5eb; -} -.table-info th, -.table-info td, -.table-info thead th, -.table-info tbody + tbody { - border-color: #86cfda; -} - -.table-hover .table-info:hover { - background-color: #abdde5; -} -.table-hover .table-info:hover > td, -.table-hover .table-info:hover > th { - background-color: #abdde5; -} - -.table-warning, -.table-warning > th, -.table-warning > td { - background-color: #ffeeba; -} -.table-warning th, -.table-warning td, -.table-warning thead th, -.table-warning tbody + tbody { - border-color: #ffdf7e; -} - -.table-hover .table-warning:hover { - background-color: #ffe8a1; -} -.table-hover .table-warning:hover > td, -.table-hover .table-warning:hover > th { - background-color: #ffe8a1; -} - -.table-danger, -.table-danger > th, -.table-danger > td { - background-color: #f5c6cb; -} -.table-danger th, -.table-danger td, -.table-danger thead th, -.table-danger tbody + tbody { - border-color: #ed969e; -} - -.table-hover .table-danger:hover { - background-color: #f1b0b7; -} -.table-hover .table-danger:hover > td, -.table-hover .table-danger:hover > th { - background-color: #f1b0b7; -} - -.table-light, -.table-light > th, -.table-light > td { - background-color: #fbfcfd; -} -.table-light th, -.table-light td, -.table-light thead th, -.table-light tbody + tbody { - border-color: #f8fafc; -} - -.table-hover .table-light:hover { - background-color: #eaeff5; -} -.table-hover .table-light:hover > td, -.table-hover .table-light:hover > th { - background-color: #eaeff5; -} - -.table-dark, -.table-dark > th, -.table-dark > td { - background-color: #ccced0; -} -.table-dark th, -.table-dark td, -.table-dark thead th, -.table-dark tbody + tbody { - border-color: #a0a4a8; -} - -.table-hover .table-dark:hover { - background-color: #bfc1c4; -} -.table-hover .table-dark:hover > td, -.table-hover .table-dark:hover > th { - background-color: #bfc1c4; -} - -.table-primary-light, -.table-primary-light > th, -.table-primary-light > td { - background-color: #fffefb; -} -.table-primary-light th, -.table-primary-light td, -.table-primary-light thead th, -.table-primary-light tbody + tbody { - border-color: #fffcf7; -} - -.table-hover .table-primary-light:hover { - background-color: #fff8e2; -} -.table-hover .table-primary-light:hover > td, -.table-hover .table-primary-light:hover > th { - background-color: #fff8e2; -} - -.table-secondary-light, -.table-secondary-light > th, -.table-secondary-light > td { - background-color: white; -} -.table-secondary-light th, -.table-secondary-light td, -.table-secondary-light thead th, -.table-secondary-light tbody + tbody { - border-color: white; -} - -.table-hover .table-secondary-light:hover { - background-color: #f2f2f2; -} -.table-hover .table-secondary-light:hover > td, -.table-hover .table-secondary-light:hover > th { - background-color: #f2f2f2; -} - -.table-tertiary, -.table-tertiary > th, -.table-tertiary > td { - background-color: #c2dafc; -} -.table-tertiary th, -.table-tertiary td, -.table-tertiary thead th, -.table-tertiary tbody + tbody { - border-color: #8ebaf9; -} - -.table-hover .table-tertiary:hover { - background-color: #aacbfb; -} -.table-hover .table-tertiary:hover > td, -.table-hover .table-tertiary:hover > th { - background-color: #aacbfb; -} - -.table-tertiary-light, -.table-tertiary-light > th, -.table-tertiary-light > td { - background-color: #f7fbff; -} -.table-tertiary-light th, -.table-tertiary-light td, -.table-tertiary-light thead th, -.table-tertiary-light tbody + tbody { - border-color: #f0f8fe; -} - -.table-hover .table-tertiary-light:hover { - background-color: #deeeff; -} -.table-hover .table-tertiary-light:hover > td, -.table-hover .table-tertiary-light:hover > th { - background-color: #deeeff; -} - -.table-white, -.table-white > th, -.table-white > td { - background-color: white; -} -.table-white th, -.table-white td, -.table-white thead th, -.table-white tbody + tbody { - border-color: white; -} - -.table-hover .table-white:hover { - background-color: #f2f2f2; -} -.table-hover .table-white:hover > td, -.table-hover .table-white:hover > th { - background-color: #f2f2f2; -} - -.table-black, -.table-black > th, -.table-black > td { - background-color: #c1c2c3; -} -.table-black th, -.table-black td, -.table-black thead th, -.table-black tbody + tbody { - border-color: #8c8e90; -} - -.table-hover .table-black:hover { - background-color: #b4b5b6; -} -.table-hover .table-black:hover > td, -.table-hover .table-black:hover > th { - background-color: #b4b5b6; -} - -.table-blue, -.table-blue > th, -.table-blue > td { - background-color: #c2dafc; -} -.table-blue th, -.table-blue td, -.table-blue thead th, -.table-blue tbody + tbody { - border-color: #8ebaf9; -} - -.table-hover .table-blue:hover { - background-color: #aacbfb; -} -.table-hover .table-blue:hover > td, -.table-hover .table-blue:hover > th { - background-color: #aacbfb; -} - -.table-light-blue, -.table-light-blue > th, -.table-light-blue > td { - background-color: #f7fbff; -} -.table-light-blue th, -.table-light-blue td, -.table-light-blue thead th, -.table-light-blue tbody + tbody { - border-color: #f0f8fe; -} - -.table-hover .table-light-blue:hover { - background-color: #deeeff; -} -.table-hover .table-light-blue:hover > td, -.table-hover .table-light-blue:hover > th { - background-color: #deeeff; -} - -.table-yellow, -.table-yellow > th, -.table-yellow > td { - background-color: #fff1b8; -} -.table-yellow th, -.table-yellow td, -.table-yellow thead th, -.table-yellow tbody + tbody { - border-color: #ffe47a; -} - -.table-hover .table-yellow:hover { - background-color: #ffec9f; -} -.table-hover .table-yellow:hover > td, -.table-hover .table-yellow:hover > th { - background-color: #ffec9f; -} - -.table-light-yellow, -.table-light-yellow > th, -.table-light-yellow > td { - background-color: #fffefb; -} -.table-light-yellow th, -.table-light-yellow td, -.table-light-yellow thead th, -.table-light-yellow tbody + tbody { - border-color: #fffcf7; -} - -.table-hover .table-light-yellow:hover { - background-color: #fff8e2; -} -.table-hover .table-light-yellow:hover > td, -.table-hover .table-light-yellow:hover > th { - background-color: #fff8e2; -} - -.table-orange, -.table-orange > th, -.table-orange > td { - background-color: #ffdfb8; -} -.table-orange th, -.table-orange td, -.table-orange thead th, -.table-orange tbody + tbody { - border-color: #ffc37a; -} - -.table-hover .table-orange:hover { - background-color: #ffd49f; -} -.table-hover .table-orange:hover > td, -.table-hover .table-orange:hover > th { - background-color: #ffd49f; -} - -.table-light-orange, -.table-light-orange > th, -.table-light-orange > td { - background-color: #fff7ea; -} -.table-light-orange th, -.table-light-orange td, -.table-light-orange thead th, -.table-light-orange tbody + tbody { - border-color: #fff1d9; -} - -.table-hover .table-light-orange:hover { - background-color: #ffedd1; -} -.table-hover .table-light-orange:hover > td, -.table-hover .table-light-orange:hover > th { - background-color: #ffedd1; -} - -.table-red, -.table-red > th, -.table-red > td { - background-color: #ffc8c8; -} -.table-red th, -.table-red td, -.table-red thead th, -.table-red tbody + tbody { - border-color: #ff9898; -} - -.table-hover .table-red:hover { - background-color: #ffafaf; -} -.table-hover .table-red:hover > td, -.table-hover .table-red:hover > th { - background-color: #ffafaf; -} - -.table-light-red, -.table-light-red > th, -.table-light-red > td { - background-color: #fff7f7; -} -.table-light-red th, -.table-light-red td, -.table-light-red thead th, -.table-light-red tbody + tbody { - border-color: #fff1ef; -} - -.table-hover .table-light-red:hover { - background-color: #ffdede; -} -.table-hover .table-light-red:hover > td, -.table-hover .table-light-red:hover > th { - background-color: #ffdede; -} - -.table-medium, -.table-medium > th, -.table-medium > td { - background-color: #f4f5f6; -} -.table-medium th, -.table-medium td, -.table-medium thead th, -.table-medium tbody + tbody { - border-color: #eaecee; -} - -.table-hover .table-medium:hover { - background-color: #e6e8eb; -} -.table-hover .table-medium:hover > td, -.table-hover .table-medium:hover > th { - background-color: #e6e8eb; -} - -.table-active, -.table-active > th, -.table-active > td { - background-color: rgba(33, 37, 41, 0.075); -} - -.table-hover .table-active:hover { - background-color: rgba(22, 24, 27, 0.075); -} -.table-hover .table-active:hover > td, -.table-hover .table-active:hover > th { - background-color: rgba(22, 24, 27, 0.075); -} - -.table .thead-dark th { - color: #fff; - background-color: #343a40; - border-color: #454d55; -} -.table .thead-light th { - color: #6c757d; - background-color: #e9ecef; - border-color: #d6dbdf; -} - -.table-dark { - color: #fff; - background-color: #343a40; -} -.table-dark th, -.table-dark td, -.table-dark thead th { - border-color: #454d55; -} -.table-dark.table-bordered { - border: 0; -} -.table-dark.table-striped tbody tr:nth-of-type(odd) { - background-color: rgba(255, 255, 255, 0.05); -} -.table-dark.table-hover tbody tr:hover { - color: #fff; - background-color: rgba(255, 255, 255, 0.075); -} - -@media (max-width: 399.98px) { - .table-responsive-xs { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .table-responsive-xs > .table-bordered { - border: 0; - } -} -@media (max-width: 615.98px) { - .table-responsive-sm { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .table-responsive-sm > .table-bordered { - border: 0; - } -} -@media (max-width: 767.98px) { - .table-responsive-md { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .table-responsive-md > .table-bordered { - border: 0; - } -} -@media (max-width: 979.98px) { - .table-responsive-lg { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .table-responsive-lg > .table-bordered { - border: 0; - } -} -@media (max-width: 1239.98px) { - .table-responsive-xl { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; - } - .table-responsive-xl > .table-bordered { - border: 0; - } -} -.table-responsive { - display: block; - width: 100%; - overflow-x: auto; - -webkit-overflow-scrolling: touch; -} -.table-responsive > .table-bordered { - border: 0; -} - -.form-control { - display: block; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - padding: 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #6c757d; - background-color: #fff; - background-clip: padding-box; - border: 1px solid #ced4da; - border-radius: 8px; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .form-control { - transition: none; - } -} -.form-control::-ms-expand { - background-color: transparent; - border: 0; -} -.form-control:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #6c757d; -} -.form-control:focus { - color: #6c757d; - background-color: #fff; - border-color: #ffe680; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.form-control::-moz-placeholder { - color: #6c757d; - opacity: 1; -} -.form-control:-ms-input-placeholder { - color: #6c757d; - opacity: 1; -} -.form-control::placeholder { - color: #6c757d; - opacity: 1; -} -.form-control:disabled, .form-control[readonly] { - background-color: #e9ecef; - opacity: 1; -} - -select.form-control:focus::-ms-value { - color: #6c757d; - background-color: #fff; -} - -.form-control-file, -.form-control-range { - display: block; - width: 100%; -} - -.col-form-label { - padding-top: calc(0.375rem + 1px); - padding-bottom: calc(0.375rem + 1px); - margin-bottom: 0; - font-size: inherit; - line-height: 1.5; -} - -.col-form-label-lg { - padding-top: calc(0.5rem + 1px); - padding-bottom: calc(0.5rem + 1px); - font-size: 1.125rem; - line-height: 1.5; -} - -.col-form-label-sm { - padding-top: calc(0.25rem + 1px); - padding-bottom: calc(0.25rem + 1px); - font-size: 0.875rem; - line-height: 1.5; -} - -.form-control-plaintext { - display: block; - width: 100%; - padding: 0.375rem 0; - margin-bottom: 0; - font-size: 1rem; - line-height: 1.5; - color: #212529; - background-color: transparent; - border: solid transparent; - border-width: 1px 0; -} -.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg { - padding-right: 0; - padding-left: 0; -} - -.form-control-sm { - height: calc(1.5em + 0.5rem + 2px); - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; - border-radius: 8px; -} - -.form-control-lg { - height: calc(1.5em + 1rem + 2px); - padding: 0.5rem 1rem; - font-size: 1.125rem; - line-height: 1.5; - border-radius: 8px; -} - -select.form-control[size], select.form-control[multiple] { - height: auto; -} - -textarea.form-control { - height: auto; -} - -.form-group { - margin-bottom: 1rem; -} - -.form-text { - display: block; - margin-top: 0.25rem; -} - -.form-row { - display: flex; - flex-wrap: wrap; - margin-right: -5px; - margin-left: -5px; -} -.form-row > .col, -.form-row > [class*=col-] { - padding-right: 5px; - padding-left: 5px; -} - -.form-check { - position: relative; - display: block; - padding-left: 1.25rem; -} - -.form-check-input { - position: absolute; - margin-top: 0.3rem; - margin-left: -1.25rem; -} -.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label { - color: #6c757d; -} - -.form-check-label { - margin-bottom: 0; -} - -.form-check-inline { - display: inline-flex; - align-items: center; - padding-left: 0; - margin-right: 0.75rem; -} -.form-check-inline .form-check-input { - position: static; - margin-top: 0; - margin-right: 0.3125rem; - margin-left: 0; -} - -.valid-feedback { - display: none; - width: 100%; - margin-top: 0.25rem; - font-size: 80%; - color: #28a745; -} - -.valid-tooltip { - position: absolute; - top: 100%; - z-index: 5; - display: none; - max-width: 100%; - padding: 0.25rem 0.5rem; - margin-top: 0.1rem; - font-size: 0.875rem; - line-height: 1.5; - color: #fff; - background-color: rgba(40, 167, 69, 0.9); - border-radius: 8px; -} - -.was-validated :valid ~ .valid-feedback, -.was-validated :valid ~ .valid-tooltip, -.is-valid ~ .valid-feedback, -.is-valid ~ .valid-tooltip { - display: block; -} - -.was-validated .form-control:valid, .form-control.is-valid { - border-color: #28a745; - padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .form-control:valid:focus, .form-control.is-valid:focus { - border-color: #28a745; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); -} - -.was-validated textarea.form-control:valid, textarea.form-control.is-valid { - padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); -} - -.was-validated .custom-select:valid, .custom-select.is-valid { - border-color: #28a745; - padding-right: calc(0.75em + 2.3125rem); - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .custom-select:valid:focus, .custom-select.is-valid:focus { - border-color: #28a745; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); -} - -.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { - color: #28a745; -} -.was-validated .form-check-input:valid ~ .valid-feedback, -.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback, -.form-check-input.is-valid ~ .valid-tooltip { - display: block; -} - -.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label { - color: #28a745; -} -.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before { - border-color: #28a745; -} -.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { - border-color: #34ce57; - background-color: #34ce57; -} -.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); -} -.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before { - border-color: #28a745; -} - -.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label { - border-color: #28a745; -} -.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { - border-color: #28a745; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); -} - -.invalid-feedback { - display: none; - width: 100%; - margin-top: 0.25rem; - font-size: 80%; - color: #dc3545; -} - -.invalid-tooltip { - position: absolute; - top: 100%; - z-index: 5; - display: none; - max-width: 100%; - padding: 0.25rem 0.5rem; - margin-top: 0.1rem; - font-size: 0.875rem; - line-height: 1.5; - color: #fff; - background-color: rgba(220, 53, 69, 0.9); - border-radius: 8px; -} - -.was-validated :invalid ~ .invalid-feedback, -.was-validated :invalid ~ .invalid-tooltip, -.is-invalid ~ .invalid-feedback, -.is-invalid ~ .invalid-tooltip { - display: block; -} - -.was-validated .form-control:invalid, .form-control.is-invalid { - border-color: #dc3545; - padding-right: calc(1.5em + 0.75rem); - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); - background-repeat: no-repeat; - background-position: right calc(0.375em + 0.1875rem) center; - background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus { - border-color: #dc3545; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); -} - -.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid { - padding-right: calc(1.5em + 0.75rem); - background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); -} - -.was-validated .custom-select:invalid, .custom-select.is-invalid { - border-color: #dc3545; - padding-right: calc(0.75em + 2.3125rem); - background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px, url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); -} -.was-validated .custom-select:invalid:focus, .custom-select.is-invalid:focus { - border-color: #dc3545; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); -} - -.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { - color: #dc3545; -} -.was-validated .form-check-input:invalid ~ .invalid-feedback, -.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback, -.form-check-input.is-invalid ~ .invalid-tooltip { - display: block; -} - -.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label { - color: #dc3545; -} -.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before { - border-color: #dc3545; -} -.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { - border-color: #e4606d; - background-color: #e4606d; -} -.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); -} -.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before, .custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before { - border-color: #dc3545; -} - -.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label { - border-color: #dc3545; -} -.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { - border-color: #dc3545; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); -} - -.form-inline { - display: flex; - flex-flow: row wrap; - align-items: center; -} -.form-inline .form-check { - width: 100%; -} -@media (min-width: 616px) { - .form-inline label { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 0; - } - .form-inline .form-group { - display: flex; - flex: 0 0 auto; - flex-flow: row wrap; - align-items: center; - margin-bottom: 0; - } - .form-inline .form-control { - display: inline-block; - width: auto; - vertical-align: middle; - } - .form-inline .form-control-plaintext { - display: inline-block; - } - .form-inline .input-group, -.form-inline .custom-select { - width: auto; - } - .form-inline .form-check { - display: flex; - align-items: center; - justify-content: center; - width: auto; - padding-left: 0; - } - .form-inline .form-check-input { - position: relative; - flex-shrink: 0; - margin-top: 0; - margin-right: 0.25rem; - margin-left: 0; - } - .form-inline .custom-control { - align-items: center; - justify-content: center; - } - .form-inline .custom-control-label { - margin-bottom: 0; - } -} - -.btn { - display: inline-block; - font-family: inherit; - font-weight: 700; - color: #212529; - text-align: center; - vertical-align: middle; - cursor: pointer; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - background-color: transparent; - border: 1px solid transparent; - padding: 12px 32px; - font-size: 0.875rem; - line-height: 20px; - border-radius: 8px; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .btn { - transition: none; - } -} -.btn:hover { - color: #212529; - text-decoration: none; -} -.btn:focus, .btn.focus { - outline: 0; - box-shadow: none; -} -.btn.disabled, .btn:disabled { - opacity: 0.65; -} -a.btn.disabled, -fieldset:disabled a.btn { - pointer-events: none; -} - -.btn-primary { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-primary:hover { - color: #495057; - background-color: #d9ad00; - border-color: #cca300; -} -.btn-primary:focus, .btn-primary.focus { - color: #495057; - background-color: #d9ad00; - border-color: #cca300; - box-shadow: 0 0 0 0 rgba(228, 185, 13, 0.5); -} -.btn-primary.disabled, .btn-primary:disabled { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, .show > .btn-primary.dropdown-toggle { - color: #495057; - background-color: #cca300; - border-color: #bf9900; -} -.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 185, 13, 0.5); -} - -.btn-secondary { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-secondary:hover { - color: #fff; - background-color: #101214; - border-color: #0a0c0d; -} -.btn-secondary:focus, .btn-secondary.focus { - color: #fff; - background-color: #101214; - border-color: #0a0c0d; - box-shadow: 0 0 0 0 rgba(66, 70, 73, 0.5); -} -.btn-secondary.disabled, .btn-secondary:disabled { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, .show > .btn-secondary.dropdown-toggle { - color: #fff; - background-color: #0a0c0d; - border-color: #050506; -} -.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(66, 70, 73, 0.5); -} - -.btn-success { - color: #fff; - background-color: #28a745; - border-color: #28a745; -} -.btn-success:hover { - color: #fff; - background-color: #218838; - border-color: #1e7e34; -} -.btn-success:focus, .btn-success.focus { - color: #fff; - background-color: #218838; - border-color: #1e7e34; - box-shadow: 0 0 0 0 rgba(72, 180, 97, 0.5); -} -.btn-success.disabled, .btn-success:disabled { - color: #fff; - background-color: #28a745; - border-color: #28a745; -} -.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active, .show > .btn-success.dropdown-toggle { - color: #fff; - background-color: #1e7e34; - border-color: #1c7430; -} -.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus, .show > .btn-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(72, 180, 97, 0.5); -} - -.btn-info { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; -} -.btn-info:hover { - color: #fff; - background-color: #138496; - border-color: #117a8b; -} -.btn-info:focus, .btn-info.focus { - color: #fff; - background-color: #138496; - border-color: #117a8b; - box-shadow: 0 0 0 0 rgba(58, 176, 195, 0.5); -} -.btn-info.disabled, .btn-info:disabled { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; -} -.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active, .show > .btn-info.dropdown-toggle { - color: #fff; - background-color: #117a8b; - border-color: #10707f; -} -.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus, .show > .btn-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(58, 176, 195, 0.5); -} - -.btn-warning { - color: #495057; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-warning:hover { - color: #495057; - background-color: #e0a800; - border-color: #d39e00; -} -.btn-warning:focus, .btn-warning.focus { - color: #495057; - background-color: #e0a800; - border-color: #d39e00; - box-shadow: 0 0 0 0 rgba(228, 176, 19, 0.5); -} -.btn-warning.disabled, .btn-warning:disabled { - color: #495057; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, .show > .btn-warning.dropdown-toggle { - color: #495057; - background-color: #d39e00; - border-color: #c69500; -} -.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 176, 19, 0.5); -} - -.btn-danger { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-danger:hover { - color: #fff; - background-color: #c82333; - border-color: #bd2130; -} -.btn-danger:focus, .btn-danger.focus { - color: #fff; - background-color: #c82333; - border-color: #bd2130; - box-shadow: 0 0 0 0 rgba(225, 83, 97, 0.5); -} -.btn-danger.disabled, .btn-danger:disabled { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active, .show > .btn-danger.dropdown-toggle { - color: #fff; - background-color: #bd2130; - border-color: #b21f2d; -} -.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus, .show > .btn-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(225, 83, 97, 0.5); -} - -.btn-light { - color: #495057; - background-color: #f1f6f9; - border-color: #f1f6f9; -} -.btn-light:hover { - color: #495057; - background-color: #d6e5ee; - border-color: #cddfea; -} -.btn-light:focus, .btn-light.focus { - color: #495057; - background-color: #d6e5ee; - border-color: #cddfea; - box-shadow: 0 0 0 0 rgba(216, 221, 225, 0.5); -} -.btn-light.disabled, .btn-light:disabled { - color: #495057; - background-color: #f1f6f9; - border-color: #f1f6f9; -} -.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active, .show > .btn-light.dropdown-toggle { - color: #495057; - background-color: #cddfea; - border-color: #c4d9e6; -} -.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus, .show > .btn-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(216, 221, 225, 0.5); -} - -.btn-dark { - color: #fff; - background-color: #495057; - border-color: #495057; -} -.btn-dark:hover { - color: #fff; - background-color: #383d42; - border-color: #32373b; -} -.btn-dark:focus, .btn-dark.focus { - color: #fff; - background-color: #383d42; - border-color: #32373b; - box-shadow: 0 0 0 0 rgba(100, 106, 112, 0.5); -} -.btn-dark.disabled, .btn-dark:disabled { - color: #fff; - background-color: #495057; - border-color: #495057; -} -.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active, .show > .btn-dark.dropdown-toggle { - color: #fff; - background-color: #32373b; - border-color: #2c3034; -} -.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus, .show > .btn-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(100, 106, 112, 0.5); -} - -.btn-primary-light { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-primary-light:hover { - color: #495057; - background-color: #ffedca; - border-color: #ffe9bd; -} -.btn-primary-light:focus, .btn-primary-light.focus { - color: #495057; - background-color: #ffedca; - border-color: #ffe9bd; - box-shadow: 0 0 0 0 rgba(228, 225, 217, 0.5); -} -.btn-primary-light.disabled, .btn-primary-light:disabled { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-primary-light:not(:disabled):not(.disabled):active, .btn-primary-light:not(:disabled):not(.disabled).active, .show > .btn-primary-light.dropdown-toggle { - color: #495057; - background-color: #ffe9bd; - border-color: #ffe5b0; -} -.btn-primary-light:not(:disabled):not(.disabled):active:focus, .btn-primary-light:not(:disabled):not(.disabled).active:focus, .show > .btn-primary-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 225, 217, 0.5); -} - -.btn-secondary-light { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-secondary-light:hover { - color: #495057; - background-color: #ececec; - border-color: #e6e6e6; -} -.btn-secondary-light:focus, .btn-secondary-light.focus { - color: #495057; - background-color: #ececec; - border-color: #e6e6e6; - box-shadow: 0 0 0 0 rgba(228, 229, 230, 0.5); -} -.btn-secondary-light.disabled, .btn-secondary-light:disabled { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-secondary-light:not(:disabled):not(.disabled):active, .btn-secondary-light:not(:disabled):not(.disabled).active, .show > .btn-secondary-light.dropdown-toggle { - color: #495057; - background-color: #e6e6e6; - border-color: #dfdfdf; -} -.btn-secondary-light:not(:disabled):not(.disabled):active:focus, .btn-secondary-light:not(:disabled):not(.disabled).active:focus, .show > .btn-secondary-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 229, 230, 0.5); -} - -.btn-tertiary { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-tertiary:hover { - color: #fff; - background-color: #0c66e7; - border-color: #0b60db; -} -.btn-tertiary:focus, .btn-tertiary.focus { - color: #fff; - background-color: #0c66e7; - border-color: #0b60db; - box-shadow: 0 0 0 0 rgba(70, 142, 246, 0.5); -} -.btn-tertiary.disabled, .btn-tertiary:disabled { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-tertiary:not(:disabled):not(.disabled):active, .btn-tertiary:not(:disabled):not(.disabled).active, .show > .btn-tertiary.dropdown-toggle { - color: #fff; - background-color: #0b60db; - border-color: #0a5bcf; -} -.btn-tertiary:not(:disabled):not(.disabled):active:focus, .btn-tertiary:not(:disabled):not(.disabled).active:focus, .show > .btn-tertiary.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(70, 142, 246, 0.5); -} - -.btn-tertiary-light { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-tertiary-light:hover { - color: #495057; - background-color: #bedffd; - border-color: #b2d8fc; -} -.btn-tertiary-light:focus, .btn-tertiary-light.focus { - color: #495057; - background-color: #bedffd; - border-color: #b2d8fc; - box-shadow: 0 0 0 0 rgba(204, 217, 229, 0.5); -} -.btn-tertiary-light.disabled, .btn-tertiary-light:disabled { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-tertiary-light:not(:disabled):not(.disabled):active, .btn-tertiary-light:not(:disabled):not(.disabled).active, .show > .btn-tertiary-light.dropdown-toggle { - color: #495057; - background-color: #b2d8fc; - border-color: #a5d2fc; -} -.btn-tertiary-light:not(:disabled):not(.disabled):active:focus, .btn-tertiary-light:not(:disabled):not(.disabled).active:focus, .show > .btn-tertiary-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(204, 217, 229, 0.5); -} - -.btn-white { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-white:hover { - color: #495057; - background-color: #ececec; - border-color: #e6e6e6; -} -.btn-white:focus, .btn-white.focus { - color: #495057; - background-color: #ececec; - border-color: #e6e6e6; - box-shadow: 0 0 0 0 rgba(228, 229, 230, 0.5); -} -.btn-white.disabled, .btn-white:disabled { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-white:not(:disabled):not(.disabled):active, .btn-white:not(:disabled):not(.disabled).active, .show > .btn-white.dropdown-toggle { - color: #495057; - background-color: #e6e6e6; - border-color: #dfdfdf; -} -.btn-white:not(:disabled):not(.disabled):active:focus, .btn-white:not(:disabled):not(.disabled).active:focus, .show > .btn-white.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 229, 230, 0.5); -} - -.btn-black { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-black:hover { - color: #fff; - background-color: #101214; - border-color: #0a0c0d; -} -.btn-black:focus, .btn-black.focus { - color: #fff; - background-color: #101214; - border-color: #0a0c0d; - box-shadow: 0 0 0 0 rgba(66, 70, 73, 0.5); -} -.btn-black.disabled, .btn-black:disabled { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-black:not(:disabled):not(.disabled):active, .btn-black:not(:disabled):not(.disabled).active, .show > .btn-black.dropdown-toggle { - color: #fff; - background-color: #0a0c0d; - border-color: #050506; -} -.btn-black:not(:disabled):not(.disabled):active:focus, .btn-black:not(:disabled):not(.disabled).active:focus, .show > .btn-black.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(66, 70, 73, 0.5); -} - -.btn-blue { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-blue:hover { - color: #fff; - background-color: #0c66e7; - border-color: #0b60db; -} -.btn-blue:focus, .btn-blue.focus { - color: #fff; - background-color: #0c66e7; - border-color: #0b60db; - box-shadow: 0 0 0 0 rgba(70, 142, 246, 0.5); -} -.btn-blue.disabled, .btn-blue:disabled { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-blue:not(:disabled):not(.disabled):active, .btn-blue:not(:disabled):not(.disabled).active, .show > .btn-blue.dropdown-toggle { - color: #fff; - background-color: #0b60db; - border-color: #0a5bcf; -} -.btn-blue:not(:disabled):not(.disabled):active:focus, .btn-blue:not(:disabled):not(.disabled).active:focus, .show > .btn-blue.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(70, 142, 246, 0.5); -} - -.btn-light-blue { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-light-blue:hover { - color: #495057; - background-color: #bedffd; - border-color: #b2d8fc; -} -.btn-light-blue:focus, .btn-light-blue.focus { - color: #495057; - background-color: #bedffd; - border-color: #b2d8fc; - box-shadow: 0 0 0 0 rgba(204, 217, 229, 0.5); -} -.btn-light-blue.disabled, .btn-light-blue:disabled { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-light-blue:not(:disabled):not(.disabled):active, .btn-light-blue:not(:disabled):not(.disabled).active, .show > .btn-light-blue.dropdown-toggle { - color: #495057; - background-color: #b2d8fc; - border-color: #a5d2fc; -} -.btn-light-blue:not(:disabled):not(.disabled):active:focus, .btn-light-blue:not(:disabled):not(.disabled).active:focus, .show > .btn-light-blue.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(204, 217, 229, 0.5); -} - -.btn-yellow { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-yellow:hover { - color: #495057; - background-color: #d9ad00; - border-color: #cca300; -} -.btn-yellow:focus, .btn-yellow.focus { - color: #495057; - background-color: #d9ad00; - border-color: #cca300; - box-shadow: 0 0 0 0 rgba(228, 185, 13, 0.5); -} -.btn-yellow.disabled, .btn-yellow:disabled { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-yellow:not(:disabled):not(.disabled):active, .btn-yellow:not(:disabled):not(.disabled).active, .show > .btn-yellow.dropdown-toggle { - color: #495057; - background-color: #cca300; - border-color: #bf9900; -} -.btn-yellow:not(:disabled):not(.disabled):active:focus, .btn-yellow:not(:disabled):not(.disabled).active:focus, .show > .btn-yellow.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 185, 13, 0.5); -} - -.btn-light-yellow { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-light-yellow:hover { - color: #495057; - background-color: #ffedca; - border-color: #ffe9bd; -} -.btn-light-yellow:focus, .btn-light-yellow.focus { - color: #495057; - background-color: #ffedca; - border-color: #ffe9bd; - box-shadow: 0 0 0 0 rgba(228, 225, 217, 0.5); -} -.btn-light-yellow.disabled, .btn-light-yellow:disabled { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-light-yellow:not(:disabled):not(.disabled):active, .btn-light-yellow:not(:disabled):not(.disabled).active, .show > .btn-light-yellow.dropdown-toggle { - color: #495057; - background-color: #ffe9bd; - border-color: #ffe5b0; -} -.btn-light-yellow:not(:disabled):not(.disabled):active:focus, .btn-light-yellow:not(:disabled):not(.disabled).active:focus, .show > .btn-light-yellow.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 225, 217, 0.5); -} - -.btn-orange { - color: #495057; - background-color: #ff8c00; - border-color: #ff8c00; -} -.btn-orange:hover { - color: #fff; - background-color: #d97700; - border-color: #cc7000; -} -.btn-orange:focus, .btn-orange.focus { - color: #fff; - background-color: #d97700; - border-color: #cc7000; - box-shadow: 0 0 0 0 rgba(228, 131, 13, 0.5); -} -.btn-orange.disabled, .btn-orange:disabled { - color: #495057; - background-color: #ff8c00; - border-color: #ff8c00; -} -.btn-orange:not(:disabled):not(.disabled):active, .btn-orange:not(:disabled):not(.disabled).active, .show > .btn-orange.dropdown-toggle { - color: #fff; - background-color: #cc7000; - border-color: #bf6900; -} -.btn-orange:not(:disabled):not(.disabled):active:focus, .btn-orange:not(:disabled):not(.disabled).active:focus, .show > .btn-orange.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 131, 13, 0.5); -} - -.btn-light-orange { - color: #495057; - background-color: #ffe4b5; - border-color: #ffe4b5; -} -.btn-light-orange:hover { - color: #495057; - background-color: #ffd68f; - border-color: #ffd182; -} -.btn-light-orange:focus, .btn-light-orange.focus { - color: #495057; - background-color: #ffd68f; - border-color: #ffd182; - box-shadow: 0 0 0 0 rgba(228, 206, 167, 0.5); -} -.btn-light-orange.disabled, .btn-light-orange:disabled { - color: #495057; - background-color: #ffe4b5; - border-color: #ffe4b5; -} -.btn-light-orange:not(:disabled):not(.disabled):active, .btn-light-orange:not(:disabled):not(.disabled).active, .show > .btn-light-orange.dropdown-toggle { - color: #495057; - background-color: #ffd182; - border-color: #ffcd75; -} -.btn-light-orange:not(:disabled):not(.disabled):active:focus, .btn-light-orange:not(:disabled):not(.disabled).active:focus, .show > .btn-light-orange.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 206, 167, 0.5); -} - -.btn-red { - color: #fff; - background-color: #ff3939; - border-color: #ff3939; -} -.btn-red:hover { - color: #fff; - background-color: #ff1313; - border-color: #ff0606; -} -.btn-red:focus, .btn-red.focus { - color: #fff; - background-color: #ff1313; - border-color: #ff0606; - box-shadow: 0 0 0 0 rgba(255, 87, 87, 0.5); -} -.btn-red.disabled, .btn-red:disabled { - color: #fff; - background-color: #ff3939; - border-color: #ff3939; -} -.btn-red:not(:disabled):not(.disabled):active, .btn-red:not(:disabled):not(.disabled).active, .show > .btn-red.dropdown-toggle { - color: #fff; - background-color: #ff0606; - border-color: #f80000; -} -.btn-red:not(:disabled):not(.disabled):active:focus, .btn-red:not(:disabled):not(.disabled).active:focus, .show > .btn-red.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 87, 87, 0.5); -} - -.btn-light-red { - color: #495057; - background-color: #ffe4e1; - border-color: #ffe4e1; -} -.btn-light-red:hover { - color: #495057; - background-color: #ffc2bb; - border-color: #ffb6ae; -} -.btn-light-red:focus, .btn-light-red.focus { - color: #495057; - background-color: #ffc2bb; - border-color: #ffb6ae; - box-shadow: 0 0 0 0 rgba(228, 206, 204, 0.5); -} -.btn-light-red.disabled, .btn-light-red:disabled { - color: #495057; - background-color: #ffe4e1; - border-color: #ffe4e1; -} -.btn-light-red:not(:disabled):not(.disabled):active, .btn-light-red:not(:disabled):not(.disabled).active, .show > .btn-light-red.dropdown-toggle { - color: #495057; - background-color: #ffb6ae; - border-color: #ffaba1; -} -.btn-light-red:not(:disabled):not(.disabled):active:focus, .btn-light-red:not(:disabled):not(.disabled).active:focus, .show > .btn-light-red.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(228, 206, 204, 0.5); -} - -.btn-medium { - color: #495057; - background-color: #d6dbdf; - border-color: #d6dbdf; -} -.btn-medium:hover { - color: #495057; - background-color: #c1c8ce; - border-color: #b9c2c9; -} -.btn-medium:focus, .btn-medium.focus { - color: #495057; - background-color: #c1c8ce; - border-color: #b9c2c9; - box-shadow: 0 0 0 0 rgba(193, 198, 203, 0.5); -} -.btn-medium.disabled, .btn-medium:disabled { - color: #495057; - background-color: #d6dbdf; - border-color: #d6dbdf; -} -.btn-medium:not(:disabled):not(.disabled):active, .btn-medium:not(:disabled):not(.disabled).active, .show > .btn-medium.dropdown-toggle { - color: #495057; - background-color: #b9c2c9; - border-color: #b2bcc3; -} -.btn-medium:not(:disabled):not(.disabled):active:focus, .btn-medium:not(:disabled):not(.disabled).active:focus, .show > .btn-medium.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(193, 198, 203, 0.5); -} - -.btn-outline-primary { - color: #ffcc00; - border-color: #ffcc00; -} -.btn-outline-primary:hover { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-outline-primary:focus, .btn-outline-primary.focus { - box-shadow: 0 0 0 0 rgba(255, 204, 0, 0.5); -} -.btn-outline-primary.disabled, .btn-outline-primary:disabled { - color: #ffcc00; - background-color: transparent; -} -.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, .show > .btn-outline-primary.dropdown-toggle { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-primary.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 204, 0, 0.5); -} - -.btn-outline-secondary { - color: #212529; - border-color: #212529; -} -.btn-outline-secondary:hover { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-outline-secondary:focus, .btn-outline-secondary.focus { - box-shadow: 0 0 0 0 rgba(33, 37, 41, 0.5); -} -.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { - color: #212529; - background-color: transparent; -} -.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, .show > .btn-outline-secondary.dropdown-toggle { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-secondary.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(33, 37, 41, 0.5); -} - -.btn-outline-success { - color: #28a745; - border-color: #28a745; -} -.btn-outline-success:hover { - color: #fff; - background-color: #28a745; - border-color: #28a745; -} -.btn-outline-success:focus, .btn-outline-success.focus { - box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.5); -} -.btn-outline-success.disabled, .btn-outline-success:disabled { - color: #28a745; - background-color: transparent; -} -.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active, .show > .btn-outline-success.dropdown-toggle { - color: #fff; - background-color: #28a745; - border-color: #28a745; -} -.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-success.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(40, 167, 69, 0.5); -} - -.btn-outline-info { - color: #17a2b8; - border-color: #17a2b8; -} -.btn-outline-info:hover { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; -} -.btn-outline-info:focus, .btn-outline-info.focus { - box-shadow: 0 0 0 0 rgba(23, 162, 184, 0.5); -} -.btn-outline-info.disabled, .btn-outline-info:disabled { - color: #17a2b8; - background-color: transparent; -} -.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active, .show > .btn-outline-info.dropdown-toggle { - color: #fff; - background-color: #17a2b8; - border-color: #17a2b8; -} -.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-info.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(23, 162, 184, 0.5); -} - -.btn-outline-warning { - color: #ffc107; - border-color: #ffc107; -} -.btn-outline-warning:hover { - color: #495057; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-outline-warning:focus, .btn-outline-warning.focus { - box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.5); -} -.btn-outline-warning.disabled, .btn-outline-warning:disabled { - color: #ffc107; - background-color: transparent; -} -.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, .show > .btn-outline-warning.dropdown-toggle { - color: #495057; - background-color: #ffc107; - border-color: #ffc107; -} -.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-warning.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 193, 7, 0.5); -} - -.btn-outline-danger { - color: #dc3545; - border-color: #dc3545; -} -.btn-outline-danger:hover { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-outline-danger:focus, .btn-outline-danger.focus { - box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.5); -} -.btn-outline-danger.disabled, .btn-outline-danger:disabled { - color: #dc3545; - background-color: transparent; -} -.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active, .show > .btn-outline-danger.dropdown-toggle { - color: #fff; - background-color: #dc3545; - border-color: #dc3545; -} -.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-danger.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(220, 53, 69, 0.5); -} - -.btn-outline-light { - color: #f1f6f9; - border-color: #f1f6f9; -} -.btn-outline-light:hover { - color: #495057; - background-color: #f1f6f9; - border-color: #f1f6f9; -} -.btn-outline-light:focus, .btn-outline-light.focus { - box-shadow: 0 0 0 0 rgba(241, 246, 249, 0.5); -} -.btn-outline-light.disabled, .btn-outline-light:disabled { - color: #f1f6f9; - background-color: transparent; -} -.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active, .show > .btn-outline-light.dropdown-toggle { - color: #495057; - background-color: #f1f6f9; - border-color: #f1f6f9; -} -.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(241, 246, 249, 0.5); -} - -.btn-outline-dark { - color: #495057; - border-color: #495057; -} -.btn-outline-dark:hover { - color: #fff; - background-color: #495057; - border-color: #495057; -} -.btn-outline-dark:focus, .btn-outline-dark.focus { - box-shadow: 0 0 0 0 rgba(73, 80, 87, 0.5); -} -.btn-outline-dark.disabled, .btn-outline-dark:disabled { - color: #495057; - background-color: transparent; -} -.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active, .show > .btn-outline-dark.dropdown-toggle { - color: #fff; - background-color: #495057; - border-color: #495057; -} -.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-dark.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(73, 80, 87, 0.5); -} - -.btn-outline-primary-light { - color: #fffaf0; - border-color: #fffaf0; -} -.btn-outline-primary-light:hover { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-outline-primary-light:focus, .btn-outline-primary-light.focus { - box-shadow: 0 0 0 0 rgba(255, 250, 240, 0.5); -} -.btn-outline-primary-light.disabled, .btn-outline-primary-light:disabled { - color: #fffaf0; - background-color: transparent; -} -.btn-outline-primary-light:not(:disabled):not(.disabled):active, .btn-outline-primary-light:not(:disabled):not(.disabled).active, .show > .btn-outline-primary-light.dropdown-toggle { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-outline-primary-light:not(:disabled):not(.disabled):active:focus, .btn-outline-primary-light:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-primary-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 250, 240, 0.5); -} - -.btn-outline-secondary-light { - color: #fff; - border-color: #fff; -} -.btn-outline-secondary-light:hover { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-outline-secondary-light:focus, .btn-outline-secondary-light.focus { - box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); -} -.btn-outline-secondary-light.disabled, .btn-outline-secondary-light:disabled { - color: #fff; - background-color: transparent; -} -.btn-outline-secondary-light:not(:disabled):not(.disabled):active, .btn-outline-secondary-light:not(:disabled):not(.disabled).active, .show > .btn-outline-secondary-light.dropdown-toggle { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-outline-secondary-light:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary-light:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-secondary-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); -} - -.btn-outline-tertiary { - color: #257af4; - border-color: #257af4; -} -.btn-outline-tertiary:hover { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-outline-tertiary:focus, .btn-outline-tertiary.focus { - box-shadow: 0 0 0 0 rgba(37, 122, 244, 0.5); -} -.btn-outline-tertiary.disabled, .btn-outline-tertiary:disabled { - color: #257af4; - background-color: transparent; -} -.btn-outline-tertiary:not(:disabled):not(.disabled):active, .btn-outline-tertiary:not(:disabled):not(.disabled).active, .show > .btn-outline-tertiary.dropdown-toggle { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-outline-tertiary:not(:disabled):not(.disabled):active:focus, .btn-outline-tertiary:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-tertiary.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(37, 122, 244, 0.5); -} - -.btn-outline-tertiary-light { - color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-outline-tertiary-light:hover { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-outline-tertiary-light:focus, .btn-outline-tertiary-light.focus { - box-shadow: 0 0 0 0 rgba(227, 241, 254, 0.5); -} -.btn-outline-tertiary-light.disabled, .btn-outline-tertiary-light:disabled { - color: #e3f1fe; - background-color: transparent; -} -.btn-outline-tertiary-light:not(:disabled):not(.disabled):active, .btn-outline-tertiary-light:not(:disabled):not(.disabled).active, .show > .btn-outline-tertiary-light.dropdown-toggle { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-outline-tertiary-light:not(:disabled):not(.disabled):active:focus, .btn-outline-tertiary-light:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-tertiary-light.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(227, 241, 254, 0.5); -} - -.btn-outline-white { - color: #fff; - border-color: #fff; -} -.btn-outline-white:hover { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-outline-white:focus, .btn-outline-white.focus { - box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); -} -.btn-outline-white.disabled, .btn-outline-white:disabled { - color: #fff; - background-color: transparent; -} -.btn-outline-white:not(:disabled):not(.disabled):active, .btn-outline-white:not(:disabled):not(.disabled).active, .show > .btn-outline-white.dropdown-toggle { - color: #495057; - background-color: #fff; - border-color: #fff; -} -.btn-outline-white:not(:disabled):not(.disabled):active:focus, .btn-outline-white:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-white.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); -} - -.btn-outline-black { - color: #212529; - border-color: #212529; -} -.btn-outline-black:hover { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-outline-black:focus, .btn-outline-black.focus { - box-shadow: 0 0 0 0 rgba(33, 37, 41, 0.5); -} -.btn-outline-black.disabled, .btn-outline-black:disabled { - color: #212529; - background-color: transparent; -} -.btn-outline-black:not(:disabled):not(.disabled):active, .btn-outline-black:not(:disabled):not(.disabled).active, .show > .btn-outline-black.dropdown-toggle { - color: #fff; - background-color: #212529; - border-color: #212529; -} -.btn-outline-black:not(:disabled):not(.disabled):active:focus, .btn-outline-black:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-black.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(33, 37, 41, 0.5); -} - -.btn-outline-blue { - color: #257af4; - border-color: #257af4; -} -.btn-outline-blue:hover { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-outline-blue:focus, .btn-outline-blue.focus { - box-shadow: 0 0 0 0 rgba(37, 122, 244, 0.5); -} -.btn-outline-blue.disabled, .btn-outline-blue:disabled { - color: #257af4; - background-color: transparent; -} -.btn-outline-blue:not(:disabled):not(.disabled):active, .btn-outline-blue:not(:disabled):not(.disabled).active, .show > .btn-outline-blue.dropdown-toggle { - color: #fff; - background-color: #257af4; - border-color: #257af4; -} -.btn-outline-blue:not(:disabled):not(.disabled):active:focus, .btn-outline-blue:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-blue.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(37, 122, 244, 0.5); -} - -.btn-outline-light-blue { - color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-outline-light-blue:hover { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-outline-light-blue:focus, .btn-outline-light-blue.focus { - box-shadow: 0 0 0 0 rgba(227, 241, 254, 0.5); -} -.btn-outline-light-blue.disabled, .btn-outline-light-blue:disabled { - color: #e3f1fe; - background-color: transparent; -} -.btn-outline-light-blue:not(:disabled):not(.disabled):active, .btn-outline-light-blue:not(:disabled):not(.disabled).active, .show > .btn-outline-light-blue.dropdown-toggle { - color: #495057; - background-color: #e3f1fe; - border-color: #e3f1fe; -} -.btn-outline-light-blue:not(:disabled):not(.disabled):active:focus, .btn-outline-light-blue:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light-blue.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(227, 241, 254, 0.5); -} - -.btn-outline-yellow { - color: #ffcc00; - border-color: #ffcc00; -} -.btn-outline-yellow:hover { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-outline-yellow:focus, .btn-outline-yellow.focus { - box-shadow: 0 0 0 0 rgba(255, 204, 0, 0.5); -} -.btn-outline-yellow.disabled, .btn-outline-yellow:disabled { - color: #ffcc00; - background-color: transparent; -} -.btn-outline-yellow:not(:disabled):not(.disabled):active, .btn-outline-yellow:not(:disabled):not(.disabled).active, .show > .btn-outline-yellow.dropdown-toggle { - color: #495057; - background-color: #ffcc00; - border-color: #ffcc00; -} -.btn-outline-yellow:not(:disabled):not(.disabled):active:focus, .btn-outline-yellow:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-yellow.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 204, 0, 0.5); -} - -.btn-outline-light-yellow { - color: #fffaf0; - border-color: #fffaf0; -} -.btn-outline-light-yellow:hover { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-outline-light-yellow:focus, .btn-outline-light-yellow.focus { - box-shadow: 0 0 0 0 rgba(255, 250, 240, 0.5); -} -.btn-outline-light-yellow.disabled, .btn-outline-light-yellow:disabled { - color: #fffaf0; - background-color: transparent; -} -.btn-outline-light-yellow:not(:disabled):not(.disabled):active, .btn-outline-light-yellow:not(:disabled):not(.disabled).active, .show > .btn-outline-light-yellow.dropdown-toggle { - color: #495057; - background-color: #fffaf0; - border-color: #fffaf0; -} -.btn-outline-light-yellow:not(:disabled):not(.disabled):active:focus, .btn-outline-light-yellow:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light-yellow.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 250, 240, 0.5); -} - -.btn-outline-orange { - color: #ff8c00; - border-color: #ff8c00; -} -.btn-outline-orange:hover { - color: #495057; - background-color: #ff8c00; - border-color: #ff8c00; -} -.btn-outline-orange:focus, .btn-outline-orange.focus { - box-shadow: 0 0 0 0 rgba(255, 140, 0, 0.5); -} -.btn-outline-orange.disabled, .btn-outline-orange:disabled { - color: #ff8c00; - background-color: transparent; -} -.btn-outline-orange:not(:disabled):not(.disabled):active, .btn-outline-orange:not(:disabled):not(.disabled).active, .show > .btn-outline-orange.dropdown-toggle { - color: #495057; - background-color: #ff8c00; - border-color: #ff8c00; -} -.btn-outline-orange:not(:disabled):not(.disabled):active:focus, .btn-outline-orange:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-orange.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 140, 0, 0.5); -} - -.btn-outline-light-orange { - color: #ffe4b5; - border-color: #ffe4b5; -} -.btn-outline-light-orange:hover { - color: #495057; - background-color: #ffe4b5; - border-color: #ffe4b5; -} -.btn-outline-light-orange:focus, .btn-outline-light-orange.focus { - box-shadow: 0 0 0 0 rgba(255, 228, 181, 0.5); -} -.btn-outline-light-orange.disabled, .btn-outline-light-orange:disabled { - color: #ffe4b5; - background-color: transparent; -} -.btn-outline-light-orange:not(:disabled):not(.disabled):active, .btn-outline-light-orange:not(:disabled):not(.disabled).active, .show > .btn-outline-light-orange.dropdown-toggle { - color: #495057; - background-color: #ffe4b5; - border-color: #ffe4b5; -} -.btn-outline-light-orange:not(:disabled):not(.disabled):active:focus, .btn-outline-light-orange:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light-orange.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 228, 181, 0.5); -} - -.btn-outline-red { - color: #ff3939; - border-color: #ff3939; -} -.btn-outline-red:hover { - color: #fff; - background-color: #ff3939; - border-color: #ff3939; -} -.btn-outline-red:focus, .btn-outline-red.focus { - box-shadow: 0 0 0 0 rgba(255, 57, 57, 0.5); -} -.btn-outline-red.disabled, .btn-outline-red:disabled { - color: #ff3939; - background-color: transparent; -} -.btn-outline-red:not(:disabled):not(.disabled):active, .btn-outline-red:not(:disabled):not(.disabled).active, .show > .btn-outline-red.dropdown-toggle { - color: #fff; - background-color: #ff3939; - border-color: #ff3939; -} -.btn-outline-red:not(:disabled):not(.disabled):active:focus, .btn-outline-red:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-red.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 57, 57, 0.5); -} - -.btn-outline-light-red { - color: #ffe4e1; - border-color: #ffe4e1; -} -.btn-outline-light-red:hover { - color: #495057; - background-color: #ffe4e1; - border-color: #ffe4e1; -} -.btn-outline-light-red:focus, .btn-outline-light-red.focus { - box-shadow: 0 0 0 0 rgba(255, 228, 225, 0.5); -} -.btn-outline-light-red.disabled, .btn-outline-light-red:disabled { - color: #ffe4e1; - background-color: transparent; -} -.btn-outline-light-red:not(:disabled):not(.disabled):active, .btn-outline-light-red:not(:disabled):not(.disabled).active, .show > .btn-outline-light-red.dropdown-toggle { - color: #495057; - background-color: #ffe4e1; - border-color: #ffe4e1; -} -.btn-outline-light-red:not(:disabled):not(.disabled):active:focus, .btn-outline-light-red:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-light-red.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(255, 228, 225, 0.5); -} - -.btn-outline-medium { - color: #d6dbdf; - border-color: #d6dbdf; -} -.btn-outline-medium:hover { - color: #495057; - background-color: #d6dbdf; - border-color: #d6dbdf; -} -.btn-outline-medium:focus, .btn-outline-medium.focus { - box-shadow: 0 0 0 0 rgba(214, 219, 223, 0.5); -} -.btn-outline-medium.disabled, .btn-outline-medium:disabled { - color: #d6dbdf; - background-color: transparent; -} -.btn-outline-medium:not(:disabled):not(.disabled):active, .btn-outline-medium:not(:disabled):not(.disabled).active, .show > .btn-outline-medium.dropdown-toggle { - color: #495057; - background-color: #d6dbdf; - border-color: #d6dbdf; -} -.btn-outline-medium:not(:disabled):not(.disabled):active:focus, .btn-outline-medium:not(:disabled):not(.disabled).active:focus, .show > .btn-outline-medium.dropdown-toggle:focus { - box-shadow: 0 0 0 0 rgba(214, 219, 223, 0.5); -} - -.btn-link { - font-weight: 400; - color: #ff8c00; - text-decoration: none; -} -.btn-link:hover { - color: #ff8c00; - text-decoration: underline; -} -.btn-link:focus, .btn-link.focus { - text-decoration: underline; - box-shadow: none; -} -.btn-link:disabled, .btn-link.disabled { - color: #d6dbdf; - pointer-events: none; -} - -.btn-lg, .btn-group-lg > .btn { - padding: 16px 32px; - font-size: 1.125rem; - line-height: 26px; - border-radius: 8px; -} - -.btn-sm, .btn-group-sm > .btn { - padding: 12px 32px; - font-size: 0.875rem; - line-height: 20px; - border-radius: 8px; -} - -.btn-block { - display: block; - width: 100%; -} -.btn-block + .btn-block { - margin-top: 24px; -} - -input[type=submit].btn-block, -input[type=reset].btn-block, -input[type=button].btn-block { - width: 100%; -} - -.fade { - transition: opacity 0.15s linear; -} -@media (prefers-reduced-motion: reduce) { - .fade { - transition: none; - } -} -.fade:not(.show) { - opacity: 0; -} - -.collapse:not(.show) { - display: none; -} - -.collapsing { - position: relative; - height: 0; - overflow: hidden; - transition: height 0.35s ease; -} -@media (prefers-reduced-motion: reduce) { - .collapsing { - transition: none; - } -} - -.dropup, -.dropright, -.dropdown, -.dropleft { - position: relative; -} - -.dropdown-toggle { - white-space: nowrap; -} -.dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid; - border-right: 0.3em solid transparent; - border-bottom: 0; - border-left: 0.3em solid transparent; -} -.dropdown-toggle:empty::after { - margin-left: 0; -} - -.dropdown-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 10rem; - padding: 0.5rem 0; - margin: 0.125rem 0 0; - font-size: 1rem; - color: #212529; - text-align: left; - list-style: none; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(33, 37, 41, 0.15); - border-radius: 8px; -} - -.dropdown-menu-left { - right: auto; - left: 0; -} - -.dropdown-menu-right { - right: 0; - left: auto; -} - -@media (min-width: 400px) { - .dropdown-menu-xs-left { - right: auto; - left: 0; - } - - .dropdown-menu-xs-right { - right: 0; - left: auto; - } -} -@media (min-width: 616px) { - .dropdown-menu-sm-left { - right: auto; - left: 0; - } - - .dropdown-menu-sm-right { - right: 0; - left: auto; - } -} -@media (min-width: 768px) { - .dropdown-menu-md-left { - right: auto; - left: 0; - } - - .dropdown-menu-md-right { - right: 0; - left: auto; - } -} -@media (min-width: 980px) { - .dropdown-menu-lg-left { - right: auto; - left: 0; - } - - .dropdown-menu-lg-right { - right: 0; - left: auto; - } -} -@media (min-width: 1240px) { - .dropdown-menu-xl-left { - right: auto; - left: 0; - } - - .dropdown-menu-xl-right { - right: 0; - left: auto; - } -} -.dropup .dropdown-menu { - top: auto; - bottom: 100%; - margin-top: 0; - margin-bottom: 0.125rem; -} -.dropup .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0; - border-right: 0.3em solid transparent; - border-bottom: 0.3em solid; - border-left: 0.3em solid transparent; -} -.dropup .dropdown-toggle:empty::after { - margin-left: 0; -} - -.dropright .dropdown-menu { - top: 0; - right: auto; - left: 100%; - margin-top: 0; - margin-left: 0.125rem; -} -.dropright .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid transparent; - border-right: 0; - border-bottom: 0.3em solid transparent; - border-left: 0.3em solid; -} -.dropright .dropdown-toggle:empty::after { - margin-left: 0; -} -.dropright .dropdown-toggle::after { - vertical-align: 0; -} - -.dropleft .dropdown-menu { - top: 0; - right: 100%; - left: auto; - margin-top: 0; - margin-right: 0.125rem; -} -.dropleft .dropdown-toggle::after { - display: inline-block; - margin-left: 0.255em; - vertical-align: 0.255em; - content: ""; -} -.dropleft .dropdown-toggle::after { - display: none; -} -.dropleft .dropdown-toggle::before { - display: inline-block; - margin-right: 0.255em; - vertical-align: 0.255em; - content: ""; - border-top: 0.3em solid transparent; - border-right: 0.3em solid; - border-bottom: 0.3em solid transparent; -} -.dropleft .dropdown-toggle:empty::after { - margin-left: 0; -} -.dropleft .dropdown-toggle::before { - vertical-align: 0; -} - -.dropdown-menu[x-placement^=top], .dropdown-menu[x-placement^=right], .dropdown-menu[x-placement^=bottom], .dropdown-menu[x-placement^=left] { - right: auto; - bottom: auto; -} - -.dropdown-divider { - height: 0; - margin: 4px 0; - overflow: hidden; - border-top: 1px solid #e9ecef; -} - -.dropdown-item { - display: block; - width: 100%; - padding: 0.25rem 1.5rem; - clear: both; - font-weight: 400; - color: #495057; - text-align: inherit; - white-space: nowrap; - background-color: transparent; - border: 0; -} -.dropdown-item:hover, .dropdown-item:focus { - color: #3d4349; - text-decoration: none; - background-color: #f1f6f9; -} -.dropdown-item.active, .dropdown-item:active { - color: #fff; - text-decoration: none; - background-color: #ffcc00; -} -.dropdown-item.disabled, .dropdown-item:disabled { - color: #6c757d; - pointer-events: none; - background-color: transparent; -} - -.dropdown-menu.show { - display: block; -} - -.dropdown-header { - display: block; - padding: 0.5rem 1.5rem; - margin-bottom: 0; - font-size: 0.875rem; - color: #6c757d; - white-space: nowrap; -} - -.dropdown-item-text { - display: block; - padding: 0.25rem 1.5rem; - color: #495057; -} - -.btn-group, -.btn-group-vertical { - position: relative; - display: inline-flex; - vertical-align: middle; -} -.btn-group > .btn, -.btn-group-vertical > .btn { - position: relative; - flex: 1 1 auto; -} -.btn-group > .btn:hover, -.btn-group-vertical > .btn:hover { - z-index: 1; -} -.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, -.btn-group-vertical > .btn:focus, -.btn-group-vertical > .btn:active, -.btn-group-vertical > .btn.active { - z-index: 1; -} - -.btn-toolbar { - display: flex; - flex-wrap: wrap; - justify-content: flex-start; -} -.btn-toolbar .input-group { - width: auto; -} - -.btn-group > .btn:not(:first-child), -.btn-group > .btn-group:not(:first-child) { - margin-left: -1px; -} -.btn-group > .btn:not(:last-child):not(.dropdown-toggle), -.btn-group > .btn-group:not(:last-child) > .btn { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.btn-group > .btn:not(:first-child), -.btn-group > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} - -.dropdown-toggle-split { - padding-right: 24px; - padding-left: 24px; -} -.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropright .dropdown-toggle-split::after { - margin-left: 0; -} -.dropleft .dropdown-toggle-split::before { - margin-right: 0; -} - -.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { - padding-right: 24px; - padding-left: 24px; -} - -.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { - padding-right: 24px; - padding-left: 24px; -} - -.btn-group-vertical { - flex-direction: column; - align-items: flex-start; - justify-content: center; -} -.btn-group-vertical > .btn, -.btn-group-vertical > .btn-group { - width: 100%; -} -.btn-group-vertical > .btn:not(:first-child), -.btn-group-vertical > .btn-group:not(:first-child) { - margin-top: -1px; -} -.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), -.btn-group-vertical > .btn-group:not(:last-child) > .btn { - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.btn-group-vertical > .btn:not(:first-child), -.btn-group-vertical > .btn-group:not(:first-child) > .btn { - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.btn-group-toggle > .btn, -.btn-group-toggle > .btn-group > .btn { - margin-bottom: 0; -} -.btn-group-toggle > .btn input[type=radio], -.btn-group-toggle > .btn input[type=checkbox], -.btn-group-toggle > .btn-group > .btn input[type=radio], -.btn-group-toggle > .btn-group > .btn input[type=checkbox] { - position: absolute; - clip: rect(0, 0, 0, 0); - pointer-events: none; -} - -.input-group { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: stretch; - width: 100%; -} -.input-group > .form-control, -.input-group > .form-control-plaintext, -.input-group > .custom-select, -.input-group > .custom-file { - position: relative; - flex: 1 1 0%; - min-width: 0; - margin-bottom: 0; -} -.input-group > .form-control + .form-control, -.input-group > .form-control + .custom-select, -.input-group > .form-control + .custom-file, -.input-group > .form-control-plaintext + .form-control, -.input-group > .form-control-plaintext + .custom-select, -.input-group > .form-control-plaintext + .custom-file, -.input-group > .custom-select + .form-control, -.input-group > .custom-select + .custom-select, -.input-group > .custom-select + .custom-file, -.input-group > .custom-file + .form-control, -.input-group > .custom-file + .custom-select, -.input-group > .custom-file + .custom-file { - margin-left: -1px; -} -.input-group > .form-control:focus, -.input-group > .custom-select:focus, -.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label { - z-index: 3; -} -.input-group > .custom-file .custom-file-input:focus { - z-index: 4; -} -.input-group > .form-control:not(:last-child), -.input-group > .custom-select:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.input-group > .form-control:not(:first-child), -.input-group > .custom-select:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} -.input-group > .custom-file { - display: flex; - align-items: center; -} -.input-group > .custom-file:not(:last-child) .custom-file-label, .input-group > .custom-file:not(:last-child) .custom-file-label::after { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} -.input-group > .custom-file:not(:first-child) .custom-file-label { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} - -.input-group-prepend, -.input-group-append { - display: flex; -} -.input-group-prepend .btn, -.input-group-append .btn { - position: relative; - z-index: 2; -} -.input-group-prepend .btn:focus, -.input-group-append .btn:focus { - z-index: 3; -} -.input-group-prepend .btn + .btn, -.input-group-prepend .btn + .input-group-text, -.input-group-prepend .input-group-text + .input-group-text, -.input-group-prepend .input-group-text + .btn, -.input-group-append .btn + .btn, -.input-group-append .btn + .input-group-text, -.input-group-append .input-group-text + .input-group-text, -.input-group-append .input-group-text + .btn { - margin-left: -1px; -} - -.input-group-prepend { - margin-right: -1px; -} - -.input-group-append { - margin-left: -1px; -} - -.input-group-text { - display: flex; - align-items: center; - padding: 0.375rem 0.75rem; - margin-bottom: 0; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #6c757d; - text-align: center; - white-space: nowrap; - background-color: #e9ecef; - border: 1px solid #ced4da; - border-radius: 8px; -} -.input-group-text input[type=radio], -.input-group-text input[type=checkbox] { - margin-top: 0; -} - -.input-group-lg > .form-control:not(textarea), -.input-group-lg > .custom-select { - height: calc(1.5em + 1rem + 2px); -} - -.input-group-lg > .form-control, -.input-group-lg > .custom-select, -.input-group-lg > .input-group-prepend > .input-group-text, -.input-group-lg > .input-group-append > .input-group-text, -.input-group-lg > .input-group-prepend > .btn, -.input-group-lg > .input-group-append > .btn { - padding: 0.5rem 1rem; - font-size: 1.125rem; - line-height: 1.5; - border-radius: 8px; -} - -.input-group-sm > .form-control:not(textarea), -.input-group-sm > .custom-select { - height: calc(1.5em + 0.5rem + 2px); -} - -.input-group-sm > .form-control, -.input-group-sm > .custom-select, -.input-group-sm > .input-group-prepend > .input-group-text, -.input-group-sm > .input-group-append > .input-group-text, -.input-group-sm > .input-group-prepend > .btn, -.input-group-sm > .input-group-append > .btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; - border-radius: 8px; -} - -.input-group-lg > .custom-select, -.input-group-sm > .custom-select { - padding-right: 1.75rem; -} - -.input-group > .input-group-prepend > .btn, -.input-group > .input-group-prepend > .input-group-text, -.input-group > .input-group-append:not(:last-child) > .btn, -.input-group > .input-group-append:not(:last-child) > .input-group-text, -.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), -.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; -} - -.input-group > .input-group-append > .btn, -.input-group > .input-group-append > .input-group-text, -.input-group > .input-group-prepend:not(:first-child) > .btn, -.input-group > .input-group-prepend:not(:first-child) > .input-group-text, -.input-group > .input-group-prepend:first-child > .btn:not(:first-child), -.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; -} - -.custom-control { - position: relative; - display: block; - min-height: 1.5rem; - padding-left: 1.5rem; -} - -.custom-control-inline { - display: inline-flex; - margin-right: 1rem; -} - -.custom-control-input { - position: absolute; - left: 0; - z-index: -1; - width: 1rem; - height: 1.25rem; - opacity: 0; -} -.custom-control-input:checked ~ .custom-control-label::before { - color: #fff; - border-color: #ffcc00; - background-color: #ffcc00; -} -.custom-control-input:focus ~ .custom-control-label::before { - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.custom-control-input:focus:not(:checked) ~ .custom-control-label::before { - border-color: #ffe680; -} -.custom-control-input:not(:disabled):active ~ .custom-control-label::before { - color: #fff; - background-color: #fff0b3; - border-color: #fff0b3; -} -.custom-control-input[disabled] ~ .custom-control-label, .custom-control-input:disabled ~ .custom-control-label { - color: #6c757d; -} -.custom-control-input[disabled] ~ .custom-control-label::before, .custom-control-input:disabled ~ .custom-control-label::before { - background-color: #e9ecef; -} - -.custom-control-label { - position: relative; - margin-bottom: 0; - vertical-align: top; -} -.custom-control-label::before { - position: absolute; - top: 0.25rem; - left: -1.5rem; - display: block; - width: 1rem; - height: 1rem; - pointer-events: none; - content: ""; - background-color: #fff; - border: #d6dbdf solid 1px; -} -.custom-control-label::after { - position: absolute; - top: 0.25rem; - left: -1.5rem; - display: block; - width: 1rem; - height: 1rem; - content: ""; - background: no-repeat 50%/50% 50%; -} - -.custom-checkbox .custom-control-label::before { - border-radius: 8px; -} -.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e"); -} -.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { - border-color: #ffcc00; - background-color: #ffcc00; -} -.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e"); -} -.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(255, 204, 0, 0.5); -} -.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { - background-color: rgba(255, 204, 0, 0.5); -} - -.custom-radio .custom-control-label::before { - border-radius: 50%; -} -.custom-radio .custom-control-input:checked ~ .custom-control-label::after { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); -} -.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(255, 204, 0, 0.5); -} - -.custom-switch { - padding-left: 2.25rem; -} -.custom-switch .custom-control-label::before { - left: -2.25rem; - width: 1.75rem; - pointer-events: all; - border-radius: 0.5rem; -} -.custom-switch .custom-control-label::after { - top: calc(0.25rem + 2px); - left: calc(-2.25rem + 2px); - width: calc(1rem - 4px); - height: calc(1rem - 4px); - background-color: #d6dbdf; - border-radius: 0.5rem; - transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .custom-switch .custom-control-label::after { - transition: none; - } -} -.custom-switch .custom-control-input:checked ~ .custom-control-label::after { - background-color: #fff; - transform: translateX(0.75rem); -} -.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before { - background-color: rgba(255, 204, 0, 0.5); -} - -.custom-select { - display: inline-block; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - padding: 0.375rem 1.75rem 0.375rem 0.75rem; - font-size: 1rem; - font-weight: 400; - line-height: 1.5; - color: #6c757d; - vertical-align: middle; - background: #fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right 0.75rem center/8px 10px; - border: 1px solid #ced4da; - border-radius: 8px; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} -.custom-select:focus { - border-color: #ffe680; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.custom-select:focus::-ms-value { - color: #6c757d; - background-color: #fff; -} -.custom-select[multiple], .custom-select[size]:not([size="1"]) { - height: auto; - padding-right: 0.75rem; - background-image: none; -} -.custom-select:disabled { - color: #6c757d; - background-color: #e9ecef; -} -.custom-select::-ms-expand { - display: none; -} -.custom-select:-moz-focusring { - color: transparent; - text-shadow: 0 0 0 #6c757d; -} - -.custom-select-sm { - height: calc(1.5em + 0.5rem + 2px); - padding-top: 0.25rem; - padding-bottom: 0.25rem; - padding-left: 0.5rem; - font-size: 0.875rem; -} - -.custom-select-lg { - height: calc(1.5em + 1rem + 2px); - padding-top: 0.5rem; - padding-bottom: 0.5rem; - padding-left: 1rem; - font-size: 1.125rem; -} - -.custom-file { - position: relative; - display: inline-block; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - margin-bottom: 0; -} - -.custom-file-input { - position: relative; - z-index: 2; - width: 100%; - height: calc(1.5em + 0.75rem + 2px); - margin: 0; - opacity: 0; -} -.custom-file-input:focus ~ .custom-file-label { - border-color: #ffe680; - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.custom-file-input[disabled] ~ .custom-file-label, .custom-file-input:disabled ~ .custom-file-label { - background-color: #e9ecef; -} -.custom-file-input:lang(en) ~ .custom-file-label::after { - content: "Browse"; -} -.custom-file-input ~ .custom-file-label[data-browse]::after { - content: attr(data-browse); -} - -.custom-file-label { - position: absolute; - top: 0; - right: 0; - left: 0; - z-index: 1; - height: calc(1.5em + 0.75rem + 2px); - padding: 0.375rem 0.75rem; - font-weight: 400; - line-height: 1.5; - color: #6c757d; - background-color: #fff; - border: 1px solid #ced4da; - border-radius: 8px; -} -.custom-file-label::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - z-index: 3; - display: block; - height: calc(1.5em + 0.75rem); - padding: 0.375rem 0.75rem; - line-height: 1.5; - color: #6c757d; - content: "Browse"; - background-color: #e9ecef; - border-left: inherit; - border-radius: 0 8px 8px 0; -} - -.custom-range { - width: 100%; - height: 1.4rem; - padding: 0; - background-color: transparent; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} -.custom-range:focus { - outline: none; -} -.custom-range:focus::-webkit-slider-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.custom-range:focus::-moz-range-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.custom-range:focus::-ms-thumb { - box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} -.custom-range::-moz-focus-outer { - border: 0; -} -.custom-range::-webkit-slider-thumb { - width: 1rem; - height: 1rem; - margin-top: -0.25rem; - background-color: #ffcc00; - border: 0; - border-radius: 1rem; - -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - -webkit-appearance: none; - appearance: none; -} -@media (prefers-reduced-motion: reduce) { - .custom-range::-webkit-slider-thumb { - -webkit-transition: none; - transition: none; - } -} -.custom-range::-webkit-slider-thumb:active { - background-color: #fff0b3; -} -.custom-range::-webkit-slider-runnable-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; -} -.custom-range::-moz-range-thumb { - width: 1rem; - height: 1rem; - background-color: #ffcc00; - border: 0; - border-radius: 1rem; - -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - -moz-appearance: none; - appearance: none; -} -@media (prefers-reduced-motion: reduce) { - .custom-range::-moz-range-thumb { - -moz-transition: none; - transition: none; - } -} -.custom-range::-moz-range-thumb:active { - background-color: #fff0b3; -} -.custom-range::-moz-range-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: #dee2e6; - border-color: transparent; - border-radius: 1rem; -} -.custom-range::-ms-thumb { - width: 1rem; - height: 1rem; - margin-top: 0; - margin-right: 0.2rem; - margin-left: 0.2rem; - background-color: #ffcc00; - border: 0; - border-radius: 1rem; - -ms-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; - appearance: none; -} -@media (prefers-reduced-motion: reduce) { - .custom-range::-ms-thumb { - -ms-transition: none; - transition: none; - } -} -.custom-range::-ms-thumb:active { - background-color: #fff0b3; -} -.custom-range::-ms-track { - width: 100%; - height: 0.5rem; - color: transparent; - cursor: pointer; - background-color: transparent; - border-color: transparent; - border-width: 0.5rem; -} -.custom-range::-ms-fill-lower { - background-color: #dee2e6; - border-radius: 1rem; -} -.custom-range::-ms-fill-upper { - margin-right: 15px; - background-color: #dee2e6; - border-radius: 1rem; -} -.custom-range:disabled::-webkit-slider-thumb { - background-color: #d6dbdf; -} -.custom-range:disabled::-webkit-slider-runnable-track { - cursor: default; -} -.custom-range:disabled::-moz-range-thumb { - background-color: #d6dbdf; -} -.custom-range:disabled::-moz-range-track { - cursor: default; -} -.custom-range:disabled::-ms-thumb { - background-color: #d6dbdf; -} - -.custom-control-label::before, -.custom-file-label, -.custom-select { - transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .custom-control-label::before, -.custom-file-label, -.custom-select { - transition: none; - } -} - -.nav { - display: flex; - flex-wrap: wrap; - padding-left: 0; - margin-bottom: 0; - list-style: none; -} - -.nav-link { - display: block; - padding: 0 0; -} -.nav-link:hover, .nav-link:focus { - text-decoration: none; -} -.nav-link.disabled { - color: #d6dbdf; - pointer-events: none; - cursor: default; -} - -.nav-tabs { - border-bottom: 1px solid #6c757d; -} -.nav-tabs .nav-item { - margin-bottom: -1px; -} -.nav-tabs .nav-link { - border: 1px solid transparent; - border-top-left-radius: 8px; - border-top-right-radius: 8px; -} -.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { - border-color: transparent; -} -.nav-tabs .nav-link.disabled { - color: #d6dbdf; - background-color: transparent; - border-color: transparent; -} -.nav-tabs .nav-link.active, -.nav-tabs .nav-item.show .nav-link { - color: #257af4; - background-color: #fff; - border-color: #6c757d; -} -.nav-tabs .dropdown-menu { - margin-top: -1px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.nav-pills .nav-link { - border-radius: 8px; -} -.nav-pills .nav-link.active, -.nav-pills .show > .nav-link { - color: #fff; - background-color: #ffcc00; -} - -.nav-fill .nav-item { - flex: 1 1 auto; - text-align: center; -} - -.nav-justified .nav-item { - flex-basis: 0; - flex-grow: 1; - text-align: center; -} - -.tab-content > .tab-pane { - display: none; -} -.tab-content > .active { - display: block; -} - -.navbar { - position: relative; - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; - padding: 24px 0; -} -.navbar .container, -.navbar .container-fluid, -.navbar .container-xs, -.navbar .container-sm, -.navbar .container-md, -.navbar .container-lg, -.navbar .container-xl { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: space-between; -} -.navbar-brand { - display: inline-block; - padding-top: -0.09375rem; - padding-bottom: -0.09375rem; - margin-right: 0; - font-size: 1.125rem; - line-height: inherit; - white-space: nowrap; -} -.navbar-brand:hover, .navbar-brand:focus { - text-decoration: none; -} - -.navbar-nav { - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; - list-style: none; -} -.navbar-nav .nav-link { - padding-right: 0; - padding-left: 0; -} -.navbar-nav .dropdown-menu { - position: static; - float: none; -} - -.navbar-text { - display: inline-block; - padding-top: 0; - padding-bottom: 0; -} - -.navbar-collapse { - flex-basis: 100%; - flex-grow: 1; - align-items: center; -} - -.navbar-toggler { - padding: 0.25rem 0.75rem; - font-size: 1.125rem; - line-height: 1; - background-color: transparent; - border: 1px solid transparent; - border-radius: 8px; -} -.navbar-toggler:hover, .navbar-toggler:focus { - text-decoration: none; -} - -.navbar-toggler-icon { - display: inline-block; - width: 1.5em; - height: 1.5em; - vertical-align: middle; - content: ""; - background: no-repeat center center; - background-size: 100% 100%; -} - -@media (max-width: 399.98px) { - .navbar-expand-xs > .container, -.navbar-expand-xs > .container-fluid, -.navbar-expand-xs > .container-xs, -.navbar-expand-xs > .container-sm, -.navbar-expand-xs > .container-md, -.navbar-expand-xs > .container-lg, -.navbar-expand-xs > .container-xl { - padding-right: 0; - padding-left: 0; - } -} -@media (min-width: 400px) { - .navbar-expand-xs { - flex-flow: row nowrap; - justify-content: flex-start; - } - .navbar-expand-xs .navbar-nav { - flex-direction: row; - } - .navbar-expand-xs .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-xs .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-xs > .container, -.navbar-expand-xs > .container-fluid, -.navbar-expand-xs > .container-xs, -.navbar-expand-xs > .container-sm, -.navbar-expand-xs > .container-md, -.navbar-expand-xs > .container-lg, -.navbar-expand-xs > .container-xl { - flex-wrap: nowrap; - } - .navbar-expand-xs .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-xs .navbar-toggler { - display: none; - } -} -@media (max-width: 615.98px) { - .navbar-expand-sm > .container, -.navbar-expand-sm > .container-fluid, -.navbar-expand-sm > .container-xs, -.navbar-expand-sm > .container-sm, -.navbar-expand-sm > .container-md, -.navbar-expand-sm > .container-lg, -.navbar-expand-sm > .container-xl { - padding-right: 0; - padding-left: 0; - } -} -@media (min-width: 616px) { - .navbar-expand-sm { - flex-flow: row nowrap; - justify-content: flex-start; - } - .navbar-expand-sm .navbar-nav { - flex-direction: row; - } - .navbar-expand-sm .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-sm .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-sm > .container, -.navbar-expand-sm > .container-fluid, -.navbar-expand-sm > .container-xs, -.navbar-expand-sm > .container-sm, -.navbar-expand-sm > .container-md, -.navbar-expand-sm > .container-lg, -.navbar-expand-sm > .container-xl { - flex-wrap: nowrap; - } - .navbar-expand-sm .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-sm .navbar-toggler { - display: none; - } -} -@media (max-width: 767.98px) { - .navbar-expand-md > .container, -.navbar-expand-md > .container-fluid, -.navbar-expand-md > .container-xs, -.navbar-expand-md > .container-sm, -.navbar-expand-md > .container-md, -.navbar-expand-md > .container-lg, -.navbar-expand-md > .container-xl { - padding-right: 0; - padding-left: 0; - } -} -@media (min-width: 768px) { - .navbar-expand-md { - flex-flow: row nowrap; - justify-content: flex-start; - } - .navbar-expand-md .navbar-nav { - flex-direction: row; - } - .navbar-expand-md .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-md .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-md > .container, -.navbar-expand-md > .container-fluid, -.navbar-expand-md > .container-xs, -.navbar-expand-md > .container-sm, -.navbar-expand-md > .container-md, -.navbar-expand-md > .container-lg, -.navbar-expand-md > .container-xl { - flex-wrap: nowrap; - } - .navbar-expand-md .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-md .navbar-toggler { - display: none; - } -} -@media (max-width: 979.98px) { - .navbar-expand-lg > .container, -.navbar-expand-lg > .container-fluid, -.navbar-expand-lg > .container-xs, -.navbar-expand-lg > .container-sm, -.navbar-expand-lg > .container-md, -.navbar-expand-lg > .container-lg, -.navbar-expand-lg > .container-xl { - padding-right: 0; - padding-left: 0; - } -} -@media (min-width: 980px) { - .navbar-expand-lg { - flex-flow: row nowrap; - justify-content: flex-start; - } - .navbar-expand-lg .navbar-nav { - flex-direction: row; - } - .navbar-expand-lg .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-lg .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-lg > .container, -.navbar-expand-lg > .container-fluid, -.navbar-expand-lg > .container-xs, -.navbar-expand-lg > .container-sm, -.navbar-expand-lg > .container-md, -.navbar-expand-lg > .container-lg, -.navbar-expand-lg > .container-xl { - flex-wrap: nowrap; - } - .navbar-expand-lg .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-lg .navbar-toggler { - display: none; - } -} -@media (max-width: 1239.98px) { - .navbar-expand-xl > .container, -.navbar-expand-xl > .container-fluid, -.navbar-expand-xl > .container-xs, -.navbar-expand-xl > .container-sm, -.navbar-expand-xl > .container-md, -.navbar-expand-xl > .container-lg, -.navbar-expand-xl > .container-xl { - padding-right: 0; - padding-left: 0; - } -} -@media (min-width: 1240px) { - .navbar-expand-xl { - flex-flow: row nowrap; - justify-content: flex-start; - } - .navbar-expand-xl .navbar-nav { - flex-direction: row; - } - .navbar-expand-xl .navbar-nav .dropdown-menu { - position: absolute; - } - .navbar-expand-xl .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; - } - .navbar-expand-xl > .container, -.navbar-expand-xl > .container-fluid, -.navbar-expand-xl > .container-xs, -.navbar-expand-xl > .container-sm, -.navbar-expand-xl > .container-md, -.navbar-expand-xl > .container-lg, -.navbar-expand-xl > .container-xl { - flex-wrap: nowrap; - } - .navbar-expand-xl .navbar-collapse { - display: flex !important; - flex-basis: auto; - } - .navbar-expand-xl .navbar-toggler { - display: none; - } -} -.navbar-expand { - flex-flow: row nowrap; - justify-content: flex-start; -} -.navbar-expand > .container, -.navbar-expand > .container-fluid, -.navbar-expand > .container-xs, -.navbar-expand > .container-sm, -.navbar-expand > .container-md, -.navbar-expand > .container-lg, -.navbar-expand > .container-xl { - padding-right: 0; - padding-left: 0; -} -.navbar-expand .navbar-nav { - flex-direction: row; -} -.navbar-expand .navbar-nav .dropdown-menu { - position: absolute; -} -.navbar-expand .navbar-nav .nav-link { - padding-right: 0.5rem; - padding-left: 0.5rem; -} -.navbar-expand > .container, -.navbar-expand > .container-fluid, -.navbar-expand > .container-xs, -.navbar-expand > .container-sm, -.navbar-expand > .container-md, -.navbar-expand > .container-lg, -.navbar-expand > .container-xl { - flex-wrap: nowrap; -} -.navbar-expand .navbar-collapse { - display: flex !important; - flex-basis: auto; -} -.navbar-expand .navbar-toggler { - display: none; -} - -.navbar-light .navbar-brand { - color: rgba(33, 37, 41, 0.9); -} -.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { - color: rgba(33, 37, 41, 0.9); -} -.navbar-light .navbar-nav .nav-link { - color: rgba(33, 37, 41, 0.5); -} -.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { - color: rgba(33, 37, 41, 0.7); -} -.navbar-light .navbar-nav .nav-link.disabled { - color: rgba(33, 37, 41, 0.3); -} -.navbar-light .navbar-nav .show > .nav-link, -.navbar-light .navbar-nav .active > .nav-link, -.navbar-light .navbar-nav .nav-link.show, -.navbar-light .navbar-nav .nav-link.active { - color: rgba(33, 37, 41, 0.9); -} -.navbar-light .navbar-toggler { - color: rgba(33, 37, 41, 0.5); - border-color: rgba(33, 37, 41, 0.1); -} -.navbar-light .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(33, 37, 41, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); -} -.navbar-light .navbar-text { - color: rgba(33, 37, 41, 0.5); -} -.navbar-light .navbar-text a { - color: rgba(33, 37, 41, 0.9); -} -.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus { - color: rgba(33, 37, 41, 0.9); -} - -.navbar-dark .navbar-brand { - color: #fff; -} -.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { - color: #fff; -} -.navbar-dark .navbar-nav .nav-link { - color: rgba(255, 255, 255, 0.5); -} -.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { - color: rgba(255, 255, 255, 0.75); -} -.navbar-dark .navbar-nav .nav-link.disabled { - color: rgba(255, 255, 255, 0.25); -} -.navbar-dark .navbar-nav .show > .nav-link, -.navbar-dark .navbar-nav .active > .nav-link, -.navbar-dark .navbar-nav .nav-link.show, -.navbar-dark .navbar-nav .nav-link.active { - color: #fff; -} -.navbar-dark .navbar-toggler { - color: rgba(255, 255, 255, 0.5); - border-color: rgba(255, 255, 255, 0.1); -} -.navbar-dark .navbar-toggler-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); -} -.navbar-dark .navbar-text { - color: rgba(255, 255, 255, 0.5); -} -.navbar-dark .navbar-text a { - color: #fff; -} -.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus { - color: #fff; -} - -.card { - position: relative; - display: flex; - flex-direction: column; - min-width: 0; - word-wrap: break-word; - background-color: #fff; - background-clip: border-box; - border: 1px solid #d6dbdf; - border-radius: 8px; -} -.card > hr { - margin-right: 0; - margin-left: 0; -} -.card > .list-group:first-child .list-group-item:first-child { - border-top-left-radius: 8px; - border-top-right-radius: 8px; -} -.card > .list-group:last-child .list-group-item:last-child { - border-bottom-right-radius: 8px; - border-bottom-left-radius: 8px; -} - -.card-body { - flex: 1 1 auto; - min-height: 1px; - padding: 24px; -} - -.card-title { - margin-bottom: 24px; -} - -.card-subtitle { - margin-top: -12px; - margin-bottom: 0; -} - -.card-text:last-child { - margin-bottom: 0; -} - -.card-link:hover { - text-decoration: none; -} -.card-link + .card-link { - margin-left: 24px; -} - -.card-header { - padding: 24px 24px; - margin-bottom: 0; - background-color: #f1f6f9; - border-bottom: 1px solid #d6dbdf; -} -.card-header:first-child { - border-radius: subtract(8px, 1px) subtract(8px, 1px) 0 0; -} -.card-header + .list-group .list-group-item:first-child { - border-top: 0; -} - -.card-footer { - padding: 24px 24px; - background-color: #f1f6f9; - border-top: 1px solid #d6dbdf; -} -.card-footer:last-child { - border-radius: 0 0 subtract(8px, 1px) subtract(8px, 1px); -} - -.card-header-tabs { - margin-right: -12px; - margin-bottom: -24px; - margin-left: -12px; - border-bottom: 0; -} - -.card-header-pills { - margin-right: -12px; - margin-left: -12px; -} - -.card-img-overlay { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - padding: 24px; -} - -.card-img, -.card-img-top, -.card-img-bottom { - flex-shrink: 0; - width: 100%; -} - -.card-img, -.card-img-top { - border-top-left-radius: subtract(8px, 1px); - border-top-right-radius: subtract(8px, 1px); -} - -.card-img, -.card-img-bottom { - border-bottom-right-radius: subtract(8px, 1px); - border-bottom-left-radius: subtract(8px, 1px); -} - -.card-deck .card { - margin-bottom: 20px; -} -@media (min-width: 616px) { - .card-deck { - display: flex; - flex-flow: row wrap; - margin-right: -20px; - margin-left: -20px; - } - .card-deck .card { - flex: 1 0 0%; - margin-right: 20px; - margin-bottom: 0; - margin-left: 20px; - } -} - -.card-group > .card { - margin-bottom: 20px; -} -@media (min-width: 616px) { - .card-group { - display: flex; - flex-flow: row wrap; - } - .card-group > .card { - flex: 1 0 0%; - margin-bottom: 0; - } - .card-group > .card + .card { - margin-left: 0; - border-left: 0; - } - .card-group > .card:not(:last-child) { - border-top-right-radius: 0; - border-bottom-right-radius: 0; - } - .card-group > .card:not(:last-child) .card-img-top, -.card-group > .card:not(:last-child) .card-header { - border-top-right-radius: 0; - } - .card-group > .card:not(:last-child) .card-img-bottom, -.card-group > .card:not(:last-child) .card-footer { - border-bottom-right-radius: 0; - } - .card-group > .card:not(:first-child) { - border-top-left-radius: 0; - border-bottom-left-radius: 0; - } - .card-group > .card:not(:first-child) .card-img-top, -.card-group > .card:not(:first-child) .card-header { - border-top-left-radius: 0; - } - .card-group > .card:not(:first-child) .card-img-bottom, -.card-group > .card:not(:first-child) .card-footer { - border-bottom-left-radius: 0; - } -} - -.card-columns .card { - margin-bottom: 40px; -} -@media (min-width: 616px) { - .card-columns { - -moz-column-count: 3; - column-count: 3; - -moz-column-gap: 40px; - column-gap: 40px; - orphans: 1; - widows: 1; - } - .card-columns .card { - display: inline-block; - width: 100%; - } -} - -.accordion > .card { - overflow: hidden; -} -.accordion > .card:not(:last-of-type) { - border-bottom: 0; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; -} -.accordion > .card:not(:first-of-type) { - border-top-left-radius: 0; - border-top-right-radius: 0; -} -.accordion > .card > .card-header { - border-radius: 0; - margin-bottom: -1px; -} - -.breadcrumb { - display: flex; - flex-wrap: wrap; - padding: 0.75rem 1rem; - margin-bottom: 1rem; - list-style: none; - background-color: #e9ecef; - border-radius: 8px; -} - -.breadcrumb-item + .breadcrumb-item { - padding-left: 0.5rem; -} -.breadcrumb-item + .breadcrumb-item::before { - display: inline-block; - padding-right: 0.5rem; - color: #6c757d; - content: "/"; -} -.breadcrumb-item + .breadcrumb-item:hover::before { - text-decoration: underline; -} -.breadcrumb-item + .breadcrumb-item:hover::before { - text-decoration: none; -} -.breadcrumb-item.active { - color: #6c757d; -} - -.pagination { - display: flex; - padding-left: 0; - list-style: none; - border-radius: 8px; -} - -.page-link { - position: relative; - display: block; - padding: 0.5rem 0.75rem; - margin-left: -1px; - line-height: 1.25; - color: #ff8c00; - background-color: #fff; - border: 1px solid #dee2e6; -} -.page-link:hover { - z-index: 2; - color: #ff8c00; - text-decoration: none; - background-color: #e9ecef; - border-color: #dee2e6; -} -.page-link:focus { - z-index: 3; - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.25); -} - -.page-item:first-child .page-link { - margin-left: 0; - border-top-left-radius: 8px; - border-bottom-left-radius: 8px; -} -.page-item:last-child .page-link { - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; -} -.page-item.active .page-link { - z-index: 3; - color: #fff; - background-color: #ffcc00; - border-color: #ffcc00; -} -.page-item.disabled .page-link { - color: #6c757d; - pointer-events: none; - cursor: auto; - background-color: #fff; - border-color: #dee2e6; -} - -.pagination-lg .page-link { - padding: 0.75rem 1.5rem; - font-size: 1.125rem; - line-height: 1.5; -} -.pagination-lg .page-item:first-child .page-link { - border-top-left-radius: 8px; - border-bottom-left-radius: 8px; -} -.pagination-lg .page-item:last-child .page-link { - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; -} - -.pagination-sm .page-link { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; -} -.pagination-sm .page-item:first-child .page-link { - border-top-left-radius: 8px; - border-bottom-left-radius: 8px; -} -.pagination-sm .page-item:last-child .page-link { - border-top-right-radius: 8px; - border-bottom-right-radius: 8px; -} - -.badge { - display: inline-block; - padding: 0.25em 0.4em; - font-size: 75%; - font-weight: 700; - line-height: 1; - text-align: center; - white-space: nowrap; - vertical-align: baseline; - border-radius: 8px; - transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .badge { - transition: none; - } -} -a.badge:hover, a.badge:focus { - text-decoration: none; -} - -.badge:empty { - display: none; -} - -.btn .badge { - position: relative; - top: -1px; -} - -.badge-pill { - padding-right: 0.6em; - padding-left: 0.6em; - border-radius: 10rem; -} - -.badge-primary { - color: #495057; - background-color: #ffcc00; -} -a.badge-primary:hover, a.badge-primary:focus { - color: #495057; - background-color: #cca300; -} -a.badge-primary:focus, a.badge-primary.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.5); -} - -.badge-secondary { - color: #fff; - background-color: #212529; -} -a.badge-secondary:hover, a.badge-secondary:focus { - color: #fff; - background-color: #0a0c0d; -} -a.badge-secondary:focus, a.badge-secondary.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(33, 37, 41, 0.5); -} - -.badge-success { - color: #fff; - background-color: #28a745; -} -a.badge-success:hover, a.badge-success:focus { - color: #fff; - background-color: #1e7e34; -} -a.badge-success:focus, a.badge-success.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); -} - -.badge-info { - color: #fff; - background-color: #17a2b8; -} -a.badge-info:hover, a.badge-info:focus { - color: #fff; - background-color: #117a8b; -} -a.badge-info:focus, a.badge-info.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); -} - -.badge-warning { - color: #495057; - background-color: #ffc107; -} -a.badge-warning:hover, a.badge-warning:focus { - color: #495057; - background-color: #d39e00; -} -a.badge-warning:focus, a.badge-warning.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); -} - -.badge-danger { - color: #fff; - background-color: #dc3545; -} -a.badge-danger:hover, a.badge-danger:focus { - color: #fff; - background-color: #bd2130; -} -a.badge-danger:focus, a.badge-danger.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); -} - -.badge-light { - color: #495057; - background-color: #f1f6f9; -} -a.badge-light:hover, a.badge-light:focus { - color: #495057; - background-color: #cddfea; -} -a.badge-light:focus, a.badge-light.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(241, 246, 249, 0.5); -} - -.badge-dark { - color: #fff; - background-color: #495057; -} -a.badge-dark:hover, a.badge-dark:focus { - color: #fff; - background-color: #32373b; -} -a.badge-dark:focus, a.badge-dark.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(73, 80, 87, 0.5); -} - -.badge-primary-light { - color: #495057; - background-color: #fffaf0; -} -a.badge-primary-light:hover, a.badge-primary-light:focus { - color: #495057; - background-color: #ffe9bd; -} -a.badge-primary-light:focus, a.badge-primary-light.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 250, 240, 0.5); -} - -.badge-secondary-light { - color: #495057; - background-color: #fff; -} -a.badge-secondary-light:hover, a.badge-secondary-light:focus { - color: #495057; - background-color: #e6e6e6; -} -a.badge-secondary-light:focus, a.badge-secondary-light.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.5); -} - -.badge-tertiary { - color: #fff; - background-color: #257af4; -} -a.badge-tertiary:hover, a.badge-tertiary:focus { - color: #fff; - background-color: #0b60db; -} -a.badge-tertiary:focus, a.badge-tertiary.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(37, 122, 244, 0.5); -} - -.badge-tertiary-light { - color: #495057; - background-color: #e3f1fe; -} -a.badge-tertiary-light:hover, a.badge-tertiary-light:focus { - color: #495057; - background-color: #b2d8fc; -} -a.badge-tertiary-light:focus, a.badge-tertiary-light.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(227, 241, 254, 0.5); -} - -.badge-white { - color: #495057; - background-color: #fff; -} -a.badge-white:hover, a.badge-white:focus { - color: #495057; - background-color: #e6e6e6; -} -a.badge-white:focus, a.badge-white.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 255, 255, 0.5); -} - -.badge-black { - color: #fff; - background-color: #212529; -} -a.badge-black:hover, a.badge-black:focus { - color: #fff; - background-color: #0a0c0d; -} -a.badge-black:focus, a.badge-black.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(33, 37, 41, 0.5); -} - -.badge-blue { - color: #fff; - background-color: #257af4; -} -a.badge-blue:hover, a.badge-blue:focus { - color: #fff; - background-color: #0b60db; -} -a.badge-blue:focus, a.badge-blue.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(37, 122, 244, 0.5); -} - -.badge-light-blue { - color: #495057; - background-color: #e3f1fe; -} -a.badge-light-blue:hover, a.badge-light-blue:focus { - color: #495057; - background-color: #b2d8fc; -} -a.badge-light-blue:focus, a.badge-light-blue.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(227, 241, 254, 0.5); -} - -.badge-yellow { - color: #495057; - background-color: #ffcc00; -} -a.badge-yellow:hover, a.badge-yellow:focus { - color: #495057; - background-color: #cca300; -} -a.badge-yellow:focus, a.badge-yellow.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 204, 0, 0.5); -} - -.badge-light-yellow { - color: #495057; - background-color: #fffaf0; -} -a.badge-light-yellow:hover, a.badge-light-yellow:focus { - color: #495057; - background-color: #ffe9bd; -} -a.badge-light-yellow:focus, a.badge-light-yellow.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 250, 240, 0.5); -} - -.badge-orange { - color: #495057; - background-color: #ff8c00; -} -a.badge-orange:hover, a.badge-orange:focus { - color: #495057; - background-color: #cc7000; -} -a.badge-orange:focus, a.badge-orange.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 140, 0, 0.5); -} - -.badge-light-orange { - color: #495057; - background-color: #ffe4b5; -} -a.badge-light-orange:hover, a.badge-light-orange:focus { - color: #495057; - background-color: #ffd182; -} -a.badge-light-orange:focus, a.badge-light-orange.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 228, 181, 0.5); -} - -.badge-red { - color: #fff; - background-color: #ff3939; -} -a.badge-red:hover, a.badge-red:focus { - color: #fff; - background-color: #ff0606; -} -a.badge-red:focus, a.badge-red.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 57, 57, 0.5); -} - -.badge-light-red { - color: #495057; - background-color: #ffe4e1; -} -a.badge-light-red:hover, a.badge-light-red:focus { - color: #495057; - background-color: #ffb6ae; -} -a.badge-light-red:focus, a.badge-light-red.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(255, 228, 225, 0.5); -} - -.badge-medium { - color: #495057; - background-color: #d6dbdf; -} -a.badge-medium:hover, a.badge-medium:focus { - color: #495057; - background-color: #b9c2c9; -} -a.badge-medium:focus, a.badge-medium.focus { - outline: 0; - box-shadow: 0 0 0 0.2rem rgba(214, 219, 223, 0.5); -} - -.jumbotron { - padding: 2rem 1rem; - margin-bottom: 2rem; - background-color: #e9ecef; - border-radius: 8px; -} -@media (min-width: 616px) { - .jumbotron { - padding: 4rem 2rem; - } -} - -.jumbotron-fluid { - padding-right: 0; - padding-left: 0; - border-radius: 0; -} - -.alert { - position: relative; - padding: 0.75rem 1.25rem; - margin-bottom: 1rem; - border: 1px solid transparent; - border-radius: 8px; -} - -.alert-heading { - color: inherit; -} - -.alert-link { - font-weight: 700; -} - -.alert-dismissible { - padding-right: 4rem; -} -.alert-dismissible .close { - position: absolute; - top: 0; - right: 0; - padding: 0.75rem 1.25rem; - color: inherit; -} - -.alert-primary { - color: #947c14; - background-color: #fff5cc; - border-color: #fff1b8; -} -.alert-primary hr { - border-top-color: #ffec9f; -} -.alert-primary .alert-link { - color: #67560e; -} - -.alert-secondary { - color: #212529; - background-color: #d3d3d4; - border-color: #c1c2c3; -} -.alert-secondary hr { - border-top-color: #b4b5b6; -} -.alert-secondary .alert-link { - color: #0a0c0d; -} - -.alert-success { - color: #256938; - background-color: #d4edda; - border-color: #c3e6cb; -} -.alert-success hr { - border-top-color: #b1dfbb; -} -.alert-success .alert-link { - color: #184324; -} - -.alert-info { - color: #1c6673; - background-color: #d1ecf1; - border-color: #bee5eb; -} -.alert-info hr { - border-top-color: #abdde5; -} -.alert-info .alert-link { - color: #12424a; -} - -.alert-warning { - color: #947617; - background-color: #fff3cd; - border-color: #ffeeba; -} -.alert-warning hr { - border-top-color: #ffe8a1; -} -.alert-warning .alert-link { - color: #685310; -} - -.alert-danger { - color: #822d38; - background-color: #f8d7da; - border-color: #f5c6cb; -} -.alert-danger hr { - border-top-color: #f1b0b7; -} -.alert-danger .alert-link { - color: #5c2028; -} - -.alert-light { - color: #8d9295; - background-color: #fcfdfe; - border-color: #fbfcfd; -} -.alert-light hr { - border-top-color: #eaeff5; -} -.alert-light .alert-link { - color: #73797c; -} - -.alert-dark { - color: #363b41; - background-color: #dbdcdd; - border-color: #ccced0; -} -.alert-dark hr { - border-top-color: #bfc1c4; -} -.alert-dark .alert-link { - color: #1f2225; -} - -.alert-primary-light { - color: #949490; - background-color: #fffefc; - border-color: #fffefb; -} -.alert-primary-light hr { - border-top-color: #fff8e2; -} -.alert-primary-light .alert-link { - color: #7b7b76; -} - -.alert-secondary-light { - color: #949698; - background-color: white; - border-color: white; -} -.alert-secondary-light hr { - border-top-color: #f2f2f2; -} -.alert-secondary-light .alert-link { - color: #7a7d7f; -} - -.alert-tertiary { - color: #235193; - background-color: #d3e4fd; - border-color: #c2dafc; -} -.alert-tertiary hr { - border-top-color: #aacbfb; -} -.alert-tertiary .alert-link { - color: #193a6a; -} - -.alert-tertiary-light { - color: #868f98; - background-color: #f9fcff; - border-color: #f7fbff; -} -.alert-tertiary-light hr { - border-top-color: #deeeff; -} -.alert-tertiary-light .alert-link { - color: #6c767f; -} - -.alert-white { - color: #949698; - background-color: white; - border-color: white; -} -.alert-white hr { - border-top-color: #f2f2f2; -} -.alert-white .alert-link { - color: #7a7d7f; -} - -.alert-black { - color: #212529; - background-color: #d3d3d4; - border-color: #c1c2c3; -} -.alert-black hr { - border-top-color: #b4b5b6; -} -.alert-black .alert-link { - color: #0a0c0d; -} - -.alert-blue { - color: #235193; - background-color: #d3e4fd; - border-color: #c2dafc; -} -.alert-blue hr { - border-top-color: #aacbfb; -} -.alert-blue .alert-link { - color: #193a6a; -} - -.alert-light-blue { - color: #868f98; - background-color: #f9fcff; - border-color: #f7fbff; -} -.alert-light-blue hr { - border-top-color: #deeeff; -} -.alert-light-blue .alert-link { - color: #6c767f; -} - -.alert-yellow { - color: #947c14; - background-color: #fff5cc; - border-color: #fff1b8; -} -.alert-yellow hr { - border-top-color: #ffec9f; -} -.alert-yellow .alert-link { - color: #67560e; -} - -.alert-light-yellow { - color: #949490; - background-color: #fffefc; - border-color: #fffefb; -} -.alert-light-yellow hr { - border-top-color: #fff8e2; -} -.alert-light-yellow .alert-link { - color: #7b7b76; -} - -.alert-orange { - color: #945b14; - background-color: #ffe8cc; - border-color: #ffdfb8; -} -.alert-orange hr { - border-top-color: #ffd49f; -} -.alert-orange .alert-link { - color: #673f0e; -} - -.alert-light-orange { - color: #948872; - background-color: floralwhite; - border-color: #fff7ea; -} -.alert-light-orange hr { - border-top-color: #ffedd1; -} -.alert-light-orange .alert-link { - color: #786e5b; -} - -.alert-red { - color: #942f31; - background-color: #ffd7d7; - border-color: #ffc8c8; -} -.alert-red hr { - border-top-color: #ffafaf; -} -.alert-red .alert-link { - color: #6d2324; -} - -.alert-light-red { - color: #948889; - background-color: #fffaf9; - border-color: #fff7f7; -} -.alert-light-red hr { - border-top-color: #ffdede; -} -.alert-light-red .alert-link { - color: #7b6e6f; -} - -.alert-medium { - color: #7f8488; - background-color: #f7f8f9; - border-color: #f4f5f6; -} -.alert-medium hr { - border-top-color: #e6e8eb; -} -.alert-medium .alert-link { - color: #666a6e; -} - -@-webkit-keyframes progress-bar-stripes { - from { - background-position: 1rem 0; - } - to { - background-position: 0 0; - } -} - -@keyframes progress-bar-stripes { - from { - background-position: 1rem 0; - } - to { - background-position: 0 0; - } -} -.progress { - display: flex; - height: 1rem; - overflow: hidden; - font-size: 0.75rem; - background-color: #e9ecef; - border-radius: 8px; -} - -.progress-bar { - display: flex; - flex-direction: column; - justify-content: center; - overflow: hidden; - color: #fff; - text-align: center; - white-space: nowrap; - background-color: #ffcc00; - transition: width 0.6s ease; -} -@media (prefers-reduced-motion: reduce) { - .progress-bar { - transition: none; - } -} - -.progress-bar-striped { - background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); - background-size: 1rem 1rem; -} - -.progress-bar-animated { - -webkit-animation: progress-bar-stripes 1s linear infinite; - animation: progress-bar-stripes 1s linear infinite; -} -@media (prefers-reduced-motion: reduce) { - .progress-bar-animated { - -webkit-animation: none; - animation: none; - } -} - -.media { - display: flex; - align-items: flex-start; -} - -.media-body { - flex: 1; -} - -.list-group { - display: flex; - flex-direction: column; - padding-left: 0; - margin-bottom: 0; -} - -.list-group-item-action { - width: 100%; - color: #6c757d; - text-align: inherit; -} -.list-group-item-action:hover, .list-group-item-action:focus { - z-index: 1; - color: #6c757d; - text-decoration: none; - background-color: #f1f6f9; -} -.list-group-item-action:active { - color: #212529; - background-color: #e9ecef; -} - -.list-group-item { - position: relative; - display: block; - padding: 0.75rem 1.25rem; - background-color: #fff; - border: 1px solid rgba(33, 37, 41, 0.125); -} -.list-group-item:first-child { - border-top-left-radius: 8px; - border-top-right-radius: 8px; -} -.list-group-item:last-child { - border-bottom-right-radius: 8px; - border-bottom-left-radius: 8px; -} -.list-group-item.disabled, .list-group-item:disabled { - color: #6c757d; - pointer-events: none; - background-color: #fff; -} -.list-group-item.active { - z-index: 2; - color: #fff; - background-color: #ffcc00; - border-color: #ffcc00; -} -.list-group-item + .list-group-item { - border-top-width: 0; -} -.list-group-item + .list-group-item.active { - margin-top: -1px; - border-top-width: 1px; -} - -.list-group-horizontal { - flex-direction: row; -} -.list-group-horizontal .list-group-item:first-child { - border-bottom-left-radius: 8px; - border-top-right-radius: 0; -} -.list-group-horizontal .list-group-item:last-child { - border-top-right-radius: 8px; - border-bottom-left-radius: 0; -} -.list-group-horizontal .list-group-item.active { - margin-top: 0; -} -.list-group-horizontal .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; -} -.list-group-horizontal .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; -} - -@media (min-width: 400px) { - .list-group-horizontal-xs { - flex-direction: row; - } - .list-group-horizontal-xs .list-group-item:first-child { - border-bottom-left-radius: 8px; - border-top-right-radius: 0; - } - .list-group-horizontal-xs .list-group-item:last-child { - border-top-right-radius: 8px; - border-bottom-left-radius: 0; - } - .list-group-horizontal-xs .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-xs .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-xs .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 616px) { - .list-group-horizontal-sm { - flex-direction: row; - } - .list-group-horizontal-sm .list-group-item:first-child { - border-bottom-left-radius: 8px; - border-top-right-radius: 0; - } - .list-group-horizontal-sm .list-group-item:last-child { - border-top-right-radius: 8px; - border-bottom-left-radius: 0; - } - .list-group-horizontal-sm .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-sm .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-sm .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 768px) { - .list-group-horizontal-md { - flex-direction: row; - } - .list-group-horizontal-md .list-group-item:first-child { - border-bottom-left-radius: 8px; - border-top-right-radius: 0; - } - .list-group-horizontal-md .list-group-item:last-child { - border-top-right-radius: 8px; - border-bottom-left-radius: 0; - } - .list-group-horizontal-md .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-md .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-md .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 980px) { - .list-group-horizontal-lg { - flex-direction: row; - } - .list-group-horizontal-lg .list-group-item:first-child { - border-bottom-left-radius: 8px; - border-top-right-radius: 0; - } - .list-group-horizontal-lg .list-group-item:last-child { - border-top-right-radius: 8px; - border-bottom-left-radius: 0; - } - .list-group-horizontal-lg .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-lg .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-lg .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -@media (min-width: 1240px) { - .list-group-horizontal-xl { - flex-direction: row; - } - .list-group-horizontal-xl .list-group-item:first-child { - border-bottom-left-radius: 8px; - border-top-right-radius: 0; - } - .list-group-horizontal-xl .list-group-item:last-child { - border-top-right-radius: 8px; - border-bottom-left-radius: 0; - } - .list-group-horizontal-xl .list-group-item.active { - margin-top: 0; - } - .list-group-horizontal-xl .list-group-item + .list-group-item { - border-top-width: 1px; - border-left-width: 0; - } - .list-group-horizontal-xl .list-group-item + .list-group-item.active { - margin-left: -1px; - border-left-width: 1px; - } -} -.list-group-flush .list-group-item { - border-right-width: 0; - border-left-width: 0; - border-radius: 0; -} -.list-group-flush .list-group-item:first-child { - border-top-width: 0; -} -.list-group-flush:last-child .list-group-item:last-child { - border-bottom-width: 0; -} - -.list-group-item-primary { - color: #947c14; - background-color: #fff1b8; -} -.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { - color: #947c14; - background-color: #ffec9f; -} -.list-group-item-primary.list-group-item-action.active { - color: #fff; - background-color: #947c14; - border-color: #947c14; -} - -.list-group-item-secondary { - color: #212529; - background-color: #c1c2c3; -} -.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { - color: #212529; - background-color: #b4b5b6; -} -.list-group-item-secondary.list-group-item-action.active { - color: #fff; - background-color: #212529; - border-color: #212529; -} - -.list-group-item-success { - color: #256938; - background-color: #c3e6cb; -} -.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { - color: #256938; - background-color: #b1dfbb; -} -.list-group-item-success.list-group-item-action.active { - color: #fff; - background-color: #256938; - border-color: #256938; -} - -.list-group-item-info { - color: #1c6673; - background-color: #bee5eb; -} -.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { - color: #1c6673; - background-color: #abdde5; -} -.list-group-item-info.list-group-item-action.active { - color: #fff; - background-color: #1c6673; - border-color: #1c6673; -} - -.list-group-item-warning { - color: #947617; - background-color: #ffeeba; -} -.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { - color: #947617; - background-color: #ffe8a1; -} -.list-group-item-warning.list-group-item-action.active { - color: #fff; - background-color: #947617; - border-color: #947617; -} - -.list-group-item-danger { - color: #822d38; - background-color: #f5c6cb; -} -.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { - color: #822d38; - background-color: #f1b0b7; -} -.list-group-item-danger.list-group-item-action.active { - color: #fff; - background-color: #822d38; - border-color: #822d38; -} - -.list-group-item-light { - color: #8d9295; - background-color: #fbfcfd; -} -.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { - color: #8d9295; - background-color: #eaeff5; -} -.list-group-item-light.list-group-item-action.active { - color: #fff; - background-color: #8d9295; - border-color: #8d9295; -} - -.list-group-item-dark { - color: #363b41; - background-color: #ccced0; -} -.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { - color: #363b41; - background-color: #bfc1c4; -} -.list-group-item-dark.list-group-item-action.active { - color: #fff; - background-color: #363b41; - border-color: #363b41; -} - -.list-group-item-primary-light { - color: #949490; - background-color: #fffefb; -} -.list-group-item-primary-light.list-group-item-action:hover, .list-group-item-primary-light.list-group-item-action:focus { - color: #949490; - background-color: #fff8e2; -} -.list-group-item-primary-light.list-group-item-action.active { - color: #fff; - background-color: #949490; - border-color: #949490; -} - -.list-group-item-secondary-light { - color: #949698; - background-color: white; -} -.list-group-item-secondary-light.list-group-item-action:hover, .list-group-item-secondary-light.list-group-item-action:focus { - color: #949698; - background-color: #f2f2f2; -} -.list-group-item-secondary-light.list-group-item-action.active { - color: #fff; - background-color: #949698; - border-color: #949698; -} - -.list-group-item-tertiary { - color: #235193; - background-color: #c2dafc; -} -.list-group-item-tertiary.list-group-item-action:hover, .list-group-item-tertiary.list-group-item-action:focus { - color: #235193; - background-color: #aacbfb; -} -.list-group-item-tertiary.list-group-item-action.active { - color: #fff; - background-color: #235193; - border-color: #235193; -} - -.list-group-item-tertiary-light { - color: #868f98; - background-color: #f7fbff; -} -.list-group-item-tertiary-light.list-group-item-action:hover, .list-group-item-tertiary-light.list-group-item-action:focus { - color: #868f98; - background-color: #deeeff; -} -.list-group-item-tertiary-light.list-group-item-action.active { - color: #fff; - background-color: #868f98; - border-color: #868f98; -} - -.list-group-item-white { - color: #949698; - background-color: white; -} -.list-group-item-white.list-group-item-action:hover, .list-group-item-white.list-group-item-action:focus { - color: #949698; - background-color: #f2f2f2; -} -.list-group-item-white.list-group-item-action.active { - color: #fff; - background-color: #949698; - border-color: #949698; -} - -.list-group-item-black { - color: #212529; - background-color: #c1c2c3; -} -.list-group-item-black.list-group-item-action:hover, .list-group-item-black.list-group-item-action:focus { - color: #212529; - background-color: #b4b5b6; -} -.list-group-item-black.list-group-item-action.active { - color: #fff; - background-color: #212529; - border-color: #212529; -} - -.list-group-item-blue { - color: #235193; - background-color: #c2dafc; -} -.list-group-item-blue.list-group-item-action:hover, .list-group-item-blue.list-group-item-action:focus { - color: #235193; - background-color: #aacbfb; -} -.list-group-item-blue.list-group-item-action.active { - color: #fff; - background-color: #235193; - border-color: #235193; -} - -.list-group-item-light-blue { - color: #868f98; - background-color: #f7fbff; -} -.list-group-item-light-blue.list-group-item-action:hover, .list-group-item-light-blue.list-group-item-action:focus { - color: #868f98; - background-color: #deeeff; -} -.list-group-item-light-blue.list-group-item-action.active { - color: #fff; - background-color: #868f98; - border-color: #868f98; -} - -.list-group-item-yellow { - color: #947c14; - background-color: #fff1b8; -} -.list-group-item-yellow.list-group-item-action:hover, .list-group-item-yellow.list-group-item-action:focus { - color: #947c14; - background-color: #ffec9f; -} -.list-group-item-yellow.list-group-item-action.active { - color: #fff; - background-color: #947c14; - border-color: #947c14; -} - -.list-group-item-light-yellow { - color: #949490; - background-color: #fffefb; -} -.list-group-item-light-yellow.list-group-item-action:hover, .list-group-item-light-yellow.list-group-item-action:focus { - color: #949490; - background-color: #fff8e2; -} -.list-group-item-light-yellow.list-group-item-action.active { - color: #fff; - background-color: #949490; - border-color: #949490; -} - -.list-group-item-orange { - color: #945b14; - background-color: #ffdfb8; -} -.list-group-item-orange.list-group-item-action:hover, .list-group-item-orange.list-group-item-action:focus { - color: #945b14; - background-color: #ffd49f; -} -.list-group-item-orange.list-group-item-action.active { - color: #fff; - background-color: #945b14; - border-color: #945b14; -} - -.list-group-item-light-orange { - color: #948872; - background-color: #fff7ea; -} -.list-group-item-light-orange.list-group-item-action:hover, .list-group-item-light-orange.list-group-item-action:focus { - color: #948872; - background-color: #ffedd1; -} -.list-group-item-light-orange.list-group-item-action.active { - color: #fff; - background-color: #948872; - border-color: #948872; -} - -.list-group-item-red { - color: #942f31; - background-color: #ffc8c8; -} -.list-group-item-red.list-group-item-action:hover, .list-group-item-red.list-group-item-action:focus { - color: #942f31; - background-color: #ffafaf; -} -.list-group-item-red.list-group-item-action.active { - color: #fff; - background-color: #942f31; - border-color: #942f31; -} - -.list-group-item-light-red { - color: #948889; - background-color: #fff7f7; -} -.list-group-item-light-red.list-group-item-action:hover, .list-group-item-light-red.list-group-item-action:focus { - color: #948889; - background-color: #ffdede; -} -.list-group-item-light-red.list-group-item-action.active { - color: #fff; - background-color: #948889; - border-color: #948889; -} - -.list-group-item-medium { - color: #7f8488; - background-color: #f4f5f6; -} -.list-group-item-medium.list-group-item-action:hover, .list-group-item-medium.list-group-item-action:focus { - color: #7f8488; - background-color: #e6e8eb; -} -.list-group-item-medium.list-group-item-action.active { - color: #fff; - background-color: #7f8488; - border-color: #7f8488; -} - -.close { - float: right; - font-size: 1.5rem; - font-weight: 700; - line-height: 1; - color: #212529; - text-shadow: 0 1px 0 #fff; - opacity: 0.5; -} -@media (max-width: 1200px) { - .close { - font-size: calc(1.275rem + 0.3vw); - } -} -.close:hover { - color: #212529; - text-decoration: none; -} -.close:not(:disabled):not(.disabled):hover, .close:not(:disabled):not(.disabled):focus { - opacity: 0.75; -} - -button.close { - padding: 0; - background-color: transparent; - border: 0; - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} - -a.close.disabled { - pointer-events: none; -} - -.toast { - max-width: 350px; - overflow: hidden; - font-size: 0.875rem; - background-color: rgba(255, 255, 255, 0.85); - background-clip: padding-box; - border: 1px solid rgba(0, 0, 0, 0.1); - box-shadow: 0 0.25rem 0.75rem rgba(33, 37, 41, 0.1); - -webkit-backdrop-filter: blur(10px); - backdrop-filter: blur(10px); - opacity: 0; - border-radius: 0.25rem; -} -.toast:not(:last-child) { - margin-bottom: 0.75rem; -} -.toast.showing { - opacity: 1; -} -.toast.show { - display: block; - opacity: 1; -} -.toast.hide { - display: none; -} - -.toast-header { - display: flex; - align-items: center; - padding: 0.25rem 0.75rem; - color: #6c757d; - background-color: rgba(255, 255, 255, 0.85); - background-clip: padding-box; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); -} - -.toast-body { - padding: 0.75rem; -} - -.modal-open { - overflow: hidden; -} -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto; -} - -.modal { - position: fixed; - top: 0; - left: 0; - z-index: 1050; - display: none; - width: 100%; - height: 100%; - overflow: hidden; - outline: 0; -} - -.modal-dialog { - position: relative; - width: auto; - margin: 0.5rem; - pointer-events: none; -} -.modal.fade .modal-dialog { - transition: transform 0.3s ease-out; - transform: translate(0, -50px); -} -@media (prefers-reduced-motion: reduce) { - .modal.fade .modal-dialog { - transition: none; - } -} -.modal.show .modal-dialog { - transform: none; -} -.modal.modal-static .modal-dialog { - transform: scale(1.02); -} - -.modal-dialog-scrollable { - display: flex; - max-height: calc(100% - 1rem); -} -.modal-dialog-scrollable .modal-content { - max-height: calc(100vh - 1rem); - overflow: hidden; -} -.modal-dialog-scrollable .modal-header, -.modal-dialog-scrollable .modal-footer { - flex-shrink: 0; -} -.modal-dialog-scrollable .modal-body { - overflow-y: auto; -} - -.modal-dialog-centered { - display: flex; - align-items: center; - min-height: calc(100% - 1rem); -} -.modal-dialog-centered::before { - display: block; - height: calc(100vh - 1rem); - content: ""; -} -.modal-dialog-centered.modal-dialog-scrollable { - flex-direction: column; - justify-content: center; - height: 100%; -} -.modal-dialog-centered.modal-dialog-scrollable .modal-content { - max-height: none; -} -.modal-dialog-centered.modal-dialog-scrollable::before { - content: none; -} - -.modal-content { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - pointer-events: auto; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(33, 37, 41, 0.2); - border-radius: 8px; - outline: 0; -} - -.modal-backdrop { - position: fixed; - top: 0; - left: 0; - z-index: 1040; - width: 100vw; - height: 100vh; - background-color: #212529; -} -.modal-backdrop.fade { - opacity: 0; -} -.modal-backdrop.show { - opacity: 0.5; -} - -.modal-header { - display: flex; - align-items: flex-start; - justify-content: space-between; - padding: 1rem 1rem; - border-bottom: 1px solid #d6dbdf; - border-top-left-radius: 7px; - border-top-right-radius: 7px; -} -.modal-header .close { - padding: 1rem 1rem; - margin: -1rem -1rem -1rem auto; -} - -.modal-title { - margin-bottom: 0; - line-height: 1.5; -} - -.modal-body { - position: relative; - flex: 1 1 auto; - padding: 1rem; -} - -.modal-footer { - display: flex; - flex-wrap: wrap; - align-items: center; - justify-content: flex-end; - padding: 0.75rem; - border-top: 1px solid #d6dbdf; - border-bottom-right-radius: 7px; - border-bottom-left-radius: 7px; -} -.modal-footer > * { - margin: 0.25rem; -} - -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} - -@media (min-width: 616px) { - .modal-dialog { - max-width: 500px; - margin: 1.75rem auto; - } - - .modal-dialog-scrollable { - max-height: calc(100% - 3.5rem); - } - .modal-dialog-scrollable .modal-content { - max-height: calc(100vh - 3.5rem); - } - - .modal-dialog-centered { - min-height: calc(100% - 3.5rem); - } - .modal-dialog-centered::before { - height: calc(100vh - 3.5rem); - } - - .modal-sm { - max-width: 300px; - } -} -@media (min-width: 980px) { - .modal-lg, -.modal-xl { - max-width: 800px; - } -} -@media (min-width: 1240px) { - .modal-xl { - max-width: 1140px; - } -} -.tooltip { - position: absolute; - z-index: 1070; - display: block; - margin: 0; - font-family: "Noto Sans", sans-serif; - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - white-space: normal; - line-break: auto; - font-size: 0.875rem; - word-wrap: break-word; - opacity: 0; -} -.tooltip.show { - opacity: 0.9; -} -.tooltip .arrow { - position: absolute; - display: block; - width: 0.8rem; - height: 0.4rem; -} -.tooltip .arrow::before { - position: absolute; - content: ""; - border-color: transparent; - border-style: solid; -} - -.bs-tooltip-top, .bs-tooltip-auto[x-placement^=top] { - padding: 0.4rem 0; -} -.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^=top] .arrow { - bottom: 0; -} -.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^=top] .arrow::before { - top: 0; - border-width: 0.4rem 0.4rem 0; - border-top-color: #212529; -} - -.bs-tooltip-right, .bs-tooltip-auto[x-placement^=right] { - padding: 0 0.4rem; -} -.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^=right] .arrow { - left: 0; - width: 0.4rem; - height: 0.8rem; -} -.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^=right] .arrow::before { - right: 0; - border-width: 0.4rem 0.4rem 0.4rem 0; - border-right-color: #212529; -} - -.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^=bottom] { - padding: 0.4rem 0; -} -.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^=bottom] .arrow { - top: 0; -} -.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^=bottom] .arrow::before { - bottom: 0; - border-width: 0 0.4rem 0.4rem; - border-bottom-color: #212529; -} - -.bs-tooltip-left, .bs-tooltip-auto[x-placement^=left] { - padding: 0 0.4rem; -} -.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^=left] .arrow { - right: 0; - width: 0.4rem; - height: 0.8rem; -} -.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^=left] .arrow::before { - left: 0; - border-width: 0.4rem 0 0.4rem 0.4rem; - border-left-color: #212529; -} - -.tooltip-inner { - max-width: 200px; - padding: 0.25rem 0.5rem; - color: #fff; - text-align: center; - background-color: #212529; - border-radius: 8px; -} - -.popover { - position: absolute; - top: 0; - left: 0; - z-index: 1060; - display: block; - max-width: 276px; - font-family: "Noto Sans", sans-serif; - font-style: normal; - font-weight: 400; - line-height: 1.5; - text-align: left; - text-align: start; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-break: normal; - word-spacing: normal; - white-space: normal; - line-break: auto; - font-size: 0.875rem; - word-wrap: break-word; - background-color: #fff; - background-clip: padding-box; - border: 1px solid rgba(33, 37, 41, 0.2); - border-radius: 8px; -} -.popover .arrow { - position: absolute; - display: block; - width: 1rem; - height: 0.5rem; - margin: 0 8px; -} -.popover .arrow::before, .popover .arrow::after { - position: absolute; - display: block; - content: ""; - border-color: transparent; - border-style: solid; -} - -.bs-popover-top, .bs-popover-auto[x-placement^=top] { - margin-bottom: 0.5rem; -} -.bs-popover-top > .arrow, .bs-popover-auto[x-placement^=top] > .arrow { - bottom: calc(-0.5rem - 1px); -} -.bs-popover-top > .arrow::before, .bs-popover-auto[x-placement^=top] > .arrow::before { - bottom: 0; - border-width: 0.5rem 0.5rem 0; - border-top-color: rgba(33, 37, 41, 0.25); -} -.bs-popover-top > .arrow::after, .bs-popover-auto[x-placement^=top] > .arrow::after { - bottom: 1px; - border-width: 0.5rem 0.5rem 0; - border-top-color: #fff; -} - -.bs-popover-right, .bs-popover-auto[x-placement^=right] { - margin-left: 0.5rem; -} -.bs-popover-right > .arrow, .bs-popover-auto[x-placement^=right] > .arrow { - left: calc(-0.5rem - 1px); - width: 0.5rem; - height: 1rem; - margin: 8px 0; -} -.bs-popover-right > .arrow::before, .bs-popover-auto[x-placement^=right] > .arrow::before { - left: 0; - border-width: 0.5rem 0.5rem 0.5rem 0; - border-right-color: rgba(33, 37, 41, 0.25); -} -.bs-popover-right > .arrow::after, .bs-popover-auto[x-placement^=right] > .arrow::after { - left: 1px; - border-width: 0.5rem 0.5rem 0.5rem 0; - border-right-color: #fff; -} - -.bs-popover-bottom, .bs-popover-auto[x-placement^=bottom] { - margin-top: 0.5rem; -} -.bs-popover-bottom > .arrow, .bs-popover-auto[x-placement^=bottom] > .arrow { - top: calc(-0.5rem - 1px); -} -.bs-popover-bottom > .arrow::before, .bs-popover-auto[x-placement^=bottom] > .arrow::before { - top: 0; - border-width: 0 0.5rem 0.5rem 0.5rem; - border-bottom-color: rgba(33, 37, 41, 0.25); -} -.bs-popover-bottom > .arrow::after, .bs-popover-auto[x-placement^=bottom] > .arrow::after { - top: 1px; - border-width: 0 0.5rem 0.5rem 0.5rem; - border-bottom-color: #fff; -} -.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^=bottom] .popover-header::before { - position: absolute; - top: 0; - left: 50%; - display: block; - width: 1rem; - margin-left: -0.5rem; - content: ""; - border-bottom: 1px solid #f7f7f7; -} - -.bs-popover-left, .bs-popover-auto[x-placement^=left] { - margin-right: 0.5rem; -} -.bs-popover-left > .arrow, .bs-popover-auto[x-placement^=left] > .arrow { - right: calc(-0.5rem - 1px); - width: 0.5rem; - height: 1rem; - margin: 8px 0; -} -.bs-popover-left > .arrow::before, .bs-popover-auto[x-placement^=left] > .arrow::before { - right: 0; - border-width: 0.5rem 0 0.5rem 0.5rem; - border-left-color: rgba(33, 37, 41, 0.25); -} -.bs-popover-left > .arrow::after, .bs-popover-auto[x-placement^=left] > .arrow::after { - right: 1px; - border-width: 0.5rem 0 0.5rem 0.5rem; - border-left-color: #fff; -} - -.popover-header { - padding: 0.5rem 0.75rem; - margin-bottom: 0; - font-size: 1rem; - background-color: #f7f7f7; - border-bottom: 1px solid #ebebeb; - border-top-left-radius: 7px; - border-top-right-radius: 7px; -} -.popover-header:empty { - display: none; -} - -.popover-body { - padding: 0.5rem 0.75rem; - color: #212529; -} - -.carousel { - position: relative; -} - -.carousel.pointer-event { - touch-action: pan-y; -} - -.carousel-inner { - position: relative; - width: 100%; - overflow: hidden; -} -.carousel-inner::after { - display: block; - clear: both; - content: ""; -} - -.carousel-item { - position: relative; - display: none; - float: left; - width: 100%; - margin-right: -100%; - -webkit-backface-visibility: hidden; - backface-visibility: hidden; - transition: transform 0.6s ease-in-out; -} -@media (prefers-reduced-motion: reduce) { - .carousel-item { - transition: none; - } -} - -.carousel-item.active, -.carousel-item-next, -.carousel-item-prev { - display: block; -} - -.carousel-item-next:not(.carousel-item-left), -.active.carousel-item-right { - transform: translateX(100%); -} - -.carousel-item-prev:not(.carousel-item-right), -.active.carousel-item-left { - transform: translateX(-100%); -} - -.carousel-fade .carousel-item { - opacity: 0; - transition-property: opacity; - transform: none; -} -.carousel-fade .carousel-item.active, -.carousel-fade .carousel-item-next.carousel-item-left, -.carousel-fade .carousel-item-prev.carousel-item-right { - z-index: 1; - opacity: 1; -} -.carousel-fade .active.carousel-item-left, -.carousel-fade .active.carousel-item-right { - z-index: 0; - opacity: 0; - transition: opacity 0s 0.6s; -} -@media (prefers-reduced-motion: reduce) { - .carousel-fade .active.carousel-item-left, -.carousel-fade .active.carousel-item-right { - transition: none; - } -} - -.carousel-control-prev, -.carousel-control-next { - position: absolute; - top: 0; - bottom: 0; - z-index: 1; - display: flex; - align-items: center; - justify-content: center; - width: 15%; - color: #fff; - text-align: center; - opacity: 0.5; - transition: opacity 0.15s ease; -} -@media (prefers-reduced-motion: reduce) { - .carousel-control-prev, -.carousel-control-next { - transition: none; - } -} -.carousel-control-prev:hover, .carousel-control-prev:focus, -.carousel-control-next:hover, -.carousel-control-next:focus { - color: #fff; - text-decoration: none; - outline: 0; - opacity: 0.9; -} - -.carousel-control-prev { - left: 0; -} - -.carousel-control-next { - right: 0; -} - -.carousel-control-prev-icon, -.carousel-control-next-icon { - display: inline-block; - width: 20px; - height: 20px; - background: no-repeat 50%/100% 100%; -} - -.carousel-control-prev-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e"); -} - -.carousel-control-next-icon { - background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e"); -} - -.carousel-indicators { - position: absolute; - right: 0; - bottom: 0; - left: 0; - z-index: 15; - display: flex; - justify-content: center; - padding-left: 0; - margin-right: 15%; - margin-left: 15%; - list-style: none; -} -.carousel-indicators li { - box-sizing: content-box; - flex: 0 1 auto; - width: 30px; - height: 3px; - margin-right: 3px; - margin-left: 3px; - text-indent: -999px; - cursor: pointer; - background-color: #fff; - background-clip: padding-box; - border-top: 10px solid transparent; - border-bottom: 10px solid transparent; - opacity: 0.5; - transition: opacity 0.6s ease; -} -@media (prefers-reduced-motion: reduce) { - .carousel-indicators li { - transition: none; - } -} -.carousel-indicators .active { - opacity: 1; -} - -.carousel-caption { - position: absolute; - right: 15%; - bottom: 20px; - left: 15%; - z-index: 10; - padding-top: 20px; - padding-bottom: 20px; - color: #fff; - text-align: center; -} - -@-webkit-keyframes spinner-border { - to { - transform: rotate(360deg); - } -} - -@keyframes spinner-border { - to { - transform: rotate(360deg); - } -} -.spinner-border { - display: inline-block; - width: 2rem; - height: 2rem; - vertical-align: text-bottom; - border: 0.25em solid currentColor; - border-right-color: transparent; - border-radius: 50%; - -webkit-animation: spinner-border 0.75s linear infinite; - animation: spinner-border 0.75s linear infinite; -} - -.spinner-border-sm { - width: 1rem; - height: 1rem; - border-width: 0.2em; -} - -@-webkit-keyframes spinner-grow { - 0% { - transform: scale(0); - } - 50% { - opacity: 1; - } -} - -@keyframes spinner-grow { - 0% { - transform: scale(0); - } - 50% { - opacity: 1; - } -} -.spinner-grow { - display: inline-block; - width: 2rem; - height: 2rem; - vertical-align: text-bottom; - background-color: currentColor; - border-radius: 50%; - opacity: 0; - -webkit-animation: spinner-grow 0.75s linear infinite; - animation: spinner-grow 0.75s linear infinite; -} - -.spinner-grow-sm { - width: 1rem; - height: 1rem; -} - -.align-baseline { - vertical-align: baseline !important; -} - -.align-top { - vertical-align: top !important; -} - -.align-middle { - vertical-align: middle !important; -} - -.align-bottom { - vertical-align: bottom !important; -} - -.align-text-bottom { - vertical-align: text-bottom !important; -} - -.align-text-top { - vertical-align: text-top !important; -} - -.bg-primary { - background-color: #ffcc00 !important; -} - -a.bg-primary:hover, a.bg-primary:focus, -button.bg-primary:hover, -button.bg-primary:focus { - background-color: #cca300 !important; -} - -.bg-secondary { - background-color: #212529 !important; -} - -a.bg-secondary:hover, a.bg-secondary:focus, -button.bg-secondary:hover, -button.bg-secondary:focus { - background-color: #0a0c0d !important; -} - -.bg-success { - background-color: #28a745 !important; -} - -a.bg-success:hover, a.bg-success:focus, -button.bg-success:hover, -button.bg-success:focus { - background-color: #1e7e34 !important; -} - -.bg-info { - background-color: #17a2b8 !important; -} - -a.bg-info:hover, a.bg-info:focus, -button.bg-info:hover, -button.bg-info:focus { - background-color: #117a8b !important; -} - -.bg-warning { - background-color: #ffc107 !important; -} - -a.bg-warning:hover, a.bg-warning:focus, -button.bg-warning:hover, -button.bg-warning:focus { - background-color: #d39e00 !important; -} - -.bg-danger { - background-color: #dc3545 !important; -} - -a.bg-danger:hover, a.bg-danger:focus, -button.bg-danger:hover, -button.bg-danger:focus { - background-color: #bd2130 !important; -} - -.bg-light { - background-color: #f1f6f9 !important; -} - -a.bg-light:hover, a.bg-light:focus, -button.bg-light:hover, -button.bg-light:focus { - background-color: #cddfea !important; -} - -.bg-dark { - background-color: #495057 !important; -} - -a.bg-dark:hover, a.bg-dark:focus, -button.bg-dark:hover, -button.bg-dark:focus { - background-color: #32373b !important; -} - -.bg-primary-light { - background-color: #fffaf0 !important; -} - -a.bg-primary-light:hover, a.bg-primary-light:focus, -button.bg-primary-light:hover, -button.bg-primary-light:focus { - background-color: #ffe9bd !important; -} - -.bg-secondary-light { - background-color: #fff !important; -} - -a.bg-secondary-light:hover, a.bg-secondary-light:focus, -button.bg-secondary-light:hover, -button.bg-secondary-light:focus { - background-color: #e6e6e6 !important; -} - -.bg-tertiary { - background-color: #257af4 !important; -} - -a.bg-tertiary:hover, a.bg-tertiary:focus, -button.bg-tertiary:hover, -button.bg-tertiary:focus { - background-color: #0b60db !important; -} - -.bg-tertiary-light { - background-color: #e3f1fe !important; -} - -a.bg-tertiary-light:hover, a.bg-tertiary-light:focus, -button.bg-tertiary-light:hover, -button.bg-tertiary-light:focus { - background-color: #b2d8fc !important; -} - -.bg-white { - background-color: #fff !important; -} - -a.bg-white:hover, a.bg-white:focus, -button.bg-white:hover, -button.bg-white:focus { - background-color: #e6e6e6 !important; -} - -.bg-black { - background-color: #212529 !important; -} - -a.bg-black:hover, a.bg-black:focus, -button.bg-black:hover, -button.bg-black:focus { - background-color: #0a0c0d !important; -} - -.bg-blue { - background-color: #257af4 !important; -} - -a.bg-blue:hover, a.bg-blue:focus, -button.bg-blue:hover, -button.bg-blue:focus { - background-color: #0b60db !important; -} - -.bg-light-blue { - background-color: #e3f1fe !important; -} - -a.bg-light-blue:hover, a.bg-light-blue:focus, -button.bg-light-blue:hover, -button.bg-light-blue:focus { - background-color: #b2d8fc !important; -} - -.bg-yellow { - background-color: #ffcc00 !important; -} - -a.bg-yellow:hover, a.bg-yellow:focus, -button.bg-yellow:hover, -button.bg-yellow:focus { - background-color: #cca300 !important; -} - -.bg-light-yellow { - background-color: #fffaf0 !important; -} - -a.bg-light-yellow:hover, a.bg-light-yellow:focus, -button.bg-light-yellow:hover, -button.bg-light-yellow:focus { - background-color: #ffe9bd !important; -} - -.bg-orange { - background-color: #ff8c00 !important; -} - -a.bg-orange:hover, a.bg-orange:focus, -button.bg-orange:hover, -button.bg-orange:focus { - background-color: #cc7000 !important; -} - -.bg-light-orange { - background-color: #ffe4b5 !important; -} - -a.bg-light-orange:hover, a.bg-light-orange:focus, -button.bg-light-orange:hover, -button.bg-light-orange:focus { - background-color: #ffd182 !important; -} - -.bg-red { - background-color: #ff3939 !important; -} - -a.bg-red:hover, a.bg-red:focus, -button.bg-red:hover, -button.bg-red:focus { - background-color: #ff0606 !important; -} - -.bg-light-red { - background-color: #ffe4e1 !important; -} - -a.bg-light-red:hover, a.bg-light-red:focus, -button.bg-light-red:hover, -button.bg-light-red:focus { - background-color: #ffb6ae !important; -} - -.bg-medium { - background-color: #d6dbdf !important; -} - -a.bg-medium:hover, a.bg-medium:focus, -button.bg-medium:hover, -button.bg-medium:focus { - background-color: #b9c2c9 !important; -} - -.bg-white { - background-color: #fff !important; -} - -.bg-transparent { - background-color: transparent !important; -} - -.border { - border: 1px solid #d6dbdf !important; -} - -.border-top { - border-top: 1px solid #d6dbdf !important; -} - -.border-right { - border-right: 1px solid #d6dbdf !important; -} - -.border-bottom { - border-bottom: 1px solid #d6dbdf !important; -} - -.border-left { - border-left: 1px solid #d6dbdf !important; -} - -.border-0 { - border: 0 !important; -} - -.border-top-0 { - border-top: 0 !important; -} - -.border-right-0 { - border-right: 0 !important; -} - -.border-bottom-0 { - border-bottom: 0 !important; -} - -.border-left-0 { - border-left: 0 !important; -} - -.border-primary { - border-color: #ffcc00 !important; -} - -.border-secondary { - border-color: #212529 !important; -} - -.border-success { - border-color: #28a745 !important; -} - -.border-info { - border-color: #17a2b8 !important; -} - -.border-warning { - border-color: #ffc107 !important; -} - -.border-danger { - border-color: #dc3545 !important; -} - -.border-light { - border-color: #f1f6f9 !important; -} - -.border-dark { - border-color: #495057 !important; -} - -.border-primary-light { - border-color: #fffaf0 !important; -} - -.border-secondary-light { - border-color: #fff !important; -} - -.border-tertiary { - border-color: #257af4 !important; -} - -.border-tertiary-light { - border-color: #e3f1fe !important; -} - -.border-white { - border-color: #fff !important; -} - -.border-black { - border-color: #212529 !important; -} - -.border-blue { - border-color: #257af4 !important; -} - -.border-light-blue { - border-color: #e3f1fe !important; -} - -.border-yellow { - border-color: #ffcc00 !important; -} - -.border-light-yellow { - border-color: #fffaf0 !important; -} - -.border-orange { - border-color: #ff8c00 !important; -} - -.border-light-orange { - border-color: #ffe4b5 !important; -} - -.border-red { - border-color: #ff3939 !important; -} - -.border-light-red { - border-color: #ffe4e1 !important; -} - -.border-medium { - border-color: #d6dbdf !important; -} - -.border-white { - border-color: #fff !important; -} - -.rounded-sm { - border-radius: 8px !important; -} - -.rounded { - border-radius: 8px !important; -} - -.rounded-top { - border-top-left-radius: 8px !important; - border-top-right-radius: 8px !important; -} - -.rounded-right { - border-top-right-radius: 8px !important; - border-bottom-right-radius: 8px !important; -} - -.rounded-bottom { - border-bottom-right-radius: 8px !important; - border-bottom-left-radius: 8px !important; -} - -.rounded-left { - border-top-left-radius: 8px !important; - border-bottom-left-radius: 8px !important; -} - -.rounded-lg { - border-radius: 8px !important; -} - -.rounded-circle { - border-radius: 50% !important; -} - -.rounded-pill { - border-radius: 50rem !important; -} - -.rounded-0 { - border-radius: 0 !important; -} - -.clearfix::after { - display: block; - clear: both; - content: ""; -} - -.d-none { - display: none !important; -} - -.d-inline { - display: inline !important; -} - -.d-inline-block { - display: inline-block !important; -} - -.d-block { - display: block !important; -} - -.d-table { - display: table !important; -} - -.d-table-row { - display: table-row !important; -} - -.d-table-cell { - display: table-cell !important; -} - -.d-flex { - display: flex !important; -} - -.d-inline-flex { - display: inline-flex !important; -} - -@media (min-width: 400px) { - .d-xs-none { - display: none !important; - } - - .d-xs-inline { - display: inline !important; - } - - .d-xs-inline-block { - display: inline-block !important; - } - - .d-xs-block { - display: block !important; - } - - .d-xs-table { - display: table !important; - } - - .d-xs-table-row { - display: table-row !important; - } - - .d-xs-table-cell { - display: table-cell !important; - } - - .d-xs-flex { - display: flex !important; - } - - .d-xs-inline-flex { - display: inline-flex !important; - } -} -@media (min-width: 616px) { - .d-sm-none { - display: none !important; - } - - .d-sm-inline { - display: inline !important; - } - - .d-sm-inline-block { - display: inline-block !important; - } - - .d-sm-block { - display: block !important; - } - - .d-sm-table { - display: table !important; - } - - .d-sm-table-row { - display: table-row !important; - } - - .d-sm-table-cell { - display: table-cell !important; - } - - .d-sm-flex { - display: flex !important; - } - - .d-sm-inline-flex { - display: inline-flex !important; - } -} -@media (min-width: 768px) { - .d-md-none { - display: none !important; - } - - .d-md-inline { - display: inline !important; - } - - .d-md-inline-block { - display: inline-block !important; - } - - .d-md-block { - display: block !important; - } - - .d-md-table { - display: table !important; - } - - .d-md-table-row { - display: table-row !important; - } - - .d-md-table-cell { - display: table-cell !important; - } - - .d-md-flex { - display: flex !important; - } - - .d-md-inline-flex { - display: inline-flex !important; - } -} -@media (min-width: 980px) { - .d-lg-none { - display: none !important; - } - - .d-lg-inline { - display: inline !important; - } - - .d-lg-inline-block { - display: inline-block !important; - } - - .d-lg-block { - display: block !important; - } - - .d-lg-table { - display: table !important; - } - - .d-lg-table-row { - display: table-row !important; - } - - .d-lg-table-cell { - display: table-cell !important; - } - - .d-lg-flex { - display: flex !important; - } - - .d-lg-inline-flex { - display: inline-flex !important; - } -} -@media (min-width: 1240px) { - .d-xl-none { - display: none !important; - } - - .d-xl-inline { - display: inline !important; - } - - .d-xl-inline-block { - display: inline-block !important; - } - - .d-xl-block { - display: block !important; - } - - .d-xl-table { - display: table !important; - } - - .d-xl-table-row { - display: table-row !important; - } - - .d-xl-table-cell { - display: table-cell !important; - } - - .d-xl-flex { - display: flex !important; - } - - .d-xl-inline-flex { - display: inline-flex !important; - } -} -@media print { - .d-print-none { - display: none !important; - } - - .d-print-inline { - display: inline !important; - } - - .d-print-inline-block { - display: inline-block !important; - } - - .d-print-block { - display: block !important; - } - - .d-print-table { - display: table !important; - } - - .d-print-table-row { - display: table-row !important; - } - - .d-print-table-cell { - display: table-cell !important; - } - - .d-print-flex { - display: flex !important; - } - - .d-print-inline-flex { - display: inline-flex !important; - } -} -.embed-responsive { - position: relative; - display: block; - width: 100%; - padding: 0; - overflow: hidden; -} -.embed-responsive::before { - display: block; - content: ""; -} -.embed-responsive .embed-responsive-item, -.embed-responsive iframe, -.embed-responsive embed, -.embed-responsive object, -.embed-responsive video { - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 100%; - height: 100%; - border: 0; -} - -.embed-responsive-21by9::before { - padding-top: 42.8571428571%; -} - -.embed-responsive-16by9::before { - padding-top: 56.25%; -} - -.embed-responsive-4by3::before { - padding-top: 75%; -} - -.embed-responsive-1by1::before { - padding-top: 100%; -} - -.flex-row { - flex-direction: row !important; -} - -.flex-column { - flex-direction: column !important; -} - -.flex-row-reverse { - flex-direction: row-reverse !important; -} - -.flex-column-reverse { - flex-direction: column-reverse !important; -} - -.flex-wrap { - flex-wrap: wrap !important; -} - -.flex-nowrap { - flex-wrap: nowrap !important; -} - -.flex-wrap-reverse { - flex-wrap: wrap-reverse !important; -} - -.flex-fill { - flex: 1 1 auto !important; -} - -.flex-grow-0 { - flex-grow: 0 !important; -} - -.flex-grow-1 { - flex-grow: 1 !important; -} - -.flex-shrink-0 { - flex-shrink: 0 !important; -} - -.flex-shrink-1 { - flex-shrink: 1 !important; -} - -.justify-content-start { - justify-content: flex-start !important; -} - -.justify-content-end { - justify-content: flex-end !important; -} - -.justify-content-center { - justify-content: center !important; -} - -.justify-content-between { - justify-content: space-between !important; -} - -.justify-content-around { - justify-content: space-around !important; -} - -.align-items-start { - align-items: flex-start !important; -} - -.align-items-end { - align-items: flex-end !important; -} - -.align-items-center { - align-items: center !important; -} - -.align-items-baseline { - align-items: baseline !important; -} - -.align-items-stretch { - align-items: stretch !important; -} - -.align-content-start { - align-content: flex-start !important; -} - -.align-content-end { - align-content: flex-end !important; -} - -.align-content-center { - align-content: center !important; -} - -.align-content-between { - align-content: space-between !important; -} - -.align-content-around { - align-content: space-around !important; -} - -.align-content-stretch { - align-content: stretch !important; -} - -.align-self-auto { - align-self: auto !important; -} - -.align-self-start { - align-self: flex-start !important; -} - -.align-self-end { - align-self: flex-end !important; -} - -.align-self-center { - align-self: center !important; -} - -.align-self-baseline { - align-self: baseline !important; -} - -.align-self-stretch { - align-self: stretch !important; -} - -@media (min-width: 400px) { - .flex-xs-row { - flex-direction: row !important; - } - - .flex-xs-column { - flex-direction: column !important; - } - - .flex-xs-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-xs-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-xs-wrap { - flex-wrap: wrap !important; - } - - .flex-xs-nowrap { - flex-wrap: nowrap !important; - } - - .flex-xs-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .flex-xs-fill { - flex: 1 1 auto !important; - } - - .flex-xs-grow-0 { - flex-grow: 0 !important; - } - - .flex-xs-grow-1 { - flex-grow: 1 !important; - } - - .flex-xs-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-xs-shrink-1 { - flex-shrink: 1 !important; - } - - .justify-content-xs-start { - justify-content: flex-start !important; - } - - .justify-content-xs-end { - justify-content: flex-end !important; - } - - .justify-content-xs-center { - justify-content: center !important; - } - - .justify-content-xs-between { - justify-content: space-between !important; - } - - .justify-content-xs-around { - justify-content: space-around !important; - } - - .align-items-xs-start { - align-items: flex-start !important; - } - - .align-items-xs-end { - align-items: flex-end !important; - } - - .align-items-xs-center { - align-items: center !important; - } - - .align-items-xs-baseline { - align-items: baseline !important; - } - - .align-items-xs-stretch { - align-items: stretch !important; - } - - .align-content-xs-start { - align-content: flex-start !important; - } - - .align-content-xs-end { - align-content: flex-end !important; - } - - .align-content-xs-center { - align-content: center !important; - } - - .align-content-xs-between { - align-content: space-between !important; - } - - .align-content-xs-around { - align-content: space-around !important; - } - - .align-content-xs-stretch { - align-content: stretch !important; - } - - .align-self-xs-auto { - align-self: auto !important; - } - - .align-self-xs-start { - align-self: flex-start !important; - } - - .align-self-xs-end { - align-self: flex-end !important; - } - - .align-self-xs-center { - align-self: center !important; - } - - .align-self-xs-baseline { - align-self: baseline !important; - } - - .align-self-xs-stretch { - align-self: stretch !important; - } -} -@media (min-width: 616px) { - .flex-sm-row { - flex-direction: row !important; - } - - .flex-sm-column { - flex-direction: column !important; - } - - .flex-sm-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-sm-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-sm-wrap { - flex-wrap: wrap !important; - } - - .flex-sm-nowrap { - flex-wrap: nowrap !important; - } - - .flex-sm-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .flex-sm-fill { - flex: 1 1 auto !important; - } - - .flex-sm-grow-0 { - flex-grow: 0 !important; - } - - .flex-sm-grow-1 { - flex-grow: 1 !important; - } - - .flex-sm-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-sm-shrink-1 { - flex-shrink: 1 !important; - } - - .justify-content-sm-start { - justify-content: flex-start !important; - } - - .justify-content-sm-end { - justify-content: flex-end !important; - } - - .justify-content-sm-center { - justify-content: center !important; - } - - .justify-content-sm-between { - justify-content: space-between !important; - } - - .justify-content-sm-around { - justify-content: space-around !important; - } - - .align-items-sm-start { - align-items: flex-start !important; - } - - .align-items-sm-end { - align-items: flex-end !important; - } - - .align-items-sm-center { - align-items: center !important; - } - - .align-items-sm-baseline { - align-items: baseline !important; - } - - .align-items-sm-stretch { - align-items: stretch !important; - } - - .align-content-sm-start { - align-content: flex-start !important; - } - - .align-content-sm-end { - align-content: flex-end !important; - } - - .align-content-sm-center { - align-content: center !important; - } - - .align-content-sm-between { - align-content: space-between !important; - } - - .align-content-sm-around { - align-content: space-around !important; - } - - .align-content-sm-stretch { - align-content: stretch !important; - } - - .align-self-sm-auto { - align-self: auto !important; - } - - .align-self-sm-start { - align-self: flex-start !important; - } - - .align-self-sm-end { - align-self: flex-end !important; - } - - .align-self-sm-center { - align-self: center !important; - } - - .align-self-sm-baseline { - align-self: baseline !important; - } - - .align-self-sm-stretch { - align-self: stretch !important; - } -} -@media (min-width: 768px) { - .flex-md-row { - flex-direction: row !important; - } - - .flex-md-column { - flex-direction: column !important; - } - - .flex-md-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-md-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-md-wrap { - flex-wrap: wrap !important; - } - - .flex-md-nowrap { - flex-wrap: nowrap !important; - } - - .flex-md-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .flex-md-fill { - flex: 1 1 auto !important; - } - - .flex-md-grow-0 { - flex-grow: 0 !important; - } - - .flex-md-grow-1 { - flex-grow: 1 !important; - } - - .flex-md-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-md-shrink-1 { - flex-shrink: 1 !important; - } - - .justify-content-md-start { - justify-content: flex-start !important; - } - - .justify-content-md-end { - justify-content: flex-end !important; - } - - .justify-content-md-center { - justify-content: center !important; - } - - .justify-content-md-between { - justify-content: space-between !important; - } - - .justify-content-md-around { - justify-content: space-around !important; - } - - .align-items-md-start { - align-items: flex-start !important; - } - - .align-items-md-end { - align-items: flex-end !important; - } - - .align-items-md-center { - align-items: center !important; - } - - .align-items-md-baseline { - align-items: baseline !important; - } - - .align-items-md-stretch { - align-items: stretch !important; - } - - .align-content-md-start { - align-content: flex-start !important; - } - - .align-content-md-end { - align-content: flex-end !important; - } - - .align-content-md-center { - align-content: center !important; - } - - .align-content-md-between { - align-content: space-between !important; - } - - .align-content-md-around { - align-content: space-around !important; - } - - .align-content-md-stretch { - align-content: stretch !important; - } - - .align-self-md-auto { - align-self: auto !important; - } - - .align-self-md-start { - align-self: flex-start !important; - } - - .align-self-md-end { - align-self: flex-end !important; - } - - .align-self-md-center { - align-self: center !important; - } - - .align-self-md-baseline { - align-self: baseline !important; - } - - .align-self-md-stretch { - align-self: stretch !important; - } -} -@media (min-width: 980px) { - .flex-lg-row { - flex-direction: row !important; - } - - .flex-lg-column { - flex-direction: column !important; - } - - .flex-lg-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-lg-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-lg-wrap { - flex-wrap: wrap !important; - } - - .flex-lg-nowrap { - flex-wrap: nowrap !important; - } - - .flex-lg-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .flex-lg-fill { - flex: 1 1 auto !important; - } - - .flex-lg-grow-0 { - flex-grow: 0 !important; - } - - .flex-lg-grow-1 { - flex-grow: 1 !important; - } - - .flex-lg-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-lg-shrink-1 { - flex-shrink: 1 !important; - } - - .justify-content-lg-start { - justify-content: flex-start !important; - } - - .justify-content-lg-end { - justify-content: flex-end !important; - } - - .justify-content-lg-center { - justify-content: center !important; - } - - .justify-content-lg-between { - justify-content: space-between !important; - } - - .justify-content-lg-around { - justify-content: space-around !important; - } - - .align-items-lg-start { - align-items: flex-start !important; - } - - .align-items-lg-end { - align-items: flex-end !important; - } - - .align-items-lg-center { - align-items: center !important; - } - - .align-items-lg-baseline { - align-items: baseline !important; - } - - .align-items-lg-stretch { - align-items: stretch !important; - } - - .align-content-lg-start { - align-content: flex-start !important; - } - - .align-content-lg-end { - align-content: flex-end !important; - } - - .align-content-lg-center { - align-content: center !important; - } - - .align-content-lg-between { - align-content: space-between !important; - } - - .align-content-lg-around { - align-content: space-around !important; - } - - .align-content-lg-stretch { - align-content: stretch !important; - } - - .align-self-lg-auto { - align-self: auto !important; - } - - .align-self-lg-start { - align-self: flex-start !important; - } - - .align-self-lg-end { - align-self: flex-end !important; - } - - .align-self-lg-center { - align-self: center !important; - } - - .align-self-lg-baseline { - align-self: baseline !important; - } - - .align-self-lg-stretch { - align-self: stretch !important; - } -} -@media (min-width: 1240px) { - .flex-xl-row { - flex-direction: row !important; - } - - .flex-xl-column { - flex-direction: column !important; - } - - .flex-xl-row-reverse { - flex-direction: row-reverse !important; - } - - .flex-xl-column-reverse { - flex-direction: column-reverse !important; - } - - .flex-xl-wrap { - flex-wrap: wrap !important; - } - - .flex-xl-nowrap { - flex-wrap: nowrap !important; - } - - .flex-xl-wrap-reverse { - flex-wrap: wrap-reverse !important; - } - - .flex-xl-fill { - flex: 1 1 auto !important; - } - - .flex-xl-grow-0 { - flex-grow: 0 !important; - } - - .flex-xl-grow-1 { - flex-grow: 1 !important; - } - - .flex-xl-shrink-0 { - flex-shrink: 0 !important; - } - - .flex-xl-shrink-1 { - flex-shrink: 1 !important; - } - - .justify-content-xl-start { - justify-content: flex-start !important; - } - - .justify-content-xl-end { - justify-content: flex-end !important; - } - - .justify-content-xl-center { - justify-content: center !important; - } - - .justify-content-xl-between { - justify-content: space-between !important; - } - - .justify-content-xl-around { - justify-content: space-around !important; - } - - .align-items-xl-start { - align-items: flex-start !important; - } - - .align-items-xl-end { - align-items: flex-end !important; - } - - .align-items-xl-center { - align-items: center !important; - } - - .align-items-xl-baseline { - align-items: baseline !important; - } - - .align-items-xl-stretch { - align-items: stretch !important; - } - - .align-content-xl-start { - align-content: flex-start !important; - } - - .align-content-xl-end { - align-content: flex-end !important; - } - - .align-content-xl-center { - align-content: center !important; - } - - .align-content-xl-between { - align-content: space-between !important; - } - - .align-content-xl-around { - align-content: space-around !important; - } - - .align-content-xl-stretch { - align-content: stretch !important; - } - - .align-self-xl-auto { - align-self: auto !important; - } - - .align-self-xl-start { - align-self: flex-start !important; - } - - .align-self-xl-end { - align-self: flex-end !important; - } - - .align-self-xl-center { - align-self: center !important; - } - - .align-self-xl-baseline { - align-self: baseline !important; - } - - .align-self-xl-stretch { - align-self: stretch !important; - } -} -.float-left { - float: left !important; -} - -.float-right { - float: right !important; -} - -.float-none { - float: none !important; -} - -@media (min-width: 400px) { - .float-xs-left { - float: left !important; - } - - .float-xs-right { - float: right !important; - } - - .float-xs-none { - float: none !important; - } -} -@media (min-width: 616px) { - .float-sm-left { - float: left !important; - } - - .float-sm-right { - float: right !important; - } - - .float-sm-none { - float: none !important; - } -} -@media (min-width: 768px) { - .float-md-left { - float: left !important; - } - - .float-md-right { - float: right !important; - } - - .float-md-none { - float: none !important; - } -} -@media (min-width: 980px) { - .float-lg-left { - float: left !important; - } - - .float-lg-right { - float: right !important; - } - - .float-lg-none { - float: none !important; - } -} -@media (min-width: 1240px) { - .float-xl-left { - float: left !important; - } - - .float-xl-right { - float: right !important; - } - - .float-xl-none { - float: none !important; - } -} -.overflow-auto { - overflow: auto !important; -} - -.overflow-hidden { - overflow: hidden !important; -} - -.position-static { - position: static !important; -} - -.position-relative { - position: relative !important; -} - -.position-absolute { - position: absolute !important; -} - -.position-fixed { - position: fixed !important; -} - -.position-sticky { - position: sticky !important; -} - -.fixed-top { - position: fixed; - top: 0; - right: 0; - left: 0; - z-index: 1030; -} - -.fixed-bottom { - position: fixed; - right: 0; - bottom: 0; - left: 0; - z-index: 1030; -} - -@supports (position: sticky) { - .sticky-top { - position: sticky; - top: 0; - z-index: 1020; - } -} - -.sr-only { - position: absolute; - width: 1px; - height: 1px; - padding: 0; - margin: -1px; - overflow: hidden; - clip: rect(0, 0, 0, 0); - white-space: nowrap; - border: 0; -} - -.sr-only-focusable:active, .sr-only-focusable:focus { - position: static; - width: auto; - height: auto; - overflow: visible; - clip: auto; - white-space: normal; -} - -.shadow-sm { - box-shadow: 0 2px 14px rgba(108, 117, 125, 0.2) !important; -} - -.shadow { - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2) !important; -} - -.shadow-lg { - box-shadow: 0 12px 32px rgba(108, 117, 125, 0.2) !important; -} - -.shadow-none { - box-shadow: none !important; -} - -.w-25 { - width: 25% !important; -} - -.w-50 { - width: 50% !important; -} - -.w-75 { - width: 75% !important; -} - -.w-100 { - width: 100% !important; -} - -.w-auto { - width: auto !important; -} - -.h-25 { - height: 25% !important; -} - -.h-50 { - height: 50% !important; -} - -.h-75 { - height: 75% !important; -} - -.h-100 { - height: 100% !important; -} - -.h-auto { - height: auto !important; -} - -.mw-100 { - max-width: 100% !important; -} - -.mh-100 { - max-height: 100% !important; -} - -.min-vw-100 { - min-width: 100vw !important; -} - -.min-vh-100 { - min-height: 100vh !important; -} - -.vw-100 { - width: 100vw !important; -} - -.vh-100 { - height: 100vh !important; -} - -.stretched-link::after { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1; - pointer-events: auto; - content: ""; - background-color: rgba(0, 0, 0, 0); -} - -.m-0 { - margin: 0 !important; -} - -.mt-0, -.my-0 { - margin-top: 0 !important; -} - -.mr-0, -.mx-0 { - margin-right: 0 !important; -} - -.mb-0, -.my-0 { - margin-bottom: 0 !important; -} - -.ml-0, -.mx-0 { - margin-left: 0 !important; -} - -.m-1 { - margin: 8px !important; -} - -.mt-1, -.my-1 { - margin-top: 8px !important; -} - -.mr-1, -.mx-1 { - margin-right: 8px !important; -} - -.mb-1, -.my-1 { - margin-bottom: 8px !important; -} - -.ml-1, -.mx-1 { - margin-left: 8px !important; -} - -.m-2 { - margin: 16px !important; -} - -.mt-2, -.my-2 { - margin-top: 16px !important; -} - -.mr-2, -.mx-2 { - margin-right: 16px !important; -} - -.mb-2, -.my-2 { - margin-bottom: 16px !important; -} - -.ml-2, -.mx-2 { - margin-left: 16px !important; -} - -.m-3 { - margin: 24px !important; -} - -.mt-3, -.my-3 { - margin-top: 24px !important; -} - -.mr-3, -.mx-3 { - margin-right: 24px !important; -} - -.mb-3, -.my-3 { - margin-bottom: 24px !important; -} - -.ml-3, -.mx-3 { - margin-left: 24px !important; -} - -.m-4 { - margin: 32px !important; -} - -.mt-4, -.my-4 { - margin-top: 32px !important; -} - -.mr-4, -.mx-4 { - margin-right: 32px !important; -} - -.mb-4, -.my-4 { - margin-bottom: 32px !important; -} - -.ml-4, -.mx-4 { - margin-left: 32px !important; -} - -.m-5 { - margin: 40px !important; -} - -.mt-5, -.my-5 { - margin-top: 40px !important; -} - -.mr-5, -.mx-5 { - margin-right: 40px !important; -} - -.mb-5, -.my-5 { - margin-bottom: 40px !important; -} - -.ml-5, -.mx-5 { - margin-left: 40px !important; -} - -.m-6 { - margin: 48px !important; -} - -.mt-6, -.my-6 { - margin-top: 48px !important; -} - -.mr-6, -.mx-6 { - margin-right: 48px !important; -} - -.mb-6, -.my-6 { - margin-bottom: 48px !important; -} - -.ml-6, -.mx-6 { - margin-left: 48px !important; -} - -.m-7 { - margin: 56px !important; -} - -.mt-7, -.my-7 { - margin-top: 56px !important; -} - -.mr-7, -.mx-7 { - margin-right: 56px !important; -} - -.mb-7, -.my-7 { - margin-bottom: 56px !important; -} - -.ml-7, -.mx-7 { - margin-left: 56px !important; -} - -.m-8 { - margin: 64px !important; -} - -.mt-8, -.my-8 { - margin-top: 64px !important; -} - -.mr-8, -.mx-8 { - margin-right: 64px !important; -} - -.mb-8, -.my-8 { - margin-bottom: 64px !important; -} - -.ml-8, -.mx-8 { - margin-left: 64px !important; -} - -.m-9 { - margin: 72px !important; -} - -.mt-9, -.my-9 { - margin-top: 72px !important; -} - -.mr-9, -.mx-9 { - margin-right: 72px !important; -} - -.mb-9, -.my-9 { - margin-bottom: 72px !important; -} - -.ml-9, -.mx-9 { - margin-left: 72px !important; -} - -.m-10 { - margin: 80px !important; -} - -.mt-10, -.my-10 { - margin-top: 80px !important; -} - -.mr-10, -.mx-10 { - margin-right: 80px !important; -} - -.mb-10, -.my-10 { - margin-bottom: 80px !important; -} - -.ml-10, -.mx-10 { - margin-left: 80px !important; -} - -.m-12 { - margin: 96px !important; -} - -.mt-12, -.my-12 { - margin-top: 96px !important; -} - -.mr-12, -.mx-12 { - margin-right: 96px !important; -} - -.mb-12, -.my-12 { - margin-bottom: 96px !important; -} - -.ml-12, -.mx-12 { - margin-left: 96px !important; -} - -.m-15 { - margin: 120px !important; -} - -.mt-15, -.my-15 { - margin-top: 120px !important; -} - -.mr-15, -.mx-15 { - margin-right: 120px !important; -} - -.mb-15, -.my-15 { - margin-bottom: 120px !important; -} - -.ml-15, -.mx-15 { - margin-left: 120px !important; -} - -.p-0 { - padding: 0 !important; -} - -.pt-0, -.py-0 { - padding-top: 0 !important; -} - -.pr-0, -.px-0 { - padding-right: 0 !important; -} - -.pb-0, -.py-0 { - padding-bottom: 0 !important; -} - -.pl-0, -.px-0 { - padding-left: 0 !important; -} - -.p-1 { - padding: 8px !important; -} - -.pt-1, -.py-1 { - padding-top: 8px !important; -} - -.pr-1, -.px-1 { - padding-right: 8px !important; -} - -.pb-1, -.py-1 { - padding-bottom: 8px !important; -} - -.pl-1, -.px-1 { - padding-left: 8px !important; -} - -.p-2 { - padding: 16px !important; -} - -.pt-2, -.py-2 { - padding-top: 16px !important; -} - -.pr-2, -.px-2 { - padding-right: 16px !important; -} - -.pb-2, -.py-2 { - padding-bottom: 16px !important; -} - -.pl-2, -.px-2 { - padding-left: 16px !important; -} - -.p-3 { - padding: 24px !important; -} - -.pt-3, -.py-3 { - padding-top: 24px !important; -} - -.pr-3, -.px-3 { - padding-right: 24px !important; -} - -.pb-3, -.py-3 { - padding-bottom: 24px !important; -} - -.pl-3, -.px-3 { - padding-left: 24px !important; -} - -.p-4 { - padding: 32px !important; -} - -.pt-4, -.py-4 { - padding-top: 32px !important; -} - -.pr-4, -.px-4 { - padding-right: 32px !important; -} - -.pb-4, -.py-4 { - padding-bottom: 32px !important; -} - -.pl-4, -.px-4 { - padding-left: 32px !important; -} - -.p-5 { - padding: 40px !important; -} - -.pt-5, -.py-5 { - padding-top: 40px !important; -} - -.pr-5, -.px-5 { - padding-right: 40px !important; -} - -.pb-5, -.py-5 { - padding-bottom: 40px !important; -} - -.pl-5, -.px-5 { - padding-left: 40px !important; -} - -.p-6 { - padding: 48px !important; -} - -.pt-6, -.py-6 { - padding-top: 48px !important; -} - -.pr-6, -.px-6 { - padding-right: 48px !important; -} - -.pb-6, -.py-6 { - padding-bottom: 48px !important; -} - -.pl-6, -.px-6 { - padding-left: 48px !important; -} - -.p-7 { - padding: 56px !important; -} - -.pt-7, -.py-7 { - padding-top: 56px !important; -} - -.pr-7, -.px-7 { - padding-right: 56px !important; -} - -.pb-7, -.py-7 { - padding-bottom: 56px !important; -} - -.pl-7, -.px-7 { - padding-left: 56px !important; -} - -.p-8 { - padding: 64px !important; -} - -.pt-8, -.py-8 { - padding-top: 64px !important; -} - -.pr-8, -.px-8 { - padding-right: 64px !important; -} - -.pb-8, -.py-8 { - padding-bottom: 64px !important; -} - -.pl-8, -.px-8 { - padding-left: 64px !important; -} - -.p-9 { - padding: 72px !important; -} - -.pt-9, -.py-9 { - padding-top: 72px !important; -} - -.pr-9, -.px-9 { - padding-right: 72px !important; -} - -.pb-9, -.py-9 { - padding-bottom: 72px !important; -} - -.pl-9, -.px-9 { - padding-left: 72px !important; -} - -.p-10 { - padding: 80px !important; -} - -.pt-10, -.py-10 { - padding-top: 80px !important; -} - -.pr-10, -.px-10 { - padding-right: 80px !important; -} - -.pb-10, -.py-10 { - padding-bottom: 80px !important; -} - -.pl-10, -.px-10 { - padding-left: 80px !important; -} - -.p-12 { - padding: 96px !important; -} - -.pt-12, -.py-12 { - padding-top: 96px !important; -} - -.pr-12, -.px-12 { - padding-right: 96px !important; -} - -.pb-12, -.py-12 { - padding-bottom: 96px !important; -} - -.pl-12, -.px-12 { - padding-left: 96px !important; -} - -.p-15 { - padding: 120px !important; -} - -.pt-15, -.py-15 { - padding-top: 120px !important; -} - -.pr-15, -.px-15 { - padding-right: 120px !important; -} - -.pb-15, -.py-15 { - padding-bottom: 120px !important; -} - -.pl-15, -.px-15 { - padding-left: 120px !important; -} - -.m-n1 { - margin: -8px !important; -} - -.mt-n1, -.my-n1 { - margin-top: -8px !important; -} - -.mr-n1, -.mx-n1 { - margin-right: -8px !important; -} - -.mb-n1, -.my-n1 { - margin-bottom: -8px !important; -} - -.ml-n1, -.mx-n1 { - margin-left: -8px !important; -} - -.m-n2 { - margin: -16px !important; -} - -.mt-n2, -.my-n2 { - margin-top: -16px !important; -} - -.mr-n2, -.mx-n2 { - margin-right: -16px !important; -} - -.mb-n2, -.my-n2 { - margin-bottom: -16px !important; -} - -.ml-n2, -.mx-n2 { - margin-left: -16px !important; -} - -.m-n3 { - margin: -24px !important; -} - -.mt-n3, -.my-n3 { - margin-top: -24px !important; -} - -.mr-n3, -.mx-n3 { - margin-right: -24px !important; -} - -.mb-n3, -.my-n3 { - margin-bottom: -24px !important; -} - -.ml-n3, -.mx-n3 { - margin-left: -24px !important; -} - -.m-n4 { - margin: -32px !important; -} - -.mt-n4, -.my-n4 { - margin-top: -32px !important; -} - -.mr-n4, -.mx-n4 { - margin-right: -32px !important; -} - -.mb-n4, -.my-n4 { - margin-bottom: -32px !important; -} - -.ml-n4, -.mx-n4 { - margin-left: -32px !important; -} - -.m-n5 { - margin: -40px !important; -} - -.mt-n5, -.my-n5 { - margin-top: -40px !important; -} - -.mr-n5, -.mx-n5 { - margin-right: -40px !important; -} - -.mb-n5, -.my-n5 { - margin-bottom: -40px !important; -} - -.ml-n5, -.mx-n5 { - margin-left: -40px !important; -} - -.m-n6 { - margin: -48px !important; -} - -.mt-n6, -.my-n6 { - margin-top: -48px !important; -} - -.mr-n6, -.mx-n6 { - margin-right: -48px !important; -} - -.mb-n6, -.my-n6 { - margin-bottom: -48px !important; -} - -.ml-n6, -.mx-n6 { - margin-left: -48px !important; -} - -.m-n7 { - margin: -56px !important; -} - -.mt-n7, -.my-n7 { - margin-top: -56px !important; -} - -.mr-n7, -.mx-n7 { - margin-right: -56px !important; -} - -.mb-n7, -.my-n7 { - margin-bottom: -56px !important; -} - -.ml-n7, -.mx-n7 { - margin-left: -56px !important; -} - -.m-n8 { - margin: -64px !important; -} - -.mt-n8, -.my-n8 { - margin-top: -64px !important; -} - -.mr-n8, -.mx-n8 { - margin-right: -64px !important; -} - -.mb-n8, -.my-n8 { - margin-bottom: -64px !important; -} - -.ml-n8, -.mx-n8 { - margin-left: -64px !important; -} - -.m-n9 { - margin: -72px !important; -} - -.mt-n9, -.my-n9 { - margin-top: -72px !important; -} - -.mr-n9, -.mx-n9 { - margin-right: -72px !important; -} - -.mb-n9, -.my-n9 { - margin-bottom: -72px !important; -} - -.ml-n9, -.mx-n9 { - margin-left: -72px !important; -} - -.m-n10 { - margin: -80px !important; -} - -.mt-n10, -.my-n10 { - margin-top: -80px !important; -} - -.mr-n10, -.mx-n10 { - margin-right: -80px !important; -} - -.mb-n10, -.my-n10 { - margin-bottom: -80px !important; -} - -.ml-n10, -.mx-n10 { - margin-left: -80px !important; -} - -.m-n12 { - margin: -96px !important; -} - -.mt-n12, -.my-n12 { - margin-top: -96px !important; -} - -.mr-n12, -.mx-n12 { - margin-right: -96px !important; -} - -.mb-n12, -.my-n12 { - margin-bottom: -96px !important; -} - -.ml-n12, -.mx-n12 { - margin-left: -96px !important; -} - -.m-n15 { - margin: -120px !important; -} - -.mt-n15, -.my-n15 { - margin-top: -120px !important; -} - -.mr-n15, -.mx-n15 { - margin-right: -120px !important; -} - -.mb-n15, -.my-n15 { - margin-bottom: -120px !important; -} - -.ml-n15, -.mx-n15 { - margin-left: -120px !important; -} - -.m-auto { - margin: auto !important; -} - -.mt-auto, -.my-auto { - margin-top: auto !important; -} - -.mr-auto, -.mx-auto { - margin-right: auto !important; -} - -.mb-auto, -.my-auto { - margin-bottom: auto !important; -} - -.ml-auto, -.mx-auto { - margin-left: auto !important; -} - -@media (min-width: 400px) { - .m-xs-0 { - margin: 0 !important; - } - - .mt-xs-0, -.my-xs-0 { - margin-top: 0 !important; - } - - .mr-xs-0, -.mx-xs-0 { - margin-right: 0 !important; - } - - .mb-xs-0, -.my-xs-0 { - margin-bottom: 0 !important; - } - - .ml-xs-0, -.mx-xs-0 { - margin-left: 0 !important; - } - - .m-xs-1 { - margin: 8px !important; - } - - .mt-xs-1, -.my-xs-1 { - margin-top: 8px !important; - } - - .mr-xs-1, -.mx-xs-1 { - margin-right: 8px !important; - } - - .mb-xs-1, -.my-xs-1 { - margin-bottom: 8px !important; - } - - .ml-xs-1, -.mx-xs-1 { - margin-left: 8px !important; - } - - .m-xs-2 { - margin: 16px !important; - } - - .mt-xs-2, -.my-xs-2 { - margin-top: 16px !important; - } - - .mr-xs-2, -.mx-xs-2 { - margin-right: 16px !important; - } - - .mb-xs-2, -.my-xs-2 { - margin-bottom: 16px !important; - } - - .ml-xs-2, -.mx-xs-2 { - margin-left: 16px !important; - } - - .m-xs-3 { - margin: 24px !important; - } - - .mt-xs-3, -.my-xs-3 { - margin-top: 24px !important; - } - - .mr-xs-3, -.mx-xs-3 { - margin-right: 24px !important; - } - - .mb-xs-3, -.my-xs-3 { - margin-bottom: 24px !important; - } - - .ml-xs-3, -.mx-xs-3 { - margin-left: 24px !important; - } - - .m-xs-4 { - margin: 32px !important; - } - - .mt-xs-4, -.my-xs-4 { - margin-top: 32px !important; - } - - .mr-xs-4, -.mx-xs-4 { - margin-right: 32px !important; - } - - .mb-xs-4, -.my-xs-4 { - margin-bottom: 32px !important; - } - - .ml-xs-4, -.mx-xs-4 { - margin-left: 32px !important; - } - - .m-xs-5 { - margin: 40px !important; - } - - .mt-xs-5, -.my-xs-5 { - margin-top: 40px !important; - } - - .mr-xs-5, -.mx-xs-5 { - margin-right: 40px !important; - } - - .mb-xs-5, -.my-xs-5 { - margin-bottom: 40px !important; - } - - .ml-xs-5, -.mx-xs-5 { - margin-left: 40px !important; - } - - .m-xs-6 { - margin: 48px !important; - } - - .mt-xs-6, -.my-xs-6 { - margin-top: 48px !important; - } - - .mr-xs-6, -.mx-xs-6 { - margin-right: 48px !important; - } - - .mb-xs-6, -.my-xs-6 { - margin-bottom: 48px !important; - } - - .ml-xs-6, -.mx-xs-6 { - margin-left: 48px !important; - } - - .m-xs-7 { - margin: 56px !important; - } - - .mt-xs-7, -.my-xs-7 { - margin-top: 56px !important; - } - - .mr-xs-7, -.mx-xs-7 { - margin-right: 56px !important; - } - - .mb-xs-7, -.my-xs-7 { - margin-bottom: 56px !important; - } - - .ml-xs-7, -.mx-xs-7 { - margin-left: 56px !important; - } - - .m-xs-8 { - margin: 64px !important; - } - - .mt-xs-8, -.my-xs-8 { - margin-top: 64px !important; - } - - .mr-xs-8, -.mx-xs-8 { - margin-right: 64px !important; - } - - .mb-xs-8, -.my-xs-8 { - margin-bottom: 64px !important; - } - - .ml-xs-8, -.mx-xs-8 { - margin-left: 64px !important; - } - - .m-xs-9 { - margin: 72px !important; - } - - .mt-xs-9, -.my-xs-9 { - margin-top: 72px !important; - } - - .mr-xs-9, -.mx-xs-9 { - margin-right: 72px !important; - } - - .mb-xs-9, -.my-xs-9 { - margin-bottom: 72px !important; - } - - .ml-xs-9, -.mx-xs-9 { - margin-left: 72px !important; - } - - .m-xs-10 { - margin: 80px !important; - } - - .mt-xs-10, -.my-xs-10 { - margin-top: 80px !important; - } - - .mr-xs-10, -.mx-xs-10 { - margin-right: 80px !important; - } - - .mb-xs-10, -.my-xs-10 { - margin-bottom: 80px !important; - } - - .ml-xs-10, -.mx-xs-10 { - margin-left: 80px !important; - } - - .m-xs-12 { - margin: 96px !important; - } - - .mt-xs-12, -.my-xs-12 { - margin-top: 96px !important; - } - - .mr-xs-12, -.mx-xs-12 { - margin-right: 96px !important; - } - - .mb-xs-12, -.my-xs-12 { - margin-bottom: 96px !important; - } - - .ml-xs-12, -.mx-xs-12 { - margin-left: 96px !important; - } - - .m-xs-15 { - margin: 120px !important; - } - - .mt-xs-15, -.my-xs-15 { - margin-top: 120px !important; - } - - .mr-xs-15, -.mx-xs-15 { - margin-right: 120px !important; - } - - .mb-xs-15, -.my-xs-15 { - margin-bottom: 120px !important; - } - - .ml-xs-15, -.mx-xs-15 { - margin-left: 120px !important; - } - - .p-xs-0 { - padding: 0 !important; - } - - .pt-xs-0, -.py-xs-0 { - padding-top: 0 !important; - } - - .pr-xs-0, -.px-xs-0 { - padding-right: 0 !important; - } - - .pb-xs-0, -.py-xs-0 { - padding-bottom: 0 !important; - } - - .pl-xs-0, -.px-xs-0 { - padding-left: 0 !important; - } - - .p-xs-1 { - padding: 8px !important; - } - - .pt-xs-1, -.py-xs-1 { - padding-top: 8px !important; - } - - .pr-xs-1, -.px-xs-1 { - padding-right: 8px !important; - } - - .pb-xs-1, -.py-xs-1 { - padding-bottom: 8px !important; - } - - .pl-xs-1, -.px-xs-1 { - padding-left: 8px !important; - } - - .p-xs-2 { - padding: 16px !important; - } - - .pt-xs-2, -.py-xs-2 { - padding-top: 16px !important; - } - - .pr-xs-2, -.px-xs-2 { - padding-right: 16px !important; - } - - .pb-xs-2, -.py-xs-2 { - padding-bottom: 16px !important; - } - - .pl-xs-2, -.px-xs-2 { - padding-left: 16px !important; - } - - .p-xs-3 { - padding: 24px !important; - } - - .pt-xs-3, -.py-xs-3 { - padding-top: 24px !important; - } - - .pr-xs-3, -.px-xs-3 { - padding-right: 24px !important; - } - - .pb-xs-3, -.py-xs-3 { - padding-bottom: 24px !important; - } - - .pl-xs-3, -.px-xs-3 { - padding-left: 24px !important; - } - - .p-xs-4 { - padding: 32px !important; - } - - .pt-xs-4, -.py-xs-4 { - padding-top: 32px !important; - } - - .pr-xs-4, -.px-xs-4 { - padding-right: 32px !important; - } - - .pb-xs-4, -.py-xs-4 { - padding-bottom: 32px !important; - } - - .pl-xs-4, -.px-xs-4 { - padding-left: 32px !important; - } - - .p-xs-5 { - padding: 40px !important; - } - - .pt-xs-5, -.py-xs-5 { - padding-top: 40px !important; - } - - .pr-xs-5, -.px-xs-5 { - padding-right: 40px !important; - } - - .pb-xs-5, -.py-xs-5 { - padding-bottom: 40px !important; - } - - .pl-xs-5, -.px-xs-5 { - padding-left: 40px !important; - } - - .p-xs-6 { - padding: 48px !important; - } - - .pt-xs-6, -.py-xs-6 { - padding-top: 48px !important; - } - - .pr-xs-6, -.px-xs-6 { - padding-right: 48px !important; - } - - .pb-xs-6, -.py-xs-6 { - padding-bottom: 48px !important; - } - - .pl-xs-6, -.px-xs-6 { - padding-left: 48px !important; - } - - .p-xs-7 { - padding: 56px !important; - } - - .pt-xs-7, -.py-xs-7 { - padding-top: 56px !important; - } - - .pr-xs-7, -.px-xs-7 { - padding-right: 56px !important; - } - - .pb-xs-7, -.py-xs-7 { - padding-bottom: 56px !important; - } - - .pl-xs-7, -.px-xs-7 { - padding-left: 56px !important; - } - - .p-xs-8 { - padding: 64px !important; - } - - .pt-xs-8, -.py-xs-8 { - padding-top: 64px !important; - } - - .pr-xs-8, -.px-xs-8 { - padding-right: 64px !important; - } - - .pb-xs-8, -.py-xs-8 { - padding-bottom: 64px !important; - } - - .pl-xs-8, -.px-xs-8 { - padding-left: 64px !important; - } - - .p-xs-9 { - padding: 72px !important; - } - - .pt-xs-9, -.py-xs-9 { - padding-top: 72px !important; - } - - .pr-xs-9, -.px-xs-9 { - padding-right: 72px !important; - } - - .pb-xs-9, -.py-xs-9 { - padding-bottom: 72px !important; - } - - .pl-xs-9, -.px-xs-9 { - padding-left: 72px !important; - } - - .p-xs-10 { - padding: 80px !important; - } - - .pt-xs-10, -.py-xs-10 { - padding-top: 80px !important; - } - - .pr-xs-10, -.px-xs-10 { - padding-right: 80px !important; - } - - .pb-xs-10, -.py-xs-10 { - padding-bottom: 80px !important; - } - - .pl-xs-10, -.px-xs-10 { - padding-left: 80px !important; - } - - .p-xs-12 { - padding: 96px !important; - } - - .pt-xs-12, -.py-xs-12 { - padding-top: 96px !important; - } - - .pr-xs-12, -.px-xs-12 { - padding-right: 96px !important; - } - - .pb-xs-12, -.py-xs-12 { - padding-bottom: 96px !important; - } - - .pl-xs-12, -.px-xs-12 { - padding-left: 96px !important; - } - - .p-xs-15 { - padding: 120px !important; - } - - .pt-xs-15, -.py-xs-15 { - padding-top: 120px !important; - } - - .pr-xs-15, -.px-xs-15 { - padding-right: 120px !important; - } - - .pb-xs-15, -.py-xs-15 { - padding-bottom: 120px !important; - } - - .pl-xs-15, -.px-xs-15 { - padding-left: 120px !important; - } - - .m-xs-n1 { - margin: -8px !important; - } - - .mt-xs-n1, -.my-xs-n1 { - margin-top: -8px !important; - } - - .mr-xs-n1, -.mx-xs-n1 { - margin-right: -8px !important; - } - - .mb-xs-n1, -.my-xs-n1 { - margin-bottom: -8px !important; - } - - .ml-xs-n1, -.mx-xs-n1 { - margin-left: -8px !important; - } - - .m-xs-n2 { - margin: -16px !important; - } - - .mt-xs-n2, -.my-xs-n2 { - margin-top: -16px !important; - } - - .mr-xs-n2, -.mx-xs-n2 { - margin-right: -16px !important; - } - - .mb-xs-n2, -.my-xs-n2 { - margin-bottom: -16px !important; - } - - .ml-xs-n2, -.mx-xs-n2 { - margin-left: -16px !important; - } - - .m-xs-n3 { - margin: -24px !important; - } - - .mt-xs-n3, -.my-xs-n3 { - margin-top: -24px !important; - } - - .mr-xs-n3, -.mx-xs-n3 { - margin-right: -24px !important; - } - - .mb-xs-n3, -.my-xs-n3 { - margin-bottom: -24px !important; - } - - .ml-xs-n3, -.mx-xs-n3 { - margin-left: -24px !important; - } - - .m-xs-n4 { - margin: -32px !important; - } - - .mt-xs-n4, -.my-xs-n4 { - margin-top: -32px !important; - } - - .mr-xs-n4, -.mx-xs-n4 { - margin-right: -32px !important; - } - - .mb-xs-n4, -.my-xs-n4 { - margin-bottom: -32px !important; - } - - .ml-xs-n4, -.mx-xs-n4 { - margin-left: -32px !important; - } - - .m-xs-n5 { - margin: -40px !important; - } - - .mt-xs-n5, -.my-xs-n5 { - margin-top: -40px !important; - } - - .mr-xs-n5, -.mx-xs-n5 { - margin-right: -40px !important; - } - - .mb-xs-n5, -.my-xs-n5 { - margin-bottom: -40px !important; - } - - .ml-xs-n5, -.mx-xs-n5 { - margin-left: -40px !important; - } - - .m-xs-n6 { - margin: -48px !important; - } - - .mt-xs-n6, -.my-xs-n6 { - margin-top: -48px !important; - } - - .mr-xs-n6, -.mx-xs-n6 { - margin-right: -48px !important; - } - - .mb-xs-n6, -.my-xs-n6 { - margin-bottom: -48px !important; - } - - .ml-xs-n6, -.mx-xs-n6 { - margin-left: -48px !important; - } - - .m-xs-n7 { - margin: -56px !important; - } - - .mt-xs-n7, -.my-xs-n7 { - margin-top: -56px !important; - } - - .mr-xs-n7, -.mx-xs-n7 { - margin-right: -56px !important; - } - - .mb-xs-n7, -.my-xs-n7 { - margin-bottom: -56px !important; - } - - .ml-xs-n7, -.mx-xs-n7 { - margin-left: -56px !important; - } - - .m-xs-n8 { - margin: -64px !important; - } - - .mt-xs-n8, -.my-xs-n8 { - margin-top: -64px !important; - } - - .mr-xs-n8, -.mx-xs-n8 { - margin-right: -64px !important; - } - - .mb-xs-n8, -.my-xs-n8 { - margin-bottom: -64px !important; - } - - .ml-xs-n8, -.mx-xs-n8 { - margin-left: -64px !important; - } - - .m-xs-n9 { - margin: -72px !important; - } - - .mt-xs-n9, -.my-xs-n9 { - margin-top: -72px !important; - } - - .mr-xs-n9, -.mx-xs-n9 { - margin-right: -72px !important; - } - - .mb-xs-n9, -.my-xs-n9 { - margin-bottom: -72px !important; - } - - .ml-xs-n9, -.mx-xs-n9 { - margin-left: -72px !important; - } - - .m-xs-n10 { - margin: -80px !important; - } - - .mt-xs-n10, -.my-xs-n10 { - margin-top: -80px !important; - } - - .mr-xs-n10, -.mx-xs-n10 { - margin-right: -80px !important; - } - - .mb-xs-n10, -.my-xs-n10 { - margin-bottom: -80px !important; - } - - .ml-xs-n10, -.mx-xs-n10 { - margin-left: -80px !important; - } - - .m-xs-n12 { - margin: -96px !important; - } - - .mt-xs-n12, -.my-xs-n12 { - margin-top: -96px !important; - } - - .mr-xs-n12, -.mx-xs-n12 { - margin-right: -96px !important; - } - - .mb-xs-n12, -.my-xs-n12 { - margin-bottom: -96px !important; - } - - .ml-xs-n12, -.mx-xs-n12 { - margin-left: -96px !important; - } - - .m-xs-n15 { - margin: -120px !important; - } - - .mt-xs-n15, -.my-xs-n15 { - margin-top: -120px !important; - } - - .mr-xs-n15, -.mx-xs-n15 { - margin-right: -120px !important; - } - - .mb-xs-n15, -.my-xs-n15 { - margin-bottom: -120px !important; - } - - .ml-xs-n15, -.mx-xs-n15 { - margin-left: -120px !important; - } - - .m-xs-auto { - margin: auto !important; - } - - .mt-xs-auto, -.my-xs-auto { - margin-top: auto !important; - } - - .mr-xs-auto, -.mx-xs-auto { - margin-right: auto !important; - } - - .mb-xs-auto, -.my-xs-auto { - margin-bottom: auto !important; - } - - .ml-xs-auto, -.mx-xs-auto { - margin-left: auto !important; - } -} -@media (min-width: 616px) { - .m-sm-0 { - margin: 0 !important; - } - - .mt-sm-0, -.my-sm-0 { - margin-top: 0 !important; - } - - .mr-sm-0, -.mx-sm-0 { - margin-right: 0 !important; - } - - .mb-sm-0, -.my-sm-0 { - margin-bottom: 0 !important; - } - - .ml-sm-0, -.mx-sm-0 { - margin-left: 0 !important; - } - - .m-sm-1 { - margin: 8px !important; - } - - .mt-sm-1, -.my-sm-1 { - margin-top: 8px !important; - } - - .mr-sm-1, -.mx-sm-1 { - margin-right: 8px !important; - } - - .mb-sm-1, -.my-sm-1 { - margin-bottom: 8px !important; - } - - .ml-sm-1, -.mx-sm-1 { - margin-left: 8px !important; - } - - .m-sm-2 { - margin: 16px !important; - } - - .mt-sm-2, -.my-sm-2 { - margin-top: 16px !important; - } - - .mr-sm-2, -.mx-sm-2 { - margin-right: 16px !important; - } - - .mb-sm-2, -.my-sm-2 { - margin-bottom: 16px !important; - } - - .ml-sm-2, -.mx-sm-2 { - margin-left: 16px !important; - } - - .m-sm-3 { - margin: 24px !important; - } - - .mt-sm-3, -.my-sm-3 { - margin-top: 24px !important; - } - - .mr-sm-3, -.mx-sm-3 { - margin-right: 24px !important; - } - - .mb-sm-3, -.my-sm-3 { - margin-bottom: 24px !important; - } - - .ml-sm-3, -.mx-sm-3 { - margin-left: 24px !important; - } - - .m-sm-4 { - margin: 32px !important; - } - - .mt-sm-4, -.my-sm-4 { - margin-top: 32px !important; - } - - .mr-sm-4, -.mx-sm-4 { - margin-right: 32px !important; - } - - .mb-sm-4, -.my-sm-4 { - margin-bottom: 32px !important; - } - - .ml-sm-4, -.mx-sm-4 { - margin-left: 32px !important; - } - - .m-sm-5 { - margin: 40px !important; - } - - .mt-sm-5, -.my-sm-5 { - margin-top: 40px !important; - } - - .mr-sm-5, -.mx-sm-5 { - margin-right: 40px !important; - } - - .mb-sm-5, -.my-sm-5 { - margin-bottom: 40px !important; - } - - .ml-sm-5, -.mx-sm-5 { - margin-left: 40px !important; - } - - .m-sm-6 { - margin: 48px !important; - } - - .mt-sm-6, -.my-sm-6 { - margin-top: 48px !important; - } - - .mr-sm-6, -.mx-sm-6 { - margin-right: 48px !important; - } - - .mb-sm-6, -.my-sm-6 { - margin-bottom: 48px !important; - } - - .ml-sm-6, -.mx-sm-6 { - margin-left: 48px !important; - } - - .m-sm-7 { - margin: 56px !important; - } - - .mt-sm-7, -.my-sm-7 { - margin-top: 56px !important; - } - - .mr-sm-7, -.mx-sm-7 { - margin-right: 56px !important; - } - - .mb-sm-7, -.my-sm-7 { - margin-bottom: 56px !important; - } - - .ml-sm-7, -.mx-sm-7 { - margin-left: 56px !important; - } - - .m-sm-8 { - margin: 64px !important; - } - - .mt-sm-8, -.my-sm-8 { - margin-top: 64px !important; - } - - .mr-sm-8, -.mx-sm-8 { - margin-right: 64px !important; - } - - .mb-sm-8, -.my-sm-8 { - margin-bottom: 64px !important; - } - - .ml-sm-8, -.mx-sm-8 { - margin-left: 64px !important; - } - - .m-sm-9 { - margin: 72px !important; - } - - .mt-sm-9, -.my-sm-9 { - margin-top: 72px !important; - } - - .mr-sm-9, -.mx-sm-9 { - margin-right: 72px !important; - } - - .mb-sm-9, -.my-sm-9 { - margin-bottom: 72px !important; - } - - .ml-sm-9, -.mx-sm-9 { - margin-left: 72px !important; - } - - .m-sm-10 { - margin: 80px !important; - } - - .mt-sm-10, -.my-sm-10 { - margin-top: 80px !important; - } - - .mr-sm-10, -.mx-sm-10 { - margin-right: 80px !important; - } - - .mb-sm-10, -.my-sm-10 { - margin-bottom: 80px !important; - } - - .ml-sm-10, -.mx-sm-10 { - margin-left: 80px !important; - } - - .m-sm-12 { - margin: 96px !important; - } - - .mt-sm-12, -.my-sm-12 { - margin-top: 96px !important; - } - - .mr-sm-12, -.mx-sm-12 { - margin-right: 96px !important; - } - - .mb-sm-12, -.my-sm-12 { - margin-bottom: 96px !important; - } - - .ml-sm-12, -.mx-sm-12 { - margin-left: 96px !important; - } - - .m-sm-15 { - margin: 120px !important; - } - - .mt-sm-15, -.my-sm-15 { - margin-top: 120px !important; - } - - .mr-sm-15, -.mx-sm-15 { - margin-right: 120px !important; - } - - .mb-sm-15, -.my-sm-15 { - margin-bottom: 120px !important; - } - - .ml-sm-15, -.mx-sm-15 { - margin-left: 120px !important; - } - - .p-sm-0 { - padding: 0 !important; - } - - .pt-sm-0, -.py-sm-0 { - padding-top: 0 !important; - } - - .pr-sm-0, -.px-sm-0 { - padding-right: 0 !important; - } - - .pb-sm-0, -.py-sm-0 { - padding-bottom: 0 !important; - } - - .pl-sm-0, -.px-sm-0 { - padding-left: 0 !important; - } - - .p-sm-1 { - padding: 8px !important; - } - - .pt-sm-1, -.py-sm-1 { - padding-top: 8px !important; - } - - .pr-sm-1, -.px-sm-1 { - padding-right: 8px !important; - } - - .pb-sm-1, -.py-sm-1 { - padding-bottom: 8px !important; - } - - .pl-sm-1, -.px-sm-1 { - padding-left: 8px !important; - } - - .p-sm-2 { - padding: 16px !important; - } - - .pt-sm-2, -.py-sm-2 { - padding-top: 16px !important; - } - - .pr-sm-2, -.px-sm-2 { - padding-right: 16px !important; - } - - .pb-sm-2, -.py-sm-2 { - padding-bottom: 16px !important; - } - - .pl-sm-2, -.px-sm-2 { - padding-left: 16px !important; - } - - .p-sm-3 { - padding: 24px !important; - } - - .pt-sm-3, -.py-sm-3 { - padding-top: 24px !important; - } - - .pr-sm-3, -.px-sm-3 { - padding-right: 24px !important; - } - - .pb-sm-3, -.py-sm-3 { - padding-bottom: 24px !important; - } - - .pl-sm-3, -.px-sm-3 { - padding-left: 24px !important; - } - - .p-sm-4 { - padding: 32px !important; - } - - .pt-sm-4, -.py-sm-4 { - padding-top: 32px !important; - } - - .pr-sm-4, -.px-sm-4 { - padding-right: 32px !important; - } - - .pb-sm-4, -.py-sm-4 { - padding-bottom: 32px !important; - } - - .pl-sm-4, -.px-sm-4 { - padding-left: 32px !important; - } - - .p-sm-5 { - padding: 40px !important; - } - - .pt-sm-5, -.py-sm-5 { - padding-top: 40px !important; - } - - .pr-sm-5, -.px-sm-5 { - padding-right: 40px !important; - } - - .pb-sm-5, -.py-sm-5 { - padding-bottom: 40px !important; - } - - .pl-sm-5, -.px-sm-5 { - padding-left: 40px !important; - } - - .p-sm-6 { - padding: 48px !important; - } - - .pt-sm-6, -.py-sm-6 { - padding-top: 48px !important; - } - - .pr-sm-6, -.px-sm-6 { - padding-right: 48px !important; - } - - .pb-sm-6, -.py-sm-6 { - padding-bottom: 48px !important; - } - - .pl-sm-6, -.px-sm-6 { - padding-left: 48px !important; - } - - .p-sm-7 { - padding: 56px !important; - } - - .pt-sm-7, -.py-sm-7 { - padding-top: 56px !important; - } - - .pr-sm-7, -.px-sm-7 { - padding-right: 56px !important; - } - - .pb-sm-7, -.py-sm-7 { - padding-bottom: 56px !important; - } - - .pl-sm-7, -.px-sm-7 { - padding-left: 56px !important; - } - - .p-sm-8 { - padding: 64px !important; - } - - .pt-sm-8, -.py-sm-8 { - padding-top: 64px !important; - } - - .pr-sm-8, -.px-sm-8 { - padding-right: 64px !important; - } - - .pb-sm-8, -.py-sm-8 { - padding-bottom: 64px !important; - } - - .pl-sm-8, -.px-sm-8 { - padding-left: 64px !important; - } - - .p-sm-9 { - padding: 72px !important; - } - - .pt-sm-9, -.py-sm-9 { - padding-top: 72px !important; - } - - .pr-sm-9, -.px-sm-9 { - padding-right: 72px !important; - } - - .pb-sm-9, -.py-sm-9 { - padding-bottom: 72px !important; - } - - .pl-sm-9, -.px-sm-9 { - padding-left: 72px !important; - } - - .p-sm-10 { - padding: 80px !important; - } - - .pt-sm-10, -.py-sm-10 { - padding-top: 80px !important; - } - - .pr-sm-10, -.px-sm-10 { - padding-right: 80px !important; - } - - .pb-sm-10, -.py-sm-10 { - padding-bottom: 80px !important; - } - - .pl-sm-10, -.px-sm-10 { - padding-left: 80px !important; - } - - .p-sm-12 { - padding: 96px !important; - } - - .pt-sm-12, -.py-sm-12 { - padding-top: 96px !important; - } - - .pr-sm-12, -.px-sm-12 { - padding-right: 96px !important; - } - - .pb-sm-12, -.py-sm-12 { - padding-bottom: 96px !important; - } - - .pl-sm-12, -.px-sm-12 { - padding-left: 96px !important; - } - - .p-sm-15 { - padding: 120px !important; - } - - .pt-sm-15, -.py-sm-15 { - padding-top: 120px !important; - } - - .pr-sm-15, -.px-sm-15 { - padding-right: 120px !important; - } - - .pb-sm-15, -.py-sm-15 { - padding-bottom: 120px !important; - } - - .pl-sm-15, -.px-sm-15 { - padding-left: 120px !important; - } - - .m-sm-n1 { - margin: -8px !important; - } - - .mt-sm-n1, -.my-sm-n1 { - margin-top: -8px !important; - } - - .mr-sm-n1, -.mx-sm-n1 { - margin-right: -8px !important; - } - - .mb-sm-n1, -.my-sm-n1 { - margin-bottom: -8px !important; - } - - .ml-sm-n1, -.mx-sm-n1 { - margin-left: -8px !important; - } - - .m-sm-n2 { - margin: -16px !important; - } - - .mt-sm-n2, -.my-sm-n2 { - margin-top: -16px !important; - } - - .mr-sm-n2, -.mx-sm-n2 { - margin-right: -16px !important; - } - - .mb-sm-n2, -.my-sm-n2 { - margin-bottom: -16px !important; - } - - .ml-sm-n2, -.mx-sm-n2 { - margin-left: -16px !important; - } - - .m-sm-n3 { - margin: -24px !important; - } - - .mt-sm-n3, -.my-sm-n3 { - margin-top: -24px !important; - } - - .mr-sm-n3, -.mx-sm-n3 { - margin-right: -24px !important; - } - - .mb-sm-n3, -.my-sm-n3 { - margin-bottom: -24px !important; - } - - .ml-sm-n3, -.mx-sm-n3 { - margin-left: -24px !important; - } - - .m-sm-n4 { - margin: -32px !important; - } - - .mt-sm-n4, -.my-sm-n4 { - margin-top: -32px !important; - } - - .mr-sm-n4, -.mx-sm-n4 { - margin-right: -32px !important; - } - - .mb-sm-n4, -.my-sm-n4 { - margin-bottom: -32px !important; - } - - .ml-sm-n4, -.mx-sm-n4 { - margin-left: -32px !important; - } - - .m-sm-n5 { - margin: -40px !important; - } - - .mt-sm-n5, -.my-sm-n5 { - margin-top: -40px !important; - } - - .mr-sm-n5, -.mx-sm-n5 { - margin-right: -40px !important; - } - - .mb-sm-n5, -.my-sm-n5 { - margin-bottom: -40px !important; - } - - .ml-sm-n5, -.mx-sm-n5 { - margin-left: -40px !important; - } - - .m-sm-n6 { - margin: -48px !important; - } - - .mt-sm-n6, -.my-sm-n6 { - margin-top: -48px !important; - } - - .mr-sm-n6, -.mx-sm-n6 { - margin-right: -48px !important; - } - - .mb-sm-n6, -.my-sm-n6 { - margin-bottom: -48px !important; - } - - .ml-sm-n6, -.mx-sm-n6 { - margin-left: -48px !important; - } - - .m-sm-n7 { - margin: -56px !important; - } - - .mt-sm-n7, -.my-sm-n7 { - margin-top: -56px !important; - } - - .mr-sm-n7, -.mx-sm-n7 { - margin-right: -56px !important; - } - - .mb-sm-n7, -.my-sm-n7 { - margin-bottom: -56px !important; - } - - .ml-sm-n7, -.mx-sm-n7 { - margin-left: -56px !important; - } - - .m-sm-n8 { - margin: -64px !important; - } - - .mt-sm-n8, -.my-sm-n8 { - margin-top: -64px !important; - } - - .mr-sm-n8, -.mx-sm-n8 { - margin-right: -64px !important; - } - - .mb-sm-n8, -.my-sm-n8 { - margin-bottom: -64px !important; - } - - .ml-sm-n8, -.mx-sm-n8 { - margin-left: -64px !important; - } - - .m-sm-n9 { - margin: -72px !important; - } - - .mt-sm-n9, -.my-sm-n9 { - margin-top: -72px !important; - } - - .mr-sm-n9, -.mx-sm-n9 { - margin-right: -72px !important; - } - - .mb-sm-n9, -.my-sm-n9 { - margin-bottom: -72px !important; - } - - .ml-sm-n9, -.mx-sm-n9 { - margin-left: -72px !important; - } - - .m-sm-n10 { - margin: -80px !important; - } - - .mt-sm-n10, -.my-sm-n10 { - margin-top: -80px !important; - } - - .mr-sm-n10, -.mx-sm-n10 { - margin-right: -80px !important; - } - - .mb-sm-n10, -.my-sm-n10 { - margin-bottom: -80px !important; - } - - .ml-sm-n10, -.mx-sm-n10 { - margin-left: -80px !important; - } - - .m-sm-n12 { - margin: -96px !important; - } - - .mt-sm-n12, -.my-sm-n12 { - margin-top: -96px !important; - } - - .mr-sm-n12, -.mx-sm-n12 { - margin-right: -96px !important; - } - - .mb-sm-n12, -.my-sm-n12 { - margin-bottom: -96px !important; - } - - .ml-sm-n12, -.mx-sm-n12 { - margin-left: -96px !important; - } - - .m-sm-n15 { - margin: -120px !important; - } - - .mt-sm-n15, -.my-sm-n15 { - margin-top: -120px !important; - } - - .mr-sm-n15, -.mx-sm-n15 { - margin-right: -120px !important; - } - - .mb-sm-n15, -.my-sm-n15 { - margin-bottom: -120px !important; - } - - .ml-sm-n15, -.mx-sm-n15 { - margin-left: -120px !important; - } - - .m-sm-auto { - margin: auto !important; - } - - .mt-sm-auto, -.my-sm-auto { - margin-top: auto !important; - } - - .mr-sm-auto, -.mx-sm-auto { - margin-right: auto !important; - } - - .mb-sm-auto, -.my-sm-auto { - margin-bottom: auto !important; - } - - .ml-sm-auto, -.mx-sm-auto { - margin-left: auto !important; - } -} -@media (min-width: 768px) { - .m-md-0 { - margin: 0 !important; - } - - .mt-md-0, -.my-md-0 { - margin-top: 0 !important; - } - - .mr-md-0, -.mx-md-0 { - margin-right: 0 !important; - } - - .mb-md-0, -.my-md-0 { - margin-bottom: 0 !important; - } - - .ml-md-0, -.mx-md-0 { - margin-left: 0 !important; - } - - .m-md-1 { - margin: 8px !important; - } - - .mt-md-1, -.my-md-1 { - margin-top: 8px !important; - } - - .mr-md-1, -.mx-md-1 { - margin-right: 8px !important; - } - - .mb-md-1, -.my-md-1 { - margin-bottom: 8px !important; - } - - .ml-md-1, -.mx-md-1 { - margin-left: 8px !important; - } - - .m-md-2 { - margin: 16px !important; - } - - .mt-md-2, -.my-md-2 { - margin-top: 16px !important; - } - - .mr-md-2, -.mx-md-2 { - margin-right: 16px !important; - } - - .mb-md-2, -.my-md-2 { - margin-bottom: 16px !important; - } - - .ml-md-2, -.mx-md-2 { - margin-left: 16px !important; - } - - .m-md-3 { - margin: 24px !important; - } - - .mt-md-3, -.my-md-3 { - margin-top: 24px !important; - } - - .mr-md-3, -.mx-md-3 { - margin-right: 24px !important; - } - - .mb-md-3, -.my-md-3 { - margin-bottom: 24px !important; - } - - .ml-md-3, -.mx-md-3 { - margin-left: 24px !important; - } - - .m-md-4 { - margin: 32px !important; - } - - .mt-md-4, -.my-md-4 { - margin-top: 32px !important; - } - - .mr-md-4, -.mx-md-4 { - margin-right: 32px !important; - } - - .mb-md-4, -.my-md-4 { - margin-bottom: 32px !important; - } - - .ml-md-4, -.mx-md-4 { - margin-left: 32px !important; - } - - .m-md-5 { - margin: 40px !important; - } - - .mt-md-5, -.my-md-5 { - margin-top: 40px !important; - } - - .mr-md-5, -.mx-md-5 { - margin-right: 40px !important; - } - - .mb-md-5, -.my-md-5 { - margin-bottom: 40px !important; - } - - .ml-md-5, -.mx-md-5 { - margin-left: 40px !important; - } - - .m-md-6 { - margin: 48px !important; - } - - .mt-md-6, -.my-md-6 { - margin-top: 48px !important; - } - - .mr-md-6, -.mx-md-6 { - margin-right: 48px !important; - } - - .mb-md-6, -.my-md-6 { - margin-bottom: 48px !important; - } - - .ml-md-6, -.mx-md-6 { - margin-left: 48px !important; - } - - .m-md-7 { - margin: 56px !important; - } - - .mt-md-7, -.my-md-7 { - margin-top: 56px !important; - } - - .mr-md-7, -.mx-md-7 { - margin-right: 56px !important; - } - - .mb-md-7, -.my-md-7 { - margin-bottom: 56px !important; - } - - .ml-md-7, -.mx-md-7 { - margin-left: 56px !important; - } - - .m-md-8 { - margin: 64px !important; - } - - .mt-md-8, -.my-md-8 { - margin-top: 64px !important; - } - - .mr-md-8, -.mx-md-8 { - margin-right: 64px !important; - } - - .mb-md-8, -.my-md-8 { - margin-bottom: 64px !important; - } - - .ml-md-8, -.mx-md-8 { - margin-left: 64px !important; - } - - .m-md-9 { - margin: 72px !important; - } - - .mt-md-9, -.my-md-9 { - margin-top: 72px !important; - } - - .mr-md-9, -.mx-md-9 { - margin-right: 72px !important; - } - - .mb-md-9, -.my-md-9 { - margin-bottom: 72px !important; - } - - .ml-md-9, -.mx-md-9 { - margin-left: 72px !important; - } - - .m-md-10 { - margin: 80px !important; - } - - .mt-md-10, -.my-md-10 { - margin-top: 80px !important; - } - - .mr-md-10, -.mx-md-10 { - margin-right: 80px !important; - } - - .mb-md-10, -.my-md-10 { - margin-bottom: 80px !important; - } - - .ml-md-10, -.mx-md-10 { - margin-left: 80px !important; - } - - .m-md-12 { - margin: 96px !important; - } - - .mt-md-12, -.my-md-12 { - margin-top: 96px !important; - } - - .mr-md-12, -.mx-md-12 { - margin-right: 96px !important; - } - - .mb-md-12, -.my-md-12 { - margin-bottom: 96px !important; - } - - .ml-md-12, -.mx-md-12 { - margin-left: 96px !important; - } - - .m-md-15 { - margin: 120px !important; - } - - .mt-md-15, -.my-md-15 { - margin-top: 120px !important; - } - - .mr-md-15, -.mx-md-15 { - margin-right: 120px !important; - } - - .mb-md-15, -.my-md-15 { - margin-bottom: 120px !important; - } - - .ml-md-15, -.mx-md-15 { - margin-left: 120px !important; - } - - .p-md-0 { - padding: 0 !important; - } - - .pt-md-0, -.py-md-0 { - padding-top: 0 !important; - } - - .pr-md-0, -.px-md-0 { - padding-right: 0 !important; - } - - .pb-md-0, -.py-md-0 { - padding-bottom: 0 !important; - } - - .pl-md-0, -.px-md-0 { - padding-left: 0 !important; - } - - .p-md-1 { - padding: 8px !important; - } - - .pt-md-1, -.py-md-1 { - padding-top: 8px !important; - } - - .pr-md-1, -.px-md-1 { - padding-right: 8px !important; - } - - .pb-md-1, -.py-md-1 { - padding-bottom: 8px !important; - } - - .pl-md-1, -.px-md-1 { - padding-left: 8px !important; - } - - .p-md-2 { - padding: 16px !important; - } - - .pt-md-2, -.py-md-2 { - padding-top: 16px !important; - } - - .pr-md-2, -.px-md-2 { - padding-right: 16px !important; - } - - .pb-md-2, -.py-md-2 { - padding-bottom: 16px !important; - } - - .pl-md-2, -.px-md-2 { - padding-left: 16px !important; - } - - .p-md-3 { - padding: 24px !important; - } - - .pt-md-3, -.py-md-3 { - padding-top: 24px !important; - } - - .pr-md-3, -.px-md-3 { - padding-right: 24px !important; - } - - .pb-md-3, -.py-md-3 { - padding-bottom: 24px !important; - } - - .pl-md-3, -.px-md-3 { - padding-left: 24px !important; - } - - .p-md-4 { - padding: 32px !important; - } - - .pt-md-4, -.py-md-4 { - padding-top: 32px !important; - } - - .pr-md-4, -.px-md-4 { - padding-right: 32px !important; - } - - .pb-md-4, -.py-md-4 { - padding-bottom: 32px !important; - } - - .pl-md-4, -.px-md-4 { - padding-left: 32px !important; - } - - .p-md-5 { - padding: 40px !important; - } - - .pt-md-5, -.py-md-5 { - padding-top: 40px !important; - } - - .pr-md-5, -.px-md-5 { - padding-right: 40px !important; - } - - .pb-md-5, -.py-md-5 { - padding-bottom: 40px !important; - } - - .pl-md-5, -.px-md-5 { - padding-left: 40px !important; - } - - .p-md-6 { - padding: 48px !important; - } - - .pt-md-6, -.py-md-6 { - padding-top: 48px !important; - } - - .pr-md-6, -.px-md-6 { - padding-right: 48px !important; - } - - .pb-md-6, -.py-md-6 { - padding-bottom: 48px !important; - } - - .pl-md-6, -.px-md-6 { - padding-left: 48px !important; - } - - .p-md-7 { - padding: 56px !important; - } - - .pt-md-7, -.py-md-7 { - padding-top: 56px !important; - } - - .pr-md-7, -.px-md-7 { - padding-right: 56px !important; - } - - .pb-md-7, -.py-md-7 { - padding-bottom: 56px !important; - } - - .pl-md-7, -.px-md-7 { - padding-left: 56px !important; - } - - .p-md-8 { - padding: 64px !important; - } - - .pt-md-8, -.py-md-8 { - padding-top: 64px !important; - } - - .pr-md-8, -.px-md-8 { - padding-right: 64px !important; - } - - .pb-md-8, -.py-md-8 { - padding-bottom: 64px !important; - } - - .pl-md-8, -.px-md-8 { - padding-left: 64px !important; - } - - .p-md-9 { - padding: 72px !important; - } - - .pt-md-9, -.py-md-9 { - padding-top: 72px !important; - } - - .pr-md-9, -.px-md-9 { - padding-right: 72px !important; - } - - .pb-md-9, -.py-md-9 { - padding-bottom: 72px !important; - } - - .pl-md-9, -.px-md-9 { - padding-left: 72px !important; - } - - .p-md-10 { - padding: 80px !important; - } - - .pt-md-10, -.py-md-10 { - padding-top: 80px !important; - } - - .pr-md-10, -.px-md-10 { - padding-right: 80px !important; - } - - .pb-md-10, -.py-md-10 { - padding-bottom: 80px !important; - } - - .pl-md-10, -.px-md-10 { - padding-left: 80px !important; - } - - .p-md-12 { - padding: 96px !important; - } - - .pt-md-12, -.py-md-12 { - padding-top: 96px !important; - } - - .pr-md-12, -.px-md-12 { - padding-right: 96px !important; - } - - .pb-md-12, -.py-md-12 { - padding-bottom: 96px !important; - } - - .pl-md-12, -.px-md-12 { - padding-left: 96px !important; - } - - .p-md-15 { - padding: 120px !important; - } - - .pt-md-15, -.py-md-15 { - padding-top: 120px !important; - } - - .pr-md-15, -.px-md-15 { - padding-right: 120px !important; - } - - .pb-md-15, -.py-md-15 { - padding-bottom: 120px !important; - } - - .pl-md-15, -.px-md-15 { - padding-left: 120px !important; - } - - .m-md-n1 { - margin: -8px !important; - } - - .mt-md-n1, -.my-md-n1 { - margin-top: -8px !important; - } - - .mr-md-n1, -.mx-md-n1 { - margin-right: -8px !important; - } - - .mb-md-n1, -.my-md-n1 { - margin-bottom: -8px !important; - } - - .ml-md-n1, -.mx-md-n1 { - margin-left: -8px !important; - } - - .m-md-n2 { - margin: -16px !important; - } - - .mt-md-n2, -.my-md-n2 { - margin-top: -16px !important; - } - - .mr-md-n2, -.mx-md-n2 { - margin-right: -16px !important; - } - - .mb-md-n2, -.my-md-n2 { - margin-bottom: -16px !important; - } - - .ml-md-n2, -.mx-md-n2 { - margin-left: -16px !important; - } - - .m-md-n3 { - margin: -24px !important; - } - - .mt-md-n3, -.my-md-n3 { - margin-top: -24px !important; - } - - .mr-md-n3, -.mx-md-n3 { - margin-right: -24px !important; - } - - .mb-md-n3, -.my-md-n3 { - margin-bottom: -24px !important; - } - - .ml-md-n3, -.mx-md-n3 { - margin-left: -24px !important; - } - - .m-md-n4 { - margin: -32px !important; - } - - .mt-md-n4, -.my-md-n4 { - margin-top: -32px !important; - } - - .mr-md-n4, -.mx-md-n4 { - margin-right: -32px !important; - } - - .mb-md-n4, -.my-md-n4 { - margin-bottom: -32px !important; - } - - .ml-md-n4, -.mx-md-n4 { - margin-left: -32px !important; - } - - .m-md-n5 { - margin: -40px !important; - } - - .mt-md-n5, -.my-md-n5 { - margin-top: -40px !important; - } - - .mr-md-n5, -.mx-md-n5 { - margin-right: -40px !important; - } - - .mb-md-n5, -.my-md-n5 { - margin-bottom: -40px !important; - } - - .ml-md-n5, -.mx-md-n5 { - margin-left: -40px !important; - } - - .m-md-n6 { - margin: -48px !important; - } - - .mt-md-n6, -.my-md-n6 { - margin-top: -48px !important; - } - - .mr-md-n6, -.mx-md-n6 { - margin-right: -48px !important; - } - - .mb-md-n6, -.my-md-n6 { - margin-bottom: -48px !important; - } - - .ml-md-n6, -.mx-md-n6 { - margin-left: -48px !important; - } - - .m-md-n7 { - margin: -56px !important; - } - - .mt-md-n7, -.my-md-n7 { - margin-top: -56px !important; - } - - .mr-md-n7, -.mx-md-n7 { - margin-right: -56px !important; - } - - .mb-md-n7, -.my-md-n7 { - margin-bottom: -56px !important; - } - - .ml-md-n7, -.mx-md-n7 { - margin-left: -56px !important; - } - - .m-md-n8 { - margin: -64px !important; - } - - .mt-md-n8, -.my-md-n8 { - margin-top: -64px !important; - } - - .mr-md-n8, -.mx-md-n8 { - margin-right: -64px !important; - } - - .mb-md-n8, -.my-md-n8 { - margin-bottom: -64px !important; - } - - .ml-md-n8, -.mx-md-n8 { - margin-left: -64px !important; - } - - .m-md-n9 { - margin: -72px !important; - } - - .mt-md-n9, -.my-md-n9 { - margin-top: -72px !important; - } - - .mr-md-n9, -.mx-md-n9 { - margin-right: -72px !important; - } - - .mb-md-n9, -.my-md-n9 { - margin-bottom: -72px !important; - } - - .ml-md-n9, -.mx-md-n9 { - margin-left: -72px !important; - } - - .m-md-n10 { - margin: -80px !important; - } - - .mt-md-n10, -.my-md-n10 { - margin-top: -80px !important; - } - - .mr-md-n10, -.mx-md-n10 { - margin-right: -80px !important; - } - - .mb-md-n10, -.my-md-n10 { - margin-bottom: -80px !important; - } - - .ml-md-n10, -.mx-md-n10 { - margin-left: -80px !important; - } - - .m-md-n12 { - margin: -96px !important; - } - - .mt-md-n12, -.my-md-n12 { - margin-top: -96px !important; - } - - .mr-md-n12, -.mx-md-n12 { - margin-right: -96px !important; - } - - .mb-md-n12, -.my-md-n12 { - margin-bottom: -96px !important; - } - - .ml-md-n12, -.mx-md-n12 { - margin-left: -96px !important; - } - - .m-md-n15 { - margin: -120px !important; - } - - .mt-md-n15, -.my-md-n15 { - margin-top: -120px !important; - } - - .mr-md-n15, -.mx-md-n15 { - margin-right: -120px !important; - } - - .mb-md-n15, -.my-md-n15 { - margin-bottom: -120px !important; - } - - .ml-md-n15, -.mx-md-n15 { - margin-left: -120px !important; - } - - .m-md-auto { - margin: auto !important; - } - - .mt-md-auto, -.my-md-auto { - margin-top: auto !important; - } - - .mr-md-auto, -.mx-md-auto { - margin-right: auto !important; - } - - .mb-md-auto, -.my-md-auto { - margin-bottom: auto !important; - } - - .ml-md-auto, -.mx-md-auto { - margin-left: auto !important; - } -} -@media (min-width: 980px) { - .m-lg-0 { - margin: 0 !important; - } - - .mt-lg-0, -.my-lg-0 { - margin-top: 0 !important; - } - - .mr-lg-0, -.mx-lg-0 { - margin-right: 0 !important; - } - - .mb-lg-0, -.my-lg-0 { - margin-bottom: 0 !important; - } - - .ml-lg-0, -.mx-lg-0 { - margin-left: 0 !important; - } - - .m-lg-1 { - margin: 8px !important; - } - - .mt-lg-1, -.my-lg-1 { - margin-top: 8px !important; - } - - .mr-lg-1, -.mx-lg-1 { - margin-right: 8px !important; - } - - .mb-lg-1, -.my-lg-1 { - margin-bottom: 8px !important; - } - - .ml-lg-1, -.mx-lg-1 { - margin-left: 8px !important; - } - - .m-lg-2 { - margin: 16px !important; - } - - .mt-lg-2, -.my-lg-2 { - margin-top: 16px !important; - } - - .mr-lg-2, -.mx-lg-2 { - margin-right: 16px !important; - } - - .mb-lg-2, -.my-lg-2 { - margin-bottom: 16px !important; - } - - .ml-lg-2, -.mx-lg-2 { - margin-left: 16px !important; - } - - .m-lg-3 { - margin: 24px !important; - } - - .mt-lg-3, -.my-lg-3 { - margin-top: 24px !important; - } - - .mr-lg-3, -.mx-lg-3 { - margin-right: 24px !important; - } - - .mb-lg-3, -.my-lg-3 { - margin-bottom: 24px !important; - } - - .ml-lg-3, -.mx-lg-3 { - margin-left: 24px !important; - } - - .m-lg-4 { - margin: 32px !important; - } - - .mt-lg-4, -.my-lg-4 { - margin-top: 32px !important; - } - - .mr-lg-4, -.mx-lg-4 { - margin-right: 32px !important; - } - - .mb-lg-4, -.my-lg-4 { - margin-bottom: 32px !important; - } - - .ml-lg-4, -.mx-lg-4 { - margin-left: 32px !important; - } - - .m-lg-5 { - margin: 40px !important; - } - - .mt-lg-5, -.my-lg-5 { - margin-top: 40px !important; - } - - .mr-lg-5, -.mx-lg-5 { - margin-right: 40px !important; - } - - .mb-lg-5, -.my-lg-5 { - margin-bottom: 40px !important; - } - - .ml-lg-5, -.mx-lg-5 { - margin-left: 40px !important; - } - - .m-lg-6 { - margin: 48px !important; - } - - .mt-lg-6, -.my-lg-6 { - margin-top: 48px !important; - } - - .mr-lg-6, -.mx-lg-6 { - margin-right: 48px !important; - } - - .mb-lg-6, -.my-lg-6 { - margin-bottom: 48px !important; - } - - .ml-lg-6, -.mx-lg-6 { - margin-left: 48px !important; - } - - .m-lg-7 { - margin: 56px !important; - } - - .mt-lg-7, -.my-lg-7 { - margin-top: 56px !important; - } - - .mr-lg-7, -.mx-lg-7 { - margin-right: 56px !important; - } - - .mb-lg-7, -.my-lg-7 { - margin-bottom: 56px !important; - } - - .ml-lg-7, -.mx-lg-7 { - margin-left: 56px !important; - } - - .m-lg-8 { - margin: 64px !important; - } - - .mt-lg-8, -.my-lg-8 { - margin-top: 64px !important; - } - - .mr-lg-8, -.mx-lg-8 { - margin-right: 64px !important; - } - - .mb-lg-8, -.my-lg-8 { - margin-bottom: 64px !important; - } - - .ml-lg-8, -.mx-lg-8 { - margin-left: 64px !important; - } - - .m-lg-9 { - margin: 72px !important; - } - - .mt-lg-9, -.my-lg-9 { - margin-top: 72px !important; - } - - .mr-lg-9, -.mx-lg-9 { - margin-right: 72px !important; - } - - .mb-lg-9, -.my-lg-9 { - margin-bottom: 72px !important; - } - - .ml-lg-9, -.mx-lg-9 { - margin-left: 72px !important; - } - - .m-lg-10 { - margin: 80px !important; - } - - .mt-lg-10, -.my-lg-10 { - margin-top: 80px !important; - } - - .mr-lg-10, -.mx-lg-10 { - margin-right: 80px !important; - } - - .mb-lg-10, -.my-lg-10 { - margin-bottom: 80px !important; - } - - .ml-lg-10, -.mx-lg-10 { - margin-left: 80px !important; - } - - .m-lg-12 { - margin: 96px !important; - } - - .mt-lg-12, -.my-lg-12 { - margin-top: 96px !important; - } - - .mr-lg-12, -.mx-lg-12 { - margin-right: 96px !important; - } - - .mb-lg-12, -.my-lg-12 { - margin-bottom: 96px !important; - } - - .ml-lg-12, -.mx-lg-12 { - margin-left: 96px !important; - } - - .m-lg-15 { - margin: 120px !important; - } - - .mt-lg-15, -.my-lg-15 { - margin-top: 120px !important; - } - - .mr-lg-15, -.mx-lg-15 { - margin-right: 120px !important; - } - - .mb-lg-15, -.my-lg-15 { - margin-bottom: 120px !important; - } - - .ml-lg-15, -.mx-lg-15 { - margin-left: 120px !important; - } - - .p-lg-0 { - padding: 0 !important; - } - - .pt-lg-0, -.py-lg-0 { - padding-top: 0 !important; - } - - .pr-lg-0, -.px-lg-0 { - padding-right: 0 !important; - } - - .pb-lg-0, -.py-lg-0 { - padding-bottom: 0 !important; - } - - .pl-lg-0, -.px-lg-0 { - padding-left: 0 !important; - } - - .p-lg-1 { - padding: 8px !important; - } - - .pt-lg-1, -.py-lg-1 { - padding-top: 8px !important; - } - - .pr-lg-1, -.px-lg-1 { - padding-right: 8px !important; - } - - .pb-lg-1, -.py-lg-1 { - padding-bottom: 8px !important; - } - - .pl-lg-1, -.px-lg-1 { - padding-left: 8px !important; - } - - .p-lg-2 { - padding: 16px !important; - } - - .pt-lg-2, -.py-lg-2 { - padding-top: 16px !important; - } - - .pr-lg-2, -.px-lg-2 { - padding-right: 16px !important; - } - - .pb-lg-2, -.py-lg-2 { - padding-bottom: 16px !important; - } - - .pl-lg-2, -.px-lg-2 { - padding-left: 16px !important; - } - - .p-lg-3 { - padding: 24px !important; - } - - .pt-lg-3, -.py-lg-3 { - padding-top: 24px !important; - } - - .pr-lg-3, -.px-lg-3 { - padding-right: 24px !important; - } - - .pb-lg-3, -.py-lg-3 { - padding-bottom: 24px !important; - } - - .pl-lg-3, -.px-lg-3 { - padding-left: 24px !important; - } - - .p-lg-4 { - padding: 32px !important; - } - - .pt-lg-4, -.py-lg-4 { - padding-top: 32px !important; - } - - .pr-lg-4, -.px-lg-4 { - padding-right: 32px !important; - } - - .pb-lg-4, -.py-lg-4 { - padding-bottom: 32px !important; - } - - .pl-lg-4, -.px-lg-4 { - padding-left: 32px !important; - } - - .p-lg-5 { - padding: 40px !important; - } - - .pt-lg-5, -.py-lg-5 { - padding-top: 40px !important; - } - - .pr-lg-5, -.px-lg-5 { - padding-right: 40px !important; - } - - .pb-lg-5, -.py-lg-5 { - padding-bottom: 40px !important; - } - - .pl-lg-5, -.px-lg-5 { - padding-left: 40px !important; - } - - .p-lg-6 { - padding: 48px !important; - } - - .pt-lg-6, -.py-lg-6 { - padding-top: 48px !important; - } - - .pr-lg-6, -.px-lg-6 { - padding-right: 48px !important; - } - - .pb-lg-6, -.py-lg-6 { - padding-bottom: 48px !important; - } - - .pl-lg-6, -.px-lg-6 { - padding-left: 48px !important; - } - - .p-lg-7 { - padding: 56px !important; - } - - .pt-lg-7, -.py-lg-7 { - padding-top: 56px !important; - } - - .pr-lg-7, -.px-lg-7 { - padding-right: 56px !important; - } - - .pb-lg-7, -.py-lg-7 { - padding-bottom: 56px !important; - } - - .pl-lg-7, -.px-lg-7 { - padding-left: 56px !important; - } - - .p-lg-8 { - padding: 64px !important; - } - - .pt-lg-8, -.py-lg-8 { - padding-top: 64px !important; - } - - .pr-lg-8, -.px-lg-8 { - padding-right: 64px !important; - } - - .pb-lg-8, -.py-lg-8 { - padding-bottom: 64px !important; - } - - .pl-lg-8, -.px-lg-8 { - padding-left: 64px !important; - } - - .p-lg-9 { - padding: 72px !important; - } - - .pt-lg-9, -.py-lg-9 { - padding-top: 72px !important; - } - - .pr-lg-9, -.px-lg-9 { - padding-right: 72px !important; - } - - .pb-lg-9, -.py-lg-9 { - padding-bottom: 72px !important; - } - - .pl-lg-9, -.px-lg-9 { - padding-left: 72px !important; - } - - .p-lg-10 { - padding: 80px !important; - } - - .pt-lg-10, -.py-lg-10 { - padding-top: 80px !important; - } - - .pr-lg-10, -.px-lg-10 { - padding-right: 80px !important; - } - - .pb-lg-10, -.py-lg-10 { - padding-bottom: 80px !important; - } - - .pl-lg-10, -.px-lg-10 { - padding-left: 80px !important; - } - - .p-lg-12 { - padding: 96px !important; - } - - .pt-lg-12, -.py-lg-12 { - padding-top: 96px !important; - } - - .pr-lg-12, -.px-lg-12 { - padding-right: 96px !important; - } - - .pb-lg-12, -.py-lg-12 { - padding-bottom: 96px !important; - } - - .pl-lg-12, -.px-lg-12 { - padding-left: 96px !important; - } - - .p-lg-15 { - padding: 120px !important; - } - - .pt-lg-15, -.py-lg-15 { - padding-top: 120px !important; - } - - .pr-lg-15, -.px-lg-15 { - padding-right: 120px !important; - } - - .pb-lg-15, -.py-lg-15 { - padding-bottom: 120px !important; - } - - .pl-lg-15, -.px-lg-15 { - padding-left: 120px !important; - } - - .m-lg-n1 { - margin: -8px !important; - } - - .mt-lg-n1, -.my-lg-n1 { - margin-top: -8px !important; - } - - .mr-lg-n1, -.mx-lg-n1 { - margin-right: -8px !important; - } - - .mb-lg-n1, -.my-lg-n1 { - margin-bottom: -8px !important; - } - - .ml-lg-n1, -.mx-lg-n1 { - margin-left: -8px !important; - } - - .m-lg-n2 { - margin: -16px !important; - } - - .mt-lg-n2, -.my-lg-n2 { - margin-top: -16px !important; - } - - .mr-lg-n2, -.mx-lg-n2 { - margin-right: -16px !important; - } - - .mb-lg-n2, -.my-lg-n2 { - margin-bottom: -16px !important; - } - - .ml-lg-n2, -.mx-lg-n2 { - margin-left: -16px !important; - } - - .m-lg-n3 { - margin: -24px !important; - } - - .mt-lg-n3, -.my-lg-n3 { - margin-top: -24px !important; - } - - .mr-lg-n3, -.mx-lg-n3 { - margin-right: -24px !important; - } - - .mb-lg-n3, -.my-lg-n3 { - margin-bottom: -24px !important; - } - - .ml-lg-n3, -.mx-lg-n3 { - margin-left: -24px !important; - } - - .m-lg-n4 { - margin: -32px !important; - } - - .mt-lg-n4, -.my-lg-n4 { - margin-top: -32px !important; - } - - .mr-lg-n4, -.mx-lg-n4 { - margin-right: -32px !important; - } - - .mb-lg-n4, -.my-lg-n4 { - margin-bottom: -32px !important; - } - - .ml-lg-n4, -.mx-lg-n4 { - margin-left: -32px !important; - } - - .m-lg-n5 { - margin: -40px !important; - } - - .mt-lg-n5, -.my-lg-n5 { - margin-top: -40px !important; - } - - .mr-lg-n5, -.mx-lg-n5 { - margin-right: -40px !important; - } - - .mb-lg-n5, -.my-lg-n5 { - margin-bottom: -40px !important; - } - - .ml-lg-n5, -.mx-lg-n5 { - margin-left: -40px !important; - } - - .m-lg-n6 { - margin: -48px !important; - } - - .mt-lg-n6, -.my-lg-n6 { - margin-top: -48px !important; - } - - .mr-lg-n6, -.mx-lg-n6 { - margin-right: -48px !important; - } - - .mb-lg-n6, -.my-lg-n6 { - margin-bottom: -48px !important; - } - - .ml-lg-n6, -.mx-lg-n6 { - margin-left: -48px !important; - } - - .m-lg-n7 { - margin: -56px !important; - } - - .mt-lg-n7, -.my-lg-n7 { - margin-top: -56px !important; - } - - .mr-lg-n7, -.mx-lg-n7 { - margin-right: -56px !important; - } - - .mb-lg-n7, -.my-lg-n7 { - margin-bottom: -56px !important; - } - - .ml-lg-n7, -.mx-lg-n7 { - margin-left: -56px !important; - } - - .m-lg-n8 { - margin: -64px !important; - } - - .mt-lg-n8, -.my-lg-n8 { - margin-top: -64px !important; - } - - .mr-lg-n8, -.mx-lg-n8 { - margin-right: -64px !important; - } - - .mb-lg-n8, -.my-lg-n8 { - margin-bottom: -64px !important; - } - - .ml-lg-n8, -.mx-lg-n8 { - margin-left: -64px !important; - } - - .m-lg-n9 { - margin: -72px !important; - } - - .mt-lg-n9, -.my-lg-n9 { - margin-top: -72px !important; - } - - .mr-lg-n9, -.mx-lg-n9 { - margin-right: -72px !important; - } - - .mb-lg-n9, -.my-lg-n9 { - margin-bottom: -72px !important; - } - - .ml-lg-n9, -.mx-lg-n9 { - margin-left: -72px !important; - } - - .m-lg-n10 { - margin: -80px !important; - } - - .mt-lg-n10, -.my-lg-n10 { - margin-top: -80px !important; - } - - .mr-lg-n10, -.mx-lg-n10 { - margin-right: -80px !important; - } - - .mb-lg-n10, -.my-lg-n10 { - margin-bottom: -80px !important; - } - - .ml-lg-n10, -.mx-lg-n10 { - margin-left: -80px !important; - } - - .m-lg-n12 { - margin: -96px !important; - } - - .mt-lg-n12, -.my-lg-n12 { - margin-top: -96px !important; - } - - .mr-lg-n12, -.mx-lg-n12 { - margin-right: -96px !important; - } - - .mb-lg-n12, -.my-lg-n12 { - margin-bottom: -96px !important; - } - - .ml-lg-n12, -.mx-lg-n12 { - margin-left: -96px !important; - } - - .m-lg-n15 { - margin: -120px !important; - } - - .mt-lg-n15, -.my-lg-n15 { - margin-top: -120px !important; - } - - .mr-lg-n15, -.mx-lg-n15 { - margin-right: -120px !important; - } - - .mb-lg-n15, -.my-lg-n15 { - margin-bottom: -120px !important; - } - - .ml-lg-n15, -.mx-lg-n15 { - margin-left: -120px !important; - } - - .m-lg-auto { - margin: auto !important; - } - - .mt-lg-auto, -.my-lg-auto { - margin-top: auto !important; - } - - .mr-lg-auto, -.mx-lg-auto { - margin-right: auto !important; - } - - .mb-lg-auto, -.my-lg-auto { - margin-bottom: auto !important; - } - - .ml-lg-auto, -.mx-lg-auto { - margin-left: auto !important; - } -} -@media (min-width: 1240px) { - .m-xl-0 { - margin: 0 !important; - } - - .mt-xl-0, -.my-xl-0 { - margin-top: 0 !important; - } - - .mr-xl-0, -.mx-xl-0 { - margin-right: 0 !important; - } - - .mb-xl-0, -.my-xl-0 { - margin-bottom: 0 !important; - } - - .ml-xl-0, -.mx-xl-0 { - margin-left: 0 !important; - } - - .m-xl-1 { - margin: 8px !important; - } - - .mt-xl-1, -.my-xl-1 { - margin-top: 8px !important; - } - - .mr-xl-1, -.mx-xl-1 { - margin-right: 8px !important; - } - - .mb-xl-1, -.my-xl-1 { - margin-bottom: 8px !important; - } - - .ml-xl-1, -.mx-xl-1 { - margin-left: 8px !important; - } - - .m-xl-2 { - margin: 16px !important; - } - - .mt-xl-2, -.my-xl-2 { - margin-top: 16px !important; - } - - .mr-xl-2, -.mx-xl-2 { - margin-right: 16px !important; - } - - .mb-xl-2, -.my-xl-2 { - margin-bottom: 16px !important; - } - - .ml-xl-2, -.mx-xl-2 { - margin-left: 16px !important; - } - - .m-xl-3 { - margin: 24px !important; - } - - .mt-xl-3, -.my-xl-3 { - margin-top: 24px !important; - } - - .mr-xl-3, -.mx-xl-3 { - margin-right: 24px !important; - } - - .mb-xl-3, -.my-xl-3 { - margin-bottom: 24px !important; - } - - .ml-xl-3, -.mx-xl-3 { - margin-left: 24px !important; - } - - .m-xl-4 { - margin: 32px !important; - } - - .mt-xl-4, -.my-xl-4 { - margin-top: 32px !important; - } - - .mr-xl-4, -.mx-xl-4 { - margin-right: 32px !important; - } - - .mb-xl-4, -.my-xl-4 { - margin-bottom: 32px !important; - } - - .ml-xl-4, -.mx-xl-4 { - margin-left: 32px !important; - } - - .m-xl-5 { - margin: 40px !important; - } - - .mt-xl-5, -.my-xl-5 { - margin-top: 40px !important; - } - - .mr-xl-5, -.mx-xl-5 { - margin-right: 40px !important; - } - - .mb-xl-5, -.my-xl-5 { - margin-bottom: 40px !important; - } - - .ml-xl-5, -.mx-xl-5 { - margin-left: 40px !important; - } - - .m-xl-6 { - margin: 48px !important; - } - - .mt-xl-6, -.my-xl-6 { - margin-top: 48px !important; - } - - .mr-xl-6, -.mx-xl-6 { - margin-right: 48px !important; - } - - .mb-xl-6, -.my-xl-6 { - margin-bottom: 48px !important; - } - - .ml-xl-6, -.mx-xl-6 { - margin-left: 48px !important; - } - - .m-xl-7 { - margin: 56px !important; - } - - .mt-xl-7, -.my-xl-7 { - margin-top: 56px !important; - } - - .mr-xl-7, -.mx-xl-7 { - margin-right: 56px !important; - } - - .mb-xl-7, -.my-xl-7 { - margin-bottom: 56px !important; - } - - .ml-xl-7, -.mx-xl-7 { - margin-left: 56px !important; - } - - .m-xl-8 { - margin: 64px !important; - } - - .mt-xl-8, -.my-xl-8 { - margin-top: 64px !important; - } - - .mr-xl-8, -.mx-xl-8 { - margin-right: 64px !important; - } - - .mb-xl-8, -.my-xl-8 { - margin-bottom: 64px !important; - } - - .ml-xl-8, -.mx-xl-8 { - margin-left: 64px !important; - } - - .m-xl-9 { - margin: 72px !important; - } - - .mt-xl-9, -.my-xl-9 { - margin-top: 72px !important; - } - - .mr-xl-9, -.mx-xl-9 { - margin-right: 72px !important; - } - - .mb-xl-9, -.my-xl-9 { - margin-bottom: 72px !important; - } - - .ml-xl-9, -.mx-xl-9 { - margin-left: 72px !important; - } - - .m-xl-10 { - margin: 80px !important; - } - - .mt-xl-10, -.my-xl-10 { - margin-top: 80px !important; - } - - .mr-xl-10, -.mx-xl-10 { - margin-right: 80px !important; - } - - .mb-xl-10, -.my-xl-10 { - margin-bottom: 80px !important; - } - - .ml-xl-10, -.mx-xl-10 { - margin-left: 80px !important; - } - - .m-xl-12 { - margin: 96px !important; - } - - .mt-xl-12, -.my-xl-12 { - margin-top: 96px !important; - } - - .mr-xl-12, -.mx-xl-12 { - margin-right: 96px !important; - } - - .mb-xl-12, -.my-xl-12 { - margin-bottom: 96px !important; - } - - .ml-xl-12, -.mx-xl-12 { - margin-left: 96px !important; - } - - .m-xl-15 { - margin: 120px !important; - } - - .mt-xl-15, -.my-xl-15 { - margin-top: 120px !important; - } - - .mr-xl-15, -.mx-xl-15 { - margin-right: 120px !important; - } - - .mb-xl-15, -.my-xl-15 { - margin-bottom: 120px !important; - } - - .ml-xl-15, -.mx-xl-15 { - margin-left: 120px !important; - } - - .p-xl-0 { - padding: 0 !important; - } - - .pt-xl-0, -.py-xl-0 { - padding-top: 0 !important; - } - - .pr-xl-0, -.px-xl-0 { - padding-right: 0 !important; - } - - .pb-xl-0, -.py-xl-0 { - padding-bottom: 0 !important; - } - - .pl-xl-0, -.px-xl-0 { - padding-left: 0 !important; - } - - .p-xl-1 { - padding: 8px !important; - } - - .pt-xl-1, -.py-xl-1 { - padding-top: 8px !important; - } - - .pr-xl-1, -.px-xl-1 { - padding-right: 8px !important; - } - - .pb-xl-1, -.py-xl-1 { - padding-bottom: 8px !important; - } - - .pl-xl-1, -.px-xl-1 { - padding-left: 8px !important; - } - - .p-xl-2 { - padding: 16px !important; - } - - .pt-xl-2, -.py-xl-2 { - padding-top: 16px !important; - } - - .pr-xl-2, -.px-xl-2 { - padding-right: 16px !important; - } - - .pb-xl-2, -.py-xl-2 { - padding-bottom: 16px !important; - } - - .pl-xl-2, -.px-xl-2 { - padding-left: 16px !important; - } - - .p-xl-3 { - padding: 24px !important; - } - - .pt-xl-3, -.py-xl-3 { - padding-top: 24px !important; - } - - .pr-xl-3, -.px-xl-3 { - padding-right: 24px !important; - } - - .pb-xl-3, -.py-xl-3 { - padding-bottom: 24px !important; - } - - .pl-xl-3, -.px-xl-3 { - padding-left: 24px !important; - } - - .p-xl-4 { - padding: 32px !important; - } - - .pt-xl-4, -.py-xl-4 { - padding-top: 32px !important; - } - - .pr-xl-4, -.px-xl-4 { - padding-right: 32px !important; - } - - .pb-xl-4, -.py-xl-4 { - padding-bottom: 32px !important; - } - - .pl-xl-4, -.px-xl-4 { - padding-left: 32px !important; - } - - .p-xl-5 { - padding: 40px !important; - } - - .pt-xl-5, -.py-xl-5 { - padding-top: 40px !important; - } - - .pr-xl-5, -.px-xl-5 { - padding-right: 40px !important; - } - - .pb-xl-5, -.py-xl-5 { - padding-bottom: 40px !important; - } - - .pl-xl-5, -.px-xl-5 { - padding-left: 40px !important; - } - - .p-xl-6 { - padding: 48px !important; - } - - .pt-xl-6, -.py-xl-6 { - padding-top: 48px !important; - } - - .pr-xl-6, -.px-xl-6 { - padding-right: 48px !important; - } - - .pb-xl-6, -.py-xl-6 { - padding-bottom: 48px !important; - } - - .pl-xl-6, -.px-xl-6 { - padding-left: 48px !important; - } - - .p-xl-7 { - padding: 56px !important; - } - - .pt-xl-7, -.py-xl-7 { - padding-top: 56px !important; - } - - .pr-xl-7, -.px-xl-7 { - padding-right: 56px !important; - } - - .pb-xl-7, -.py-xl-7 { - padding-bottom: 56px !important; - } - - .pl-xl-7, -.px-xl-7 { - padding-left: 56px !important; - } - - .p-xl-8 { - padding: 64px !important; - } - - .pt-xl-8, -.py-xl-8 { - padding-top: 64px !important; - } - - .pr-xl-8, -.px-xl-8 { - padding-right: 64px !important; - } - - .pb-xl-8, -.py-xl-8 { - padding-bottom: 64px !important; - } - - .pl-xl-8, -.px-xl-8 { - padding-left: 64px !important; - } - - .p-xl-9 { - padding: 72px !important; - } - - .pt-xl-9, -.py-xl-9 { - padding-top: 72px !important; - } - - .pr-xl-9, -.px-xl-9 { - padding-right: 72px !important; - } - - .pb-xl-9, -.py-xl-9 { - padding-bottom: 72px !important; - } - - .pl-xl-9, -.px-xl-9 { - padding-left: 72px !important; - } - - .p-xl-10 { - padding: 80px !important; - } - - .pt-xl-10, -.py-xl-10 { - padding-top: 80px !important; - } - - .pr-xl-10, -.px-xl-10 { - padding-right: 80px !important; - } - - .pb-xl-10, -.py-xl-10 { - padding-bottom: 80px !important; - } - - .pl-xl-10, -.px-xl-10 { - padding-left: 80px !important; - } - - .p-xl-12 { - padding: 96px !important; - } - - .pt-xl-12, -.py-xl-12 { - padding-top: 96px !important; - } - - .pr-xl-12, -.px-xl-12 { - padding-right: 96px !important; - } - - .pb-xl-12, -.py-xl-12 { - padding-bottom: 96px !important; - } - - .pl-xl-12, -.px-xl-12 { - padding-left: 96px !important; - } - - .p-xl-15 { - padding: 120px !important; - } - - .pt-xl-15, -.py-xl-15 { - padding-top: 120px !important; - } - - .pr-xl-15, -.px-xl-15 { - padding-right: 120px !important; - } - - .pb-xl-15, -.py-xl-15 { - padding-bottom: 120px !important; - } - - .pl-xl-15, -.px-xl-15 { - padding-left: 120px !important; - } - - .m-xl-n1 { - margin: -8px !important; - } - - .mt-xl-n1, -.my-xl-n1 { - margin-top: -8px !important; - } - - .mr-xl-n1, -.mx-xl-n1 { - margin-right: -8px !important; - } - - .mb-xl-n1, -.my-xl-n1 { - margin-bottom: -8px !important; - } - - .ml-xl-n1, -.mx-xl-n1 { - margin-left: -8px !important; - } - - .m-xl-n2 { - margin: -16px !important; - } - - .mt-xl-n2, -.my-xl-n2 { - margin-top: -16px !important; - } - - .mr-xl-n2, -.mx-xl-n2 { - margin-right: -16px !important; - } - - .mb-xl-n2, -.my-xl-n2 { - margin-bottom: -16px !important; - } - - .ml-xl-n2, -.mx-xl-n2 { - margin-left: -16px !important; - } - - .m-xl-n3 { - margin: -24px !important; - } - - .mt-xl-n3, -.my-xl-n3 { - margin-top: -24px !important; - } - - .mr-xl-n3, -.mx-xl-n3 { - margin-right: -24px !important; - } - - .mb-xl-n3, -.my-xl-n3 { - margin-bottom: -24px !important; - } - - .ml-xl-n3, -.mx-xl-n3 { - margin-left: -24px !important; - } - - .m-xl-n4 { - margin: -32px !important; - } - - .mt-xl-n4, -.my-xl-n4 { - margin-top: -32px !important; - } - - .mr-xl-n4, -.mx-xl-n4 { - margin-right: -32px !important; - } - - .mb-xl-n4, -.my-xl-n4 { - margin-bottom: -32px !important; - } - - .ml-xl-n4, -.mx-xl-n4 { - margin-left: -32px !important; - } - - .m-xl-n5 { - margin: -40px !important; - } - - .mt-xl-n5, -.my-xl-n5 { - margin-top: -40px !important; - } - - .mr-xl-n5, -.mx-xl-n5 { - margin-right: -40px !important; - } - - .mb-xl-n5, -.my-xl-n5 { - margin-bottom: -40px !important; - } - - .ml-xl-n5, -.mx-xl-n5 { - margin-left: -40px !important; - } - - .m-xl-n6 { - margin: -48px !important; - } - - .mt-xl-n6, -.my-xl-n6 { - margin-top: -48px !important; - } - - .mr-xl-n6, -.mx-xl-n6 { - margin-right: -48px !important; - } - - .mb-xl-n6, -.my-xl-n6 { - margin-bottom: -48px !important; - } - - .ml-xl-n6, -.mx-xl-n6 { - margin-left: -48px !important; - } - - .m-xl-n7 { - margin: -56px !important; - } - - .mt-xl-n7, -.my-xl-n7 { - margin-top: -56px !important; - } - - .mr-xl-n7, -.mx-xl-n7 { - margin-right: -56px !important; - } - - .mb-xl-n7, -.my-xl-n7 { - margin-bottom: -56px !important; - } - - .ml-xl-n7, -.mx-xl-n7 { - margin-left: -56px !important; - } - - .m-xl-n8 { - margin: -64px !important; - } - - .mt-xl-n8, -.my-xl-n8 { - margin-top: -64px !important; - } - - .mr-xl-n8, -.mx-xl-n8 { - margin-right: -64px !important; - } - - .mb-xl-n8, -.my-xl-n8 { - margin-bottom: -64px !important; - } - - .ml-xl-n8, -.mx-xl-n8 { - margin-left: -64px !important; - } - - .m-xl-n9 { - margin: -72px !important; - } - - .mt-xl-n9, -.my-xl-n9 { - margin-top: -72px !important; - } - - .mr-xl-n9, -.mx-xl-n9 { - margin-right: -72px !important; - } - - .mb-xl-n9, -.my-xl-n9 { - margin-bottom: -72px !important; - } - - .ml-xl-n9, -.mx-xl-n9 { - margin-left: -72px !important; - } - - .m-xl-n10 { - margin: -80px !important; - } - - .mt-xl-n10, -.my-xl-n10 { - margin-top: -80px !important; - } - - .mr-xl-n10, -.mx-xl-n10 { - margin-right: -80px !important; - } - - .mb-xl-n10, -.my-xl-n10 { - margin-bottom: -80px !important; - } - - .ml-xl-n10, -.mx-xl-n10 { - margin-left: -80px !important; - } - - .m-xl-n12 { - margin: -96px !important; - } - - .mt-xl-n12, -.my-xl-n12 { - margin-top: -96px !important; - } - - .mr-xl-n12, -.mx-xl-n12 { - margin-right: -96px !important; - } - - .mb-xl-n12, -.my-xl-n12 { - margin-bottom: -96px !important; - } - - .ml-xl-n12, -.mx-xl-n12 { - margin-left: -96px !important; - } - - .m-xl-n15 { - margin: -120px !important; - } - - .mt-xl-n15, -.my-xl-n15 { - margin-top: -120px !important; - } - - .mr-xl-n15, -.mx-xl-n15 { - margin-right: -120px !important; - } - - .mb-xl-n15, -.my-xl-n15 { - margin-bottom: -120px !important; - } - - .ml-xl-n15, -.mx-xl-n15 { - margin-left: -120px !important; - } - - .m-xl-auto { - margin: auto !important; - } - - .mt-xl-auto, -.my-xl-auto { - margin-top: auto !important; - } - - .mr-xl-auto, -.mx-xl-auto { - margin-right: auto !important; - } - - .mb-xl-auto, -.my-xl-auto { - margin-bottom: auto !important; - } - - .ml-xl-auto, -.mx-xl-auto { - margin-left: auto !important; - } -} -.text-monospace { - font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace !important; -} - -.text-justify { - text-align: justify !important; -} - -.text-wrap { - white-space: normal !important; -} - -.text-nowrap { - white-space: nowrap !important; -} - -.text-truncate { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.text-left { - text-align: left !important; -} - -.text-right { - text-align: right !important; -} - -.text-center { - text-align: center !important; -} - -@media (min-width: 400px) { - .text-xs-left { - text-align: left !important; - } - - .text-xs-right { - text-align: right !important; - } - - .text-xs-center { - text-align: center !important; - } -} -@media (min-width: 616px) { - .text-sm-left { - text-align: left !important; - } - - .text-sm-right { - text-align: right !important; - } - - .text-sm-center { - text-align: center !important; - } -} -@media (min-width: 768px) { - .text-md-left { - text-align: left !important; - } - - .text-md-right { - text-align: right !important; - } - - .text-md-center { - text-align: center !important; - } -} -@media (min-width: 980px) { - .text-lg-left { - text-align: left !important; - } - - .text-lg-right { - text-align: right !important; - } - - .text-lg-center { - text-align: center !important; - } -} -@media (min-width: 1240px) { - .text-xl-left { - text-align: left !important; - } - - .text-xl-right { - text-align: right !important; - } - - .text-xl-center { - text-align: center !important; - } -} -.text-lowercase { - text-transform: lowercase !important; -} - -.text-uppercase { - text-transform: uppercase !important; -} - -.text-capitalize { - text-transform: capitalize !important; -} - -.font-weight-light { - font-weight: 300 !important; -} - -.font-weight-lighter { - font-weight: lighter !important; -} - -.font-weight-normal { - font-weight: 400 !important; -} - -.font-weight-bold { - font-weight: 700 !important; -} - -.font-weight-bolder { - font-weight: bolder !important; -} - -.font-italic { - font-style: italic !important; -} - -.text-white { - color: #fff !important; -} - -.text-primary { - color: #ffcc00 !important; -} - -a.text-primary:hover, a.text-primary:focus { - color: #b38f00 !important; -} - -.text-secondary { - color: #212529 !important; -} - -a.text-secondary:hover, a.text-secondary:focus { - color: black !important; -} - -.text-success { - color: #28a745 !important; -} - -a.text-success:hover, a.text-success:focus { - color: #19692c !important; -} - -.text-info { - color: #17a2b8 !important; -} - -a.text-info:hover, a.text-info:focus { - color: #0f6674 !important; -} - -.text-warning { - color: #ffc107 !important; -} - -a.text-warning:hover, a.text-warning:focus { - color: #ba8b00 !important; -} - -.text-danger { - color: #dc3545 !important; -} - -a.text-danger:hover, a.text-danger:focus { - color: #a71d2a !important; -} - -.text-light { - color: #f1f6f9 !important; -} - -a.text-light:hover, a.text-light:focus { - color: #bbd4e2 !important; -} - -.text-dark { - color: #495057 !important; -} - -a.text-dark:hover, a.text-dark:focus { - color: #262a2d !important; -} - -.text-primary-light { - color: #fffaf0 !important; -} - -a.text-primary-light:hover, a.text-primary-light:focus { - color: #ffe1a4 !important; -} - -.text-secondary-light { - color: #fff !important; -} - -a.text-secondary-light:hover, a.text-secondary-light:focus { - color: #d9d9d9 !important; -} - -.text-tertiary { - color: #257af4 !important; -} - -a.text-tertiary:hover, a.text-tertiary:focus { - color: #0a56c3 !important; -} - -.text-tertiary-light { - color: #e3f1fe !important; -} - -a.text-tertiary-light:hover, a.text-tertiary-light:focus { - color: #99ccfb !important; -} - -.text-white { - color: #fff !important; -} - -a.text-white:hover, a.text-white:focus { - color: #d9d9d9 !important; -} - -.text-black { - color: #212529 !important; -} - -a.text-black:hover, a.text-black:focus { - color: black !important; -} - -.text-blue { - color: #257af4 !important; -} - -a.text-blue:hover, a.text-blue:focus { - color: #0a56c3 !important; -} - -.text-light-blue { - color: #e3f1fe !important; -} - -a.text-light-blue:hover, a.text-light-blue:focus { - color: #99ccfb !important; -} - -.text-yellow { - color: #ffcc00 !important; -} - -a.text-yellow:hover, a.text-yellow:focus { - color: #b38f00 !important; -} - -.text-light-yellow { - color: #fffaf0 !important; -} - -a.text-light-yellow:hover, a.text-light-yellow:focus { - color: #ffe1a4 !important; -} - -.text-orange { - color: #ff8c00 !important; -} - -a.text-orange:hover, a.text-orange:focus { - color: #b36200 !important; -} - -.text-light-orange { - color: #ffe4b5 !important; -} - -a.text-light-orange:hover, a.text-light-orange:focus { - color: #ffc869 !important; -} - -.text-red { - color: #ff3939 !important; -} - -a.text-red:hover, a.text-red:focus { - color: #ec0000 !important; -} - -.text-light-red { - color: #ffe4e1 !important; -} - -a.text-light-red:hover, a.text-light-red:focus { - color: #ff9f95 !important; -} - -.text-medium { - color: #d6dbdf !important; -} - -a.text-medium:hover, a.text-medium:focus { - color: #abb5bd !important; -} - -.text-body { - color: #212529 !important; -} - -.text-muted { - color: #6c757d !important; -} - -.text-black-50 { - color: rgba(33, 37, 41, 0.5) !important; -} - -.text-white-50 { - color: rgba(255, 255, 255, 0.5) !important; -} - -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} - -.text-decoration-none { - text-decoration: none !important; -} - -.text-break { - word-break: break-word !important; - overflow-wrap: break-word !important; -} - -.text-reset { - color: inherit !important; -} - -.visible { - visibility: visible !important; -} - -.invisible { - visibility: hidden !important; -} - -@media print { - *, -*::before, -*::after { - text-shadow: none !important; - box-shadow: none !important; - } - - a:not(.btn) { - text-decoration: underline; - } - - abbr[title]::after { - content: " (" attr(title) ")"; - } - - pre { - white-space: pre-wrap !important; - } - - pre, -blockquote { - border: 1px solid #d6dbdf; - page-break-inside: avoid; - } - - thead { - display: table-header-group; - } - - tr, -img { - page-break-inside: avoid; - } - - p, -h2, -h3 { - orphans: 3; - widows: 3; - } - - h2, -h3 { - page-break-after: avoid; - } - - @page { - size: a3; - } - body { - min-width: 980px !important; - } - - .container { - min-width: 980px !important; - } - - .navbar { - display: none; - } - - .badge { - border: 1px solid #212529; - } - - .table { - border-collapse: collapse !important; - } - .table td, -.table th { - background-color: #fff !important; - } - - .table-bordered th, -.table-bordered td { - border: 1px solid #dee2e6 !important; - } - - .table-dark { - color: inherit; - } - .table-dark th, -.table-dark td, -.table-dark thead th, -.table-dark tbody + tbody { - border-color: #d6dbdf; - } - - .table .thead-dark th { - color: inherit; - border-color: #d6dbdf; - } -} \ No newline at end of file + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--gray:#6c757d;--gray-dark:#343a40;--brand-primary:#fc0;--brand-secondary:#ff3939;--primary-accent-yellow:#fc0;--primary-accent-light-yellow:#fffaf0;--primary-accent-blue:#257af4;--primary-accent-light-blue:#e3f1fe;--secondary-accent-orange:#ff8c00;--secondary-accent-light-orange:#ffe4b5;--secondary-accent-red:#ff3939;--secondary-accent-light-red:#ffe4e1;--primary:#fc0;--secondary:#212529;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f1f6f9;--dark:#495057;--primary-light:#fffaf0;--secondary-light:#fff;--tertiary:#257af4;--tertiary-light:#e3f1fe;--white:#fff;--black:#212529;--blue:#257af4;--light-blue:#e3f1fe;--yellow:#fc0;--light-yellow:#fffaf0;--orange:#ff8c00;--light-orange:#ffe4b5;--red:#ff3939;--light-red:#ffe4e1;--medium:#d6dbdf;--breakpoint-xxs:0;--breakpoint-xs:400px;--breakpoint-sm:616px;--breakpoint-md:768px;--breakpoint-lg:980px;--breakpoint-xl:1240px;--font-family-sans-serif:"Noto Sans",sans-serif;--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(33,37,41,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:Noto Sans,sans-serif;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:16px}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{text-decoration:none;background-color:transparent}a,a:hover{color:#ff8c00}a:hover{text-decoration:underline}a:not([href]),a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}@media(max-width:1200px){legend{font-size:calc(1.275rem + .3vw)}}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:16px;font-family:Hind Siliguri,sans-serif;font-weight:500;line-height:1.125}.h1,h1{font-size:2.5rem}@media(max-width:1200px){.h1,h1{font-size:calc(1.375rem + 1.5vw)}}.h2,h2{font-size:2rem}@media(max-width:1200px){.h2,h2{font-size:calc(1.325rem + .9vw)}}.h3,h3{font-size:1.75rem}@media(max-width:1200px){.h3,h3{font-size:calc(1.3rem + .6vw)}}.h4,h4{font-size:1.5rem}@media(max-width:1200px){.h4,h4{font-size:calc(1.275rem + .3vw)}}.h5,h5{font-size:1.125rem}.h6,h6{font-size:.875rem}.lead{font-size:1.375rem;font-weight:400}@media(max-width:1200px){.lead{font-size:calc(1.2625rem + .15vw)}}.display-1{font-size:4rem;font-weight:600;line-height:1.125}@media(max-width:1200px){.display-1{font-size:calc(1.525rem + 3.3vw)}}.display-2{font-size:2.5rem;font-weight:600;line-height:1.125}@media(max-width:1200px){.display-2{font-size:calc(1.375rem + 1.5vw)}}.display-3{font-size:2rem;font-weight:500;line-height:1.125}@media(max-width:1200px){.display-3{font-size:calc(1.325rem + .9vw)}}.display-4{font-size:1.75rem;font-weight:500;line-height:1.125}@media(max-width:1200px){.display-4{font-size:calc(1.3rem + .6vw)}}hr{margin-top:8px;margin-bottom:8px;border:0;border-top:1px solid rgba(33,37,41,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:8px;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer:before{content:"— "}.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:8px}.figure{display:inline-block}.figure-img{margin-bottom:4px;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#495057;border-radius:8px}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#495057}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:20px;padding-left:20px;margin-right:auto;margin-left:auto}@media(min-width:400px){.container{max-width:576px}}@media(min-width:616px){.container{max-width:576px}}@media(min-width:768px){.container{max-width:958px}}@media(min-width:980px){.container{max-width:1008px}}@media(min-width:1240px){.container{max-width:1118px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xs{width:100%;padding-right:20px;padding-left:20px;margin-right:auto;margin-left:auto}@media(min-width:400px){.container,.container-xs{max-width:576px}}@media(min-width:616px){.container,.container-sm,.container-xs{max-width:576px}}@media(min-width:768px){.container,.container-md,.container-sm,.container-xs{max-width:958px}}@media(min-width:980px){.container,.container-lg,.container-md,.container-sm,.container-xs{max-width:1008px}}@media(min-width:1240px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xs{max-width:1118px}}.row{display:flex;flex-wrap:wrap;margin-right:-20px;margin-left:-20px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto,.col-xs,.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-auto{position:relative;width:100%;padding-right:20px;padding-left:20px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media(min-width:400px){.col-xs{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xs-1>*{flex:0 0 100%;max-width:100%}.row-cols-xs-2>*{flex:0 0 50%;max-width:50%}.row-cols-xs-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xs-4>*{flex:0 0 25%;max-width:25%}.row-cols-xs-5>*{flex:0 0 20%;max-width:20%}.row-cols-xs-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xs-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xs-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xs-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xs-3{flex:0 0 25%;max-width:25%}.col-xs-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xs-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xs-6{flex:0 0 50%;max-width:50%}.col-xs-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xs-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xs-9{flex:0 0 75%;max-width:75%}.col-xs-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xs-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xs-12{flex:0 0 100%;max-width:100%}.order-xs-first{order:-1}.order-xs-last{order:13}.order-xs-0{order:0}.order-xs-1{order:1}.order-xs-2{order:2}.order-xs-3{order:3}.order-xs-4{order:4}.order-xs-5{order:5}.order-xs-6{order:6}.order-xs-7{order:7}.order-xs-8{order:8}.order-xs-9{order:9}.order-xs-10{order:10}.order-xs-11{order:11}.order-xs-12{order:12}.offset-xs-0{margin-left:0}.offset-xs-1{margin-left:8.3333333333%}.offset-xs-2{margin-left:16.6666666667%}.offset-xs-3{margin-left:25%}.offset-xs-4{margin-left:33.3333333333%}.offset-xs-5{margin-left:41.6666666667%}.offset-xs-6{margin-left:50%}.offset-xs-7{margin-left:58.3333333333%}.offset-xs-8{margin-left:66.6666666667%}.offset-xs-9{margin-left:75%}.offset-xs-10{margin-left:83.3333333333%}.offset-xs-11{margin-left:91.6666666667%}}@media(min-width:616px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media(min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media(min-width:980px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media(min-width:1240px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.table{width:100%;margin-bottom:8px;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #d6dbdf}.table thead th{vertical-align:bottom;border-bottom:2px solid #d6dbdf}.table tbody+tbody{border-top:2px solid #d6dbdf}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #d6dbdf}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(33,37,41,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(33,37,41,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#fff1b8}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#ffe47a}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#ffec9f}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#c1c2c3}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#8c8e90}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#b4b5b6}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fbfcfd}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#f8fafc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#eaeff5}.table-dark,.table-dark>td,.table-dark>th{background-color:#ccced0}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#a0a4a8}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#bfc1c4}.table-primary-light,.table-primary-light>td,.table-primary-light>th{background-color:#fffefb}.table-primary-light tbody+tbody,.table-primary-light td,.table-primary-light th,.table-primary-light thead th{border-color:#fffcf7}.table-hover .table-primary-light:hover,.table-hover .table-primary-light:hover>td,.table-hover .table-primary-light:hover>th{background-color:#fff8e2}.table-secondary-light,.table-secondary-light>td,.table-secondary-light>th{background-color:#fff}.table-secondary-light tbody+tbody,.table-secondary-light td,.table-secondary-light th,.table-secondary-light thead th{border-color:#fff}.table-hover .table-secondary-light:hover,.table-hover .table-secondary-light:hover>td,.table-hover .table-secondary-light:hover>th{background-color:#f2f2f2}.table-tertiary,.table-tertiary>td,.table-tertiary>th{background-color:#c2dafc}.table-tertiary tbody+tbody,.table-tertiary td,.table-tertiary th,.table-tertiary thead th{border-color:#8ebaf9}.table-hover .table-tertiary:hover,.table-hover .table-tertiary:hover>td,.table-hover .table-tertiary:hover>th{background-color:#aacbfb}.table-tertiary-light,.table-tertiary-light>td,.table-tertiary-light>th{background-color:#f7fbff}.table-tertiary-light tbody+tbody,.table-tertiary-light td,.table-tertiary-light th,.table-tertiary-light thead th{border-color:#f0f8fe}.table-hover .table-tertiary-light:hover,.table-hover .table-tertiary-light:hover>td,.table-hover .table-tertiary-light:hover>th{background-color:#deeeff}.table-white,.table-white>td,.table-white>th{background-color:#fff}.table-white tbody+tbody,.table-white td,.table-white th,.table-white thead th{border-color:#fff}.table-hover .table-white:hover,.table-hover .table-white:hover>td,.table-hover .table-white:hover>th{background-color:#f2f2f2}.table-black,.table-black>td,.table-black>th{background-color:#c1c2c3}.table-black tbody+tbody,.table-black td,.table-black th,.table-black thead th{border-color:#8c8e90}.table-hover .table-black:hover,.table-hover .table-black:hover>td,.table-hover .table-black:hover>th{background-color:#b4b5b6}.table-blue,.table-blue>td,.table-blue>th{background-color:#c2dafc}.table-blue tbody+tbody,.table-blue td,.table-blue th,.table-blue thead th{border-color:#8ebaf9}.table-hover .table-blue:hover,.table-hover .table-blue:hover>td,.table-hover .table-blue:hover>th{background-color:#aacbfb}.table-light-blue,.table-light-blue>td,.table-light-blue>th{background-color:#f7fbff}.table-light-blue tbody+tbody,.table-light-blue td,.table-light-blue th,.table-light-blue thead th{border-color:#f0f8fe}.table-hover .table-light-blue:hover,.table-hover .table-light-blue:hover>td,.table-hover .table-light-blue:hover>th{background-color:#deeeff}.table-yellow,.table-yellow>td,.table-yellow>th{background-color:#fff1b8}.table-yellow tbody+tbody,.table-yellow td,.table-yellow th,.table-yellow thead th{border-color:#ffe47a}.table-hover .table-yellow:hover,.table-hover .table-yellow:hover>td,.table-hover .table-yellow:hover>th{background-color:#ffec9f}.table-light-yellow,.table-light-yellow>td,.table-light-yellow>th{background-color:#fffefb}.table-light-yellow tbody+tbody,.table-light-yellow td,.table-light-yellow th,.table-light-yellow thead th{border-color:#fffcf7}.table-hover .table-light-yellow:hover,.table-hover .table-light-yellow:hover>td,.table-hover .table-light-yellow:hover>th{background-color:#fff8e2}.table-orange,.table-orange>td,.table-orange>th{background-color:#ffdfb8}.table-orange tbody+tbody,.table-orange td,.table-orange th,.table-orange thead th{border-color:#ffc37a}.table-hover .table-orange:hover,.table-hover .table-orange:hover>td,.table-hover .table-orange:hover>th{background-color:#ffd49f}.table-light-orange,.table-light-orange>td,.table-light-orange>th{background-color:#fff7ea}.table-light-orange tbody+tbody,.table-light-orange td,.table-light-orange th,.table-light-orange thead th{border-color:#fff1d9}.table-hover .table-light-orange:hover,.table-hover .table-light-orange:hover>td,.table-hover .table-light-orange:hover>th{background-color:#ffedd1}.table-red,.table-red>td,.table-red>th{background-color:#ffc8c8}.table-red tbody+tbody,.table-red td,.table-red th,.table-red thead th{border-color:#ff9898}.table-hover .table-red:hover,.table-hover .table-red:hover>td,.table-hover .table-red:hover>th{background-color:#ffafaf}.table-light-red,.table-light-red>td,.table-light-red>th{background-color:#fff7f7}.table-light-red tbody+tbody,.table-light-red td,.table-light-red th,.table-light-red thead th{border-color:#fff1ef}.table-hover .table-light-red:hover,.table-hover .table-light-red:hover>td,.table-hover .table-light-red:hover>th{background-color:#ffdede}.table-medium,.table-medium>td,.table-medium>th{background-color:#f4f5f6}.table-medium tbody+tbody,.table-medium td,.table-medium th,.table-medium thead th{border-color:#eaecee}.table-hover .table-medium:hover,.table-hover .table-medium:hover>td,.table-hover .table-medium:hover>th{background-color:#e6e8eb}.table-active,.table-active>td,.table-active>th{background-color:rgba(33,37,41,.075)}.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(22,24,27,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#6c757d;background-color:#e9ecef;border-color:#d6dbdf}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media(max-width:399.98px){.table-responsive-xs{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xs>.table-bordered{border:0}}@media(max-width:615.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media(max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media(max-width:979.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media(max-width:1239.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#6c757d;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:8px;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #6c757d}.form-control:focus{color:#6c757d;background-color:#fff;border-color:#ffe680;outline:0;box-shadow:0 0 0 .2rem rgba(255,204,0,.25)}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#6c757d;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.125rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:8px}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.125rem;line-height:1.5;border-radius:8px}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:8px}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:8px}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media(min-width:616px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{display:flex;align-items:center;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-family:inherit;font-weight:700;color:#212529;text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:12px 32px;font-size:.875rem;line-height:20px;border-radius:8px;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:none}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#495057;background-color:#fc0;border-color:#fc0}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#495057;background-color:#d9ad00;border-color:#cca300}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 0 rgba(228,185,13,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#495057;background-color:#fc0;border-color:#fc0}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#495057;background-color:#cca300;border-color:#bf9900}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,185,13,.5)}.btn-secondary{color:#fff;background-color:#212529;border-color:#212529}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#101214;border-color:#0a0c0d}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 0 rgba(66,70,73,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#0a0c0d;border-color:#050506}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(66,70,73,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 0 rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 0 rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(58,176,195,.5)}.btn-warning{color:#495057;background-color:#ffc107;border-color:#ffc107}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#495057;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 0 rgba(228,176,19,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#495057;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#495057;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,176,19,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 0 rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(225,83,97,.5)}.btn-light{color:#495057;background-color:#f1f6f9;border-color:#f1f6f9}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#495057;background-color:#d6e5ee;border-color:#cddfea}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 0 rgba(216,221,225,.5)}.btn-light.disabled,.btn-light:disabled{color:#495057;background-color:#f1f6f9;border-color:#f1f6f9}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#495057;background-color:#cddfea;border-color:#c4d9e6}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(216,221,225,.5)}.btn-dark{color:#fff;background-color:#495057;border-color:#495057}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#383d42;border-color:#32373b}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 0 rgba(100,106,112,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#495057;border-color:#495057}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#32373b;border-color:#2c3034}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(100,106,112,.5)}.btn-primary-light{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-primary-light.focus,.btn-primary-light:focus,.btn-primary-light:hover{color:#495057;background-color:#ffedca;border-color:#ffe9bd}.btn-primary-light.focus,.btn-primary-light:focus{box-shadow:0 0 0 0 rgba(228,225,217,.5)}.btn-primary-light.disabled,.btn-primary-light:disabled{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-primary-light:not(:disabled):not(.disabled).active,.btn-primary-light:not(:disabled):not(.disabled):active,.show>.btn-primary-light.dropdown-toggle{color:#495057;background-color:#ffe9bd;border-color:#ffe5b0}.btn-primary-light:not(:disabled):not(.disabled).active:focus,.btn-primary-light:not(:disabled):not(.disabled):active:focus,.show>.btn-primary-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,225,217,.5)}.btn-secondary-light{color:#495057;background-color:#fff;border-color:#fff}.btn-secondary-light.focus,.btn-secondary-light:focus,.btn-secondary-light:hover{color:#495057;background-color:#ececec;border-color:#e6e6e6}.btn-secondary-light.focus,.btn-secondary-light:focus{box-shadow:0 0 0 0 rgba(228,229,230,.5)}.btn-secondary-light.disabled,.btn-secondary-light:disabled{color:#495057;background-color:#fff;border-color:#fff}.btn-secondary-light:not(:disabled):not(.disabled).active,.btn-secondary-light:not(:disabled):not(.disabled):active,.show>.btn-secondary-light.dropdown-toggle{color:#495057;background-color:#e6e6e6;border-color:#dfdfdf}.btn-secondary-light:not(:disabled):not(.disabled).active:focus,.btn-secondary-light:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,229,230,.5)}.btn-tertiary{color:#fff;background-color:#257af4;border-color:#257af4}.btn-tertiary.focus,.btn-tertiary:focus,.btn-tertiary:hover{color:#fff;background-color:#0c66e7;border-color:#0b60db}.btn-tertiary.focus,.btn-tertiary:focus{box-shadow:0 0 0 0 rgba(70,142,246,.5)}.btn-tertiary.disabled,.btn-tertiary:disabled{color:#fff;background-color:#257af4;border-color:#257af4}.btn-tertiary:not(:disabled):not(.disabled).active,.btn-tertiary:not(:disabled):not(.disabled):active,.show>.btn-tertiary.dropdown-toggle{color:#fff;background-color:#0b60db;border-color:#0a5bcf}.btn-tertiary:not(:disabled):not(.disabled).active:focus,.btn-tertiary:not(:disabled):not(.disabled):active:focus,.show>.btn-tertiary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(70,142,246,.5)}.btn-tertiary-light{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-tertiary-light.focus,.btn-tertiary-light:focus,.btn-tertiary-light:hover{color:#495057;background-color:#bedffd;border-color:#b2d8fc}.btn-tertiary-light.focus,.btn-tertiary-light:focus{box-shadow:0 0 0 0 rgba(204,217,229,.5)}.btn-tertiary-light.disabled,.btn-tertiary-light:disabled{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-tertiary-light:not(:disabled):not(.disabled).active,.btn-tertiary-light:not(:disabled):not(.disabled):active,.show>.btn-tertiary-light.dropdown-toggle{color:#495057;background-color:#b2d8fc;border-color:#a5d2fc}.btn-tertiary-light:not(:disabled):not(.disabled).active:focus,.btn-tertiary-light:not(:disabled):not(.disabled):active:focus,.show>.btn-tertiary-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(204,217,229,.5)}.btn-white{color:#495057;background-color:#fff;border-color:#fff}.btn-white.focus,.btn-white:focus,.btn-white:hover{color:#495057;background-color:#ececec;border-color:#e6e6e6}.btn-white.focus,.btn-white:focus{box-shadow:0 0 0 0 rgba(228,229,230,.5)}.btn-white.disabled,.btn-white:disabled{color:#495057;background-color:#fff;border-color:#fff}.btn-white:not(:disabled):not(.disabled).active,.btn-white:not(:disabled):not(.disabled):active,.show>.btn-white.dropdown-toggle{color:#495057;background-color:#e6e6e6;border-color:#dfdfdf}.btn-white:not(:disabled):not(.disabled).active:focus,.btn-white:not(:disabled):not(.disabled):active:focus,.show>.btn-white.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,229,230,.5)}.btn-black{color:#fff;background-color:#212529;border-color:#212529}.btn-black.focus,.btn-black:focus,.btn-black:hover{color:#fff;background-color:#101214;border-color:#0a0c0d}.btn-black.focus,.btn-black:focus{box-shadow:0 0 0 0 rgba(66,70,73,.5)}.btn-black.disabled,.btn-black:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-black:not(:disabled):not(.disabled).active,.btn-black:not(:disabled):not(.disabled):active,.show>.btn-black.dropdown-toggle{color:#fff;background-color:#0a0c0d;border-color:#050506}.btn-black:not(:disabled):not(.disabled).active:focus,.btn-black:not(:disabled):not(.disabled):active:focus,.show>.btn-black.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(66,70,73,.5)}.btn-blue{color:#fff;background-color:#257af4;border-color:#257af4}.btn-blue.focus,.btn-blue:focus,.btn-blue:hover{color:#fff;background-color:#0c66e7;border-color:#0b60db}.btn-blue.focus,.btn-blue:focus{box-shadow:0 0 0 0 rgba(70,142,246,.5)}.btn-blue.disabled,.btn-blue:disabled{color:#fff;background-color:#257af4;border-color:#257af4}.btn-blue:not(:disabled):not(.disabled).active,.btn-blue:not(:disabled):not(.disabled):active,.show>.btn-blue.dropdown-toggle{color:#fff;background-color:#0b60db;border-color:#0a5bcf}.btn-blue:not(:disabled):not(.disabled).active:focus,.btn-blue:not(:disabled):not(.disabled):active:focus,.show>.btn-blue.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(70,142,246,.5)}.btn-light-blue{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-light-blue.focus,.btn-light-blue:focus,.btn-light-blue:hover{color:#495057;background-color:#bedffd;border-color:#b2d8fc}.btn-light-blue.focus,.btn-light-blue:focus{box-shadow:0 0 0 0 rgba(204,217,229,.5)}.btn-light-blue.disabled,.btn-light-blue:disabled{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-light-blue:not(:disabled):not(.disabled).active,.btn-light-blue:not(:disabled):not(.disabled):active,.show>.btn-light-blue.dropdown-toggle{color:#495057;background-color:#b2d8fc;border-color:#a5d2fc}.btn-light-blue:not(:disabled):not(.disabled).active:focus,.btn-light-blue:not(:disabled):not(.disabled):active:focus,.show>.btn-light-blue.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(204,217,229,.5)}.btn-yellow{color:#495057;background-color:#fc0;border-color:#fc0}.btn-yellow.focus,.btn-yellow:focus,.btn-yellow:hover{color:#495057;background-color:#d9ad00;border-color:#cca300}.btn-yellow.focus,.btn-yellow:focus{box-shadow:0 0 0 0 rgba(228,185,13,.5)}.btn-yellow.disabled,.btn-yellow:disabled{color:#495057;background-color:#fc0;border-color:#fc0}.btn-yellow:not(:disabled):not(.disabled).active,.btn-yellow:not(:disabled):not(.disabled):active,.show>.btn-yellow.dropdown-toggle{color:#495057;background-color:#cca300;border-color:#bf9900}.btn-yellow:not(:disabled):not(.disabled).active:focus,.btn-yellow:not(:disabled):not(.disabled):active:focus,.show>.btn-yellow.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,185,13,.5)}.btn-light-yellow{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-light-yellow.focus,.btn-light-yellow:focus,.btn-light-yellow:hover{color:#495057;background-color:#ffedca;border-color:#ffe9bd}.btn-light-yellow.focus,.btn-light-yellow:focus{box-shadow:0 0 0 0 rgba(228,225,217,.5)}.btn-light-yellow.disabled,.btn-light-yellow:disabled{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-light-yellow:not(:disabled):not(.disabled).active,.btn-light-yellow:not(:disabled):not(.disabled):active,.show>.btn-light-yellow.dropdown-toggle{color:#495057;background-color:#ffe9bd;border-color:#ffe5b0}.btn-light-yellow:not(:disabled):not(.disabled).active:focus,.btn-light-yellow:not(:disabled):not(.disabled):active:focus,.show>.btn-light-yellow.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,225,217,.5)}.btn-orange{color:#495057;background-color:#ff8c00;border-color:#ff8c00}.btn-orange.focus,.btn-orange:focus,.btn-orange:hover{color:#fff;background-color:#d97700;border-color:#cc7000}.btn-orange.focus,.btn-orange:focus{box-shadow:0 0 0 0 rgba(228,131,13,.5)}.btn-orange.disabled,.btn-orange:disabled{color:#495057;background-color:#ff8c00;border-color:#ff8c00}.btn-orange:not(:disabled):not(.disabled).active,.btn-orange:not(:disabled):not(.disabled):active,.show>.btn-orange.dropdown-toggle{color:#fff;background-color:#cc7000;border-color:#bf6900}.btn-orange:not(:disabled):not(.disabled).active:focus,.btn-orange:not(:disabled):not(.disabled):active:focus,.show>.btn-orange.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,131,13,.5)}.btn-light-orange{color:#495057;background-color:#ffe4b5;border-color:#ffe4b5}.btn-light-orange.focus,.btn-light-orange:focus,.btn-light-orange:hover{color:#495057;background-color:#ffd68f;border-color:#ffd182}.btn-light-orange.focus,.btn-light-orange:focus{box-shadow:0 0 0 0 rgba(228,206,167,.5)}.btn-light-orange.disabled,.btn-light-orange:disabled{color:#495057;background-color:#ffe4b5;border-color:#ffe4b5}.btn-light-orange:not(:disabled):not(.disabled).active,.btn-light-orange:not(:disabled):not(.disabled):active,.show>.btn-light-orange.dropdown-toggle{color:#495057;background-color:#ffd182;border-color:#ffcd75}.btn-light-orange:not(:disabled):not(.disabled).active:focus,.btn-light-orange:not(:disabled):not(.disabled):active:focus,.show>.btn-light-orange.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,206,167,.5)}.btn-red{color:#fff;background-color:#ff3939;border-color:#ff3939}.btn-red.focus,.btn-red:focus,.btn-red:hover{color:#fff;background-color:#ff1313;border-color:#ff0606}.btn-red.focus,.btn-red:focus{box-shadow:0 0 0 0 rgba(255,87,87,.5)}.btn-red.disabled,.btn-red:disabled{color:#fff;background-color:#ff3939;border-color:#ff3939}.btn-red:not(:disabled):not(.disabled).active,.btn-red:not(:disabled):not(.disabled):active,.show>.btn-red.dropdown-toggle{color:#fff;background-color:#ff0606;border-color:#f80000}.btn-red:not(:disabled):not(.disabled).active:focus,.btn-red:not(:disabled):not(.disabled):active:focus,.show>.btn-red.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,87,87,.5)}.btn-light-red{color:#495057;background-color:#ffe4e1;border-color:#ffe4e1}.btn-light-red.focus,.btn-light-red:focus,.btn-light-red:hover{color:#495057;background-color:#ffc2bb;border-color:#ffb6ae}.btn-light-red.focus,.btn-light-red:focus{box-shadow:0 0 0 0 rgba(228,206,204,.5)}.btn-light-red.disabled,.btn-light-red:disabled{color:#495057;background-color:#ffe4e1;border-color:#ffe4e1}.btn-light-red:not(:disabled):not(.disabled).active,.btn-light-red:not(:disabled):not(.disabled):active,.show>.btn-light-red.dropdown-toggle{color:#495057;background-color:#ffb6ae;border-color:#ffaba1}.btn-light-red:not(:disabled):not(.disabled).active:focus,.btn-light-red:not(:disabled):not(.disabled):active:focus,.show>.btn-light-red.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(228,206,204,.5)}.btn-medium{color:#495057;background-color:#d6dbdf;border-color:#d6dbdf}.btn-medium.focus,.btn-medium:focus,.btn-medium:hover{color:#495057;background-color:#c1c8ce;border-color:#b9c2c9}.btn-medium.focus,.btn-medium:focus{box-shadow:0 0 0 0 rgba(193,198,203,.5)}.btn-medium.disabled,.btn-medium:disabled{color:#495057;background-color:#d6dbdf;border-color:#d6dbdf}.btn-medium:not(:disabled):not(.disabled).active,.btn-medium:not(:disabled):not(.disabled):active,.show>.btn-medium.dropdown-toggle{color:#495057;background-color:#b9c2c9;border-color:#b2bcc3}.btn-medium:not(:disabled):not(.disabled).active:focus,.btn-medium:not(:disabled):not(.disabled):active:focus,.show>.btn-medium.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(193,198,203,.5)}.btn-outline-primary{color:#fc0;border-color:#fc0}.btn-outline-primary:hover{color:#495057;background-color:#fc0;border-color:#fc0}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(255,204,0,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#fc0;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#495057;background-color:#fc0;border-color:#fc0}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,204,0,.5)}.btn-outline-secondary{color:#212529;border-color:#212529}.btn-outline-secondary:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(33,37,41,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#212529;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(33,37,41,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#495057;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#495057;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(220,53,69,.5)}.btn-outline-light{color:#f1f6f9;border-color:#f1f6f9}.btn-outline-light:hover{color:#495057;background-color:#f1f6f9;border-color:#f1f6f9}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(241,246,249,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f1f6f9;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#495057;background-color:#f1f6f9;border-color:#f1f6f9}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(241,246,249,.5)}.btn-outline-dark{color:#495057;border-color:#495057}.btn-outline-dark:hover{color:#fff;background-color:#495057;border-color:#495057}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(73,80,87,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#495057;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#495057;border-color:#495057}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(73,80,87,.5)}.btn-outline-primary-light{color:#fffaf0;border-color:#fffaf0}.btn-outline-primary-light:hover{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-outline-primary-light.focus,.btn-outline-primary-light:focus{box-shadow:0 0 0 0 rgba(255,250,240,.5)}.btn-outline-primary-light.disabled,.btn-outline-primary-light:disabled{color:#fffaf0;background-color:transparent}.btn-outline-primary-light:not(:disabled):not(.disabled).active,.btn-outline-primary-light:not(:disabled):not(.disabled):active,.show>.btn-outline-primary-light.dropdown-toggle{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-outline-primary-light:not(:disabled):not(.disabled).active:focus,.btn-outline-primary-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,250,240,.5)}.btn-outline-secondary-light{color:#fff;border-color:#fff}.btn-outline-secondary-light:hover{color:#495057;background-color:#fff;border-color:#fff}.btn-outline-secondary-light.focus,.btn-outline-secondary-light:focus{box-shadow:0 0 0 0 hsla(0,0%,100%,.5)}.btn-outline-secondary-light.disabled,.btn-outline-secondary-light:disabled{color:#fff;background-color:transparent}.btn-outline-secondary-light:not(:disabled):not(.disabled).active,.btn-outline-secondary-light:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary-light.dropdown-toggle{color:#495057;background-color:#fff;border-color:#fff}.btn-outline-secondary-light:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary-light.dropdown-toggle:focus{box-shadow:0 0 0 0 hsla(0,0%,100%,.5)}.btn-outline-tertiary{color:#257af4;border-color:#257af4}.btn-outline-tertiary:hover{color:#fff;background-color:#257af4;border-color:#257af4}.btn-outline-tertiary.focus,.btn-outline-tertiary:focus{box-shadow:0 0 0 0 rgba(37,122,244,.5)}.btn-outline-tertiary.disabled,.btn-outline-tertiary:disabled{color:#257af4;background-color:transparent}.btn-outline-tertiary:not(:disabled):not(.disabled).active,.btn-outline-tertiary:not(:disabled):not(.disabled):active,.show>.btn-outline-tertiary.dropdown-toggle{color:#fff;background-color:#257af4;border-color:#257af4}.btn-outline-tertiary:not(:disabled):not(.disabled).active:focus,.btn-outline-tertiary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-tertiary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(37,122,244,.5)}.btn-outline-tertiary-light{color:#e3f1fe;border-color:#e3f1fe}.btn-outline-tertiary-light:hover{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-outline-tertiary-light.focus,.btn-outline-tertiary-light:focus{box-shadow:0 0 0 0 rgba(227,241,254,.5)}.btn-outline-tertiary-light.disabled,.btn-outline-tertiary-light:disabled{color:#e3f1fe;background-color:transparent}.btn-outline-tertiary-light:not(:disabled):not(.disabled).active,.btn-outline-tertiary-light:not(:disabled):not(.disabled):active,.show>.btn-outline-tertiary-light.dropdown-toggle{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-outline-tertiary-light:not(:disabled):not(.disabled).active:focus,.btn-outline-tertiary-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-tertiary-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(227,241,254,.5)}.btn-outline-white{color:#fff;border-color:#fff}.btn-outline-white:hover{color:#495057;background-color:#fff;border-color:#fff}.btn-outline-white.focus,.btn-outline-white:focus{box-shadow:0 0 0 0 hsla(0,0%,100%,.5)}.btn-outline-white.disabled,.btn-outline-white:disabled{color:#fff;background-color:transparent}.btn-outline-white:not(:disabled):not(.disabled).active,.btn-outline-white:not(:disabled):not(.disabled):active,.show>.btn-outline-white.dropdown-toggle{color:#495057;background-color:#fff;border-color:#fff}.btn-outline-white:not(:disabled):not(.disabled).active:focus,.btn-outline-white:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-white.dropdown-toggle:focus{box-shadow:0 0 0 0 hsla(0,0%,100%,.5)}.btn-outline-black{color:#212529;border-color:#212529}.btn-outline-black:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-black.focus,.btn-outline-black:focus{box-shadow:0 0 0 0 rgba(33,37,41,.5)}.btn-outline-black.disabled,.btn-outline-black:disabled{color:#212529;background-color:transparent}.btn-outline-black:not(:disabled):not(.disabled).active,.btn-outline-black:not(:disabled):not(.disabled):active,.show>.btn-outline-black.dropdown-toggle{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-black:not(:disabled):not(.disabled).active:focus,.btn-outline-black:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-black.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(33,37,41,.5)}.btn-outline-blue{color:#257af4;border-color:#257af4}.btn-outline-blue:hover{color:#fff;background-color:#257af4;border-color:#257af4}.btn-outline-blue.focus,.btn-outline-blue:focus{box-shadow:0 0 0 0 rgba(37,122,244,.5)}.btn-outline-blue.disabled,.btn-outline-blue:disabled{color:#257af4;background-color:transparent}.btn-outline-blue:not(:disabled):not(.disabled).active,.btn-outline-blue:not(:disabled):not(.disabled):active,.show>.btn-outline-blue.dropdown-toggle{color:#fff;background-color:#257af4;border-color:#257af4}.btn-outline-blue:not(:disabled):not(.disabled).active:focus,.btn-outline-blue:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-blue.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(37,122,244,.5)}.btn-outline-light-blue{color:#e3f1fe;border-color:#e3f1fe}.btn-outline-light-blue:hover{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-outline-light-blue.focus,.btn-outline-light-blue:focus{box-shadow:0 0 0 0 rgba(227,241,254,.5)}.btn-outline-light-blue.disabled,.btn-outline-light-blue:disabled{color:#e3f1fe;background-color:transparent}.btn-outline-light-blue:not(:disabled):not(.disabled).active,.btn-outline-light-blue:not(:disabled):not(.disabled):active,.show>.btn-outline-light-blue.dropdown-toggle{color:#495057;background-color:#e3f1fe;border-color:#e3f1fe}.btn-outline-light-blue:not(:disabled):not(.disabled).active:focus,.btn-outline-light-blue:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light-blue.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(227,241,254,.5)}.btn-outline-yellow{color:#fc0;border-color:#fc0}.btn-outline-yellow:hover{color:#495057;background-color:#fc0;border-color:#fc0}.btn-outline-yellow.focus,.btn-outline-yellow:focus{box-shadow:0 0 0 0 rgba(255,204,0,.5)}.btn-outline-yellow.disabled,.btn-outline-yellow:disabled{color:#fc0;background-color:transparent}.btn-outline-yellow:not(:disabled):not(.disabled).active,.btn-outline-yellow:not(:disabled):not(.disabled):active,.show>.btn-outline-yellow.dropdown-toggle{color:#495057;background-color:#fc0;border-color:#fc0}.btn-outline-yellow:not(:disabled):not(.disabled).active:focus,.btn-outline-yellow:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-yellow.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,204,0,.5)}.btn-outline-light-yellow{color:#fffaf0;border-color:#fffaf0}.btn-outline-light-yellow:hover{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-outline-light-yellow.focus,.btn-outline-light-yellow:focus{box-shadow:0 0 0 0 rgba(255,250,240,.5)}.btn-outline-light-yellow.disabled,.btn-outline-light-yellow:disabled{color:#fffaf0;background-color:transparent}.btn-outline-light-yellow:not(:disabled):not(.disabled).active,.btn-outline-light-yellow:not(:disabled):not(.disabled):active,.show>.btn-outline-light-yellow.dropdown-toggle{color:#495057;background-color:#fffaf0;border-color:#fffaf0}.btn-outline-light-yellow:not(:disabled):not(.disabled).active:focus,.btn-outline-light-yellow:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light-yellow.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,250,240,.5)}.btn-outline-orange{color:#ff8c00;border-color:#ff8c00}.btn-outline-orange:hover{color:#495057;background-color:#ff8c00;border-color:#ff8c00}.btn-outline-orange.focus,.btn-outline-orange:focus{box-shadow:0 0 0 0 rgba(255,140,0,.5)}.btn-outline-orange.disabled,.btn-outline-orange:disabled{color:#ff8c00;background-color:transparent}.btn-outline-orange:not(:disabled):not(.disabled).active,.btn-outline-orange:not(:disabled):not(.disabled):active,.show>.btn-outline-orange.dropdown-toggle{color:#495057;background-color:#ff8c00;border-color:#ff8c00}.btn-outline-orange:not(:disabled):not(.disabled).active:focus,.btn-outline-orange:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-orange.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,140,0,.5)}.btn-outline-light-orange{color:#ffe4b5;border-color:#ffe4b5}.btn-outline-light-orange:hover{color:#495057;background-color:#ffe4b5;border-color:#ffe4b5}.btn-outline-light-orange.focus,.btn-outline-light-orange:focus{box-shadow:0 0 0 0 rgba(255,228,181,.5)}.btn-outline-light-orange.disabled,.btn-outline-light-orange:disabled{color:#ffe4b5;background-color:transparent}.btn-outline-light-orange:not(:disabled):not(.disabled).active,.btn-outline-light-orange:not(:disabled):not(.disabled):active,.show>.btn-outline-light-orange.dropdown-toggle{color:#495057;background-color:#ffe4b5;border-color:#ffe4b5}.btn-outline-light-orange:not(:disabled):not(.disabled).active:focus,.btn-outline-light-orange:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light-orange.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,228,181,.5)}.btn-outline-red{color:#ff3939;border-color:#ff3939}.btn-outline-red:hover{color:#fff;background-color:#ff3939;border-color:#ff3939}.btn-outline-red.focus,.btn-outline-red:focus{box-shadow:0 0 0 0 rgba(255,57,57,.5)}.btn-outline-red.disabled,.btn-outline-red:disabled{color:#ff3939;background-color:transparent}.btn-outline-red:not(:disabled):not(.disabled).active,.btn-outline-red:not(:disabled):not(.disabled):active,.show>.btn-outline-red.dropdown-toggle{color:#fff;background-color:#ff3939;border-color:#ff3939}.btn-outline-red:not(:disabled):not(.disabled).active:focus,.btn-outline-red:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-red.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,57,57,.5)}.btn-outline-light-red{color:#ffe4e1;border-color:#ffe4e1}.btn-outline-light-red:hover{color:#495057;background-color:#ffe4e1;border-color:#ffe4e1}.btn-outline-light-red.focus,.btn-outline-light-red:focus{box-shadow:0 0 0 0 rgba(255,228,225,.5)}.btn-outline-light-red.disabled,.btn-outline-light-red:disabled{color:#ffe4e1;background-color:transparent}.btn-outline-light-red:not(:disabled):not(.disabled).active,.btn-outline-light-red:not(:disabled):not(.disabled):active,.show>.btn-outline-light-red.dropdown-toggle{color:#495057;background-color:#ffe4e1;border-color:#ffe4e1}.btn-outline-light-red:not(:disabled):not(.disabled).active:focus,.btn-outline-light-red:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light-red.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,228,225,.5)}.btn-outline-medium{color:#d6dbdf;border-color:#d6dbdf}.btn-outline-medium:hover{color:#495057;background-color:#d6dbdf;border-color:#d6dbdf}.btn-outline-medium.focus,.btn-outline-medium:focus{box-shadow:0 0 0 0 rgba(214,219,223,.5)}.btn-outline-medium.disabled,.btn-outline-medium:disabled{color:#d6dbdf;background-color:transparent}.btn-outline-medium:not(:disabled):not(.disabled).active,.btn-outline-medium:not(:disabled):not(.disabled):active,.show>.btn-outline-medium.dropdown-toggle{color:#495057;background-color:#d6dbdf;border-color:#d6dbdf}.btn-outline-medium:not(:disabled):not(.disabled).active:focus,.btn-outline-medium:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-medium.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(214,219,223,.5)}.btn-link{font-weight:400;color:#ff8c00;text-decoration:none}.btn-link:hover{color:#ff8c00;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#d6dbdf;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:16px 32px;font-size:1.125rem;line-height:26px;border-radius:8px}.btn-group-sm>.btn,.btn-sm{padding:12px 32px;font-size:.875rem;line-height:20px;border-radius:8px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:24px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media(prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(33,37,41,.15);border-radius:8px}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media(min-width:400px){.dropdown-menu-xs-left{right:auto;left:0}.dropdown-menu-xs-right{right:0;left:auto}}@media(min-width:616px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media(min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media(min-width:980px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media(min-width:1240px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:4px 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#495057;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#3d4349;text-decoration:none;background-color:#f1f6f9}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#fc0}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#495057}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:24px;padding-left:24px}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:24px;padding-left:24px}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 0%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label:after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#6c757d;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:8px}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.125rem;line-height:1.5;border-radius:8px}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:8px}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label:before{color:#fff;border-color:#fc0;background-color:#fc0}.custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 .2rem rgba(255,204,0,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#ffe680}.custom-control-input:not(:disabled):active~.custom-control-label:before{color:#fff;background-color:#fff0b3;border-color:#fff0b3}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label:before{pointer-events:none;background-color:#fff;border:1px solid #d6dbdf}.custom-control-label:after,.custom-control-label:before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:""}.custom-control-label:after{background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label:before{border-radius:8px}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{border-color:#fc0;background-color:#fc0}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(255,204,0,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:rgba(255,204,0,.5)}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(255,204,0,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label:after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#d6dbdf;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#fff;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(255,204,0,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#6c757d;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:8px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#ffe680;outline:0;box-shadow:0 0 0 .2rem rgba(255,204,0,.25)}.custom-select:focus::-ms-value{color:#6c757d;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #6c757d}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.125rem}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{position:relative;width:100%;height:calc(1.5em + .75rem + 2px)}.custom-file-input{z-index:2;margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#ffe680;box-shadow:0 0 0 .2rem rgba(255,204,0,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{left:0;z-index:1;height:calc(1.5em + .75rem + 2px);font-weight:400;background-color:#fff;border:1px solid #ced4da;border-radius:8px}.custom-file-label,.custom-file-label:after{position:absolute;top:0;right:0;padding:.375rem .75rem;line-height:1.5;color:#6c757d}.custom-file-label:after{bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 8px 8px 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:none}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(255,204,0,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(255,204,0,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(255,204,0,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#fc0;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media(prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#fff0b3}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#fc0;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media(prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#fff0b3}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#fc0;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media(prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#fff0b3}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#d6dbdf}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#d6dbdf}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#d6dbdf}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:0}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#d6dbdf;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #6c757d}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:8px;border-top-right-radius:8px}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:transparent}.nav-tabs .nav-link.disabled{color:#d6dbdf;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#257af4;background-color:#fff;border-color:#6c757d}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:8px}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#fc0}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:24px 0}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl,.navbar .container-xs{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:-.09375rem;padding-bottom:-.09375rem;margin-right:0;font-size:1.125rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:0;padding-bottom:0}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.125rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:8px}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat 50%;background-size:100% 100%}@media(max-width:399.98px){.navbar-expand-xs>.container,.navbar-expand-xs>.container-fluid,.navbar-expand-xs>.container-lg,.navbar-expand-xs>.container-md,.navbar-expand-xs>.container-sm,.navbar-expand-xs>.container-xl,.navbar-expand-xs>.container-xs{padding-right:0;padding-left:0}}@media(min-width:400px){.navbar-expand-xs{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xs .navbar-nav{flex-direction:row}.navbar-expand-xs .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xs .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xs>.container,.navbar-expand-xs>.container-fluid,.navbar-expand-xs>.container-lg,.navbar-expand-xs>.container-md,.navbar-expand-xs>.container-sm,.navbar-expand-xs>.container-xl,.navbar-expand-xs>.container-xs{flex-wrap:nowrap}.navbar-expand-xs .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xs .navbar-toggler{display:none}}@media(max-width:615.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl,.navbar-expand-sm>.container-xs{padding-right:0;padding-left:0}}@media(min-width:616px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl,.navbar-expand-sm>.container-xs{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media(max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl,.navbar-expand-md>.container-xs{padding-right:0;padding-left:0}}@media(min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl,.navbar-expand-md>.container-xs{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media(max-width:979.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl,.navbar-expand-lg>.container-xs{padding-right:0;padding-left:0}}@media(min-width:980px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl,.navbar-expand-lg>.container-xs{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media(max-width:1239.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl,.navbar-expand-xl>.container-xs{padding-right:0;padding-left:0}}@media(min-width:1240px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl,.navbar-expand-xl>.container-xs{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl,.navbar-expand>.container-xs{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl,.navbar-expand>.container-xs{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(33,37,41,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(33,37,41,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(33,37,41,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(33,37,41,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(33,37,41,.9)}.navbar-light .navbar-toggler{color:rgba(33,37,41,.5);border-color:rgba(33,37,41,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(33, 37, 41, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(33,37,41,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(33,37,41,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:hsla(0,0%,100%,.5);border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.5)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid #d6dbdf;border-radius:8px}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:8px;border-top-right-radius:8px}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:8px;border-bottom-left-radius:8px}.card-body{flex:1 1 auto;min-height:1px;padding:24px}.card-title{margin-bottom:24px}.card-subtitle{margin-top:-12px}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:24px}.card-header{padding:24px;margin-bottom:0;background-color:#f1f6f9;border-bottom:1px solid #d6dbdf}.card-header:first-child{border-radius:subtract(8px,1px) subtract(8px,1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:24px;background-color:#f1f6f9;border-top:1px solid #d6dbdf}.card-footer:last-child{border-radius:0 0 subtract(8px,1px) subtract(8px,1px)}.card-header-tabs{margin-bottom:-24px;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-12px;margin-left:-12px}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:24px}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:subtract(8px,1px);border-top-right-radius:subtract(8px,1px)}.card-img,.card-img-bottom{border-bottom-right-radius:subtract(8px,1px);border-bottom-left-radius:subtract(8px,1px)}.card-deck .card{margin-bottom:20px}@media(min-width:616px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-20px;margin-left:-20px}.card-deck .card{flex:1 0 0%;margin-right:20px;margin-bottom:0;margin-left:20px}}.card-group>.card{margin-bottom:20px}@media(min-width:616px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:40px}@media(min-width:616px){.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:40px;column-gap:40px;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:8px}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:8px}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#ff8c00;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#ff8c00;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(255,204,0,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:8px;border-bottom-left-radius:8px}.page-item:last-child .page-link{border-top-right-radius:8px;border-bottom-right-radius:8px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#fc0;border-color:#fc0}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.125rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:8px;border-bottom-left-radius:8px}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:8px;border-bottom-right-radius:8px}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:8px;border-bottom-left-radius:8px}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:8px;border-bottom-right-radius:8px}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:8px;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#495057;background-color:#fc0}a.badge-primary:focus,a.badge-primary:hover{color:#495057;background-color:#cca300}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,204,0,.5)}.badge-secondary{color:#fff;background-color:#212529}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#0a0c0d}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(33,37,41,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#495057;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#495057;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#495057;background-color:#f1f6f9}a.badge-light:focus,a.badge-light:hover{color:#495057;background-color:#cddfea}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(241,246,249,.5)}.badge-dark{color:#fff;background-color:#495057}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#32373b}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(73,80,87,.5)}.badge-primary-light{color:#495057;background-color:#fffaf0}a.badge-primary-light:focus,a.badge-primary-light:hover{color:#495057;background-color:#ffe9bd}a.badge-primary-light.focus,a.badge-primary-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,250,240,.5)}.badge-secondary-light{color:#495057;background-color:#fff}a.badge-secondary-light:focus,a.badge-secondary-light:hover{color:#495057;background-color:#e6e6e6}a.badge-secondary-light.focus,a.badge-secondary-light:focus{outline:0;box-shadow:0 0 0 .2rem hsla(0,0%,100%,.5)}.badge-tertiary{color:#fff;background-color:#257af4}a.badge-tertiary:focus,a.badge-tertiary:hover{color:#fff;background-color:#0b60db}a.badge-tertiary.focus,a.badge-tertiary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(37,122,244,.5)}.badge-tertiary-light{color:#495057;background-color:#e3f1fe}a.badge-tertiary-light:focus,a.badge-tertiary-light:hover{color:#495057;background-color:#b2d8fc}a.badge-tertiary-light.focus,a.badge-tertiary-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(227,241,254,.5)}.badge-white{color:#495057;background-color:#fff}a.badge-white:focus,a.badge-white:hover{color:#495057;background-color:#e6e6e6}a.badge-white.focus,a.badge-white:focus{outline:0;box-shadow:0 0 0 .2rem hsla(0,0%,100%,.5)}.badge-black{color:#fff;background-color:#212529}a.badge-black:focus,a.badge-black:hover{color:#fff;background-color:#0a0c0d}a.badge-black.focus,a.badge-black:focus{outline:0;box-shadow:0 0 0 .2rem rgba(33,37,41,.5)}.badge-blue{color:#fff;background-color:#257af4}a.badge-blue:focus,a.badge-blue:hover{color:#fff;background-color:#0b60db}a.badge-blue.focus,a.badge-blue:focus{outline:0;box-shadow:0 0 0 .2rem rgba(37,122,244,.5)}.badge-light-blue{color:#495057;background-color:#e3f1fe}a.badge-light-blue:focus,a.badge-light-blue:hover{color:#495057;background-color:#b2d8fc}a.badge-light-blue.focus,a.badge-light-blue:focus{outline:0;box-shadow:0 0 0 .2rem rgba(227,241,254,.5)}.badge-yellow{color:#495057;background-color:#fc0}a.badge-yellow:focus,a.badge-yellow:hover{color:#495057;background-color:#cca300}a.badge-yellow.focus,a.badge-yellow:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,204,0,.5)}.badge-light-yellow{color:#495057;background-color:#fffaf0}a.badge-light-yellow:focus,a.badge-light-yellow:hover{color:#495057;background-color:#ffe9bd}a.badge-light-yellow.focus,a.badge-light-yellow:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,250,240,.5)}.badge-orange{color:#495057;background-color:#ff8c00}a.badge-orange:focus,a.badge-orange:hover{color:#495057;background-color:#cc7000}a.badge-orange.focus,a.badge-orange:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,140,0,.5)}.badge-light-orange{color:#495057;background-color:#ffe4b5}a.badge-light-orange:focus,a.badge-light-orange:hover{color:#495057;background-color:#ffd182}a.badge-light-orange.focus,a.badge-light-orange:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,228,181,.5)}.badge-red{color:#fff;background-color:#ff3939}a.badge-red:focus,a.badge-red:hover{color:#fff;background-color:#ff0606}a.badge-red.focus,a.badge-red:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,57,57,.5)}.badge-light-red{color:#495057;background-color:#ffe4e1}a.badge-light-red:focus,a.badge-light-red:hover{color:#495057;background-color:#ffb6ae}a.badge-light-red.focus,a.badge-light-red:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,228,225,.5)}.badge-medium{color:#495057;background-color:#d6dbdf}a.badge-medium:focus,a.badge-medium:hover{color:#495057;background-color:#b9c2c9}a.badge-medium.focus,a.badge-medium:focus{outline:0;box-shadow:0 0 0 .2rem rgba(214,219,223,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:8px}@media(min-width:616px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:8px}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#947c14;background-color:#fff5cc;border-color:#fff1b8}.alert-primary hr{border-top-color:#ffec9f}.alert-primary .alert-link{color:#67560e}.alert-secondary{color:#212529;background-color:#d3d3d4;border-color:#c1c2c3}.alert-secondary hr{border-top-color:#b4b5b6}.alert-secondary .alert-link{color:#0a0c0d}.alert-success{color:#256938;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#184324}.alert-info{color:#1c6673;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#12424a}.alert-warning{color:#947617;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#685310}.alert-danger{color:#822d38;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#5c2028}.alert-light{color:#8d9295;background-color:#fcfdfe;border-color:#fbfcfd}.alert-light hr{border-top-color:#eaeff5}.alert-light .alert-link{color:#73797c}.alert-dark{color:#363b41;background-color:#dbdcdd;border-color:#ccced0}.alert-dark hr{border-top-color:#bfc1c4}.alert-dark .alert-link{color:#1f2225}.alert-primary-light{color:#949490;background-color:#fffefc;border-color:#fffefb}.alert-primary-light hr{border-top-color:#fff8e2}.alert-primary-light .alert-link{color:#7b7b76}.alert-secondary-light{color:#949698;background-color:#fff;border-color:#fff}.alert-secondary-light hr{border-top-color:#f2f2f2}.alert-secondary-light .alert-link{color:#7a7d7f}.alert-tertiary{color:#235193;background-color:#d3e4fd;border-color:#c2dafc}.alert-tertiary hr{border-top-color:#aacbfb}.alert-tertiary .alert-link{color:#193a6a}.alert-tertiary-light{color:#868f98;background-color:#f9fcff;border-color:#f7fbff}.alert-tertiary-light hr{border-top-color:#deeeff}.alert-tertiary-light .alert-link{color:#6c767f}.alert-white{color:#949698;background-color:#fff;border-color:#fff}.alert-white hr{border-top-color:#f2f2f2}.alert-white .alert-link{color:#7a7d7f}.alert-black{color:#212529;background-color:#d3d3d4;border-color:#c1c2c3}.alert-black hr{border-top-color:#b4b5b6}.alert-black .alert-link{color:#0a0c0d}.alert-blue{color:#235193;background-color:#d3e4fd;border-color:#c2dafc}.alert-blue hr{border-top-color:#aacbfb}.alert-blue .alert-link{color:#193a6a}.alert-light-blue{color:#868f98;background-color:#f9fcff;border-color:#f7fbff}.alert-light-blue hr{border-top-color:#deeeff}.alert-light-blue .alert-link{color:#6c767f}.alert-yellow{color:#947c14;background-color:#fff5cc;border-color:#fff1b8}.alert-yellow hr{border-top-color:#ffec9f}.alert-yellow .alert-link{color:#67560e}.alert-light-yellow{color:#949490;background-color:#fffefc;border-color:#fffefb}.alert-light-yellow hr{border-top-color:#fff8e2}.alert-light-yellow .alert-link{color:#7b7b76}.alert-orange{color:#945b14;background-color:#ffe8cc;border-color:#ffdfb8}.alert-orange hr{border-top-color:#ffd49f}.alert-orange .alert-link{color:#673f0e}.alert-light-orange{color:#948872;background-color:#fffaf0;border-color:#fff7ea}.alert-light-orange hr{border-top-color:#ffedd1}.alert-light-orange .alert-link{color:#786e5b}.alert-red{color:#942f31;background-color:#ffd7d7;border-color:#ffc8c8}.alert-red hr{border-top-color:#ffafaf}.alert-red .alert-link{color:#6d2324}.alert-light-red{color:#948889;background-color:#fffaf9;border-color:#fff7f7}.alert-light-red hr{border-top-color:#ffdede}.alert-light-red .alert-link{color:#7b6e6f}.alert-medium{color:#7f8488;background-color:#f7f8f9;border-color:#f4f5f6}.alert-medium hr{border-top-color:#e6e8eb}.alert-medium .alert-link{color:#666a6e}@-webkit-keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{height:1rem;font-size:.75rem;background-color:#e9ecef;border-radius:8px}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#fc0;transition:width .6s ease}@media(prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media(prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#6c757d;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#6c757d;text-decoration:none;background-color:#f1f6f9}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(33,37,41,.125)}.list-group-item:first-child{border-top-left-radius:8px;border-top-right-radius:8px}.list-group-item:last-child{border-bottom-right-radius:8px;border-bottom-left-radius:8px}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#fc0;border-color:#fc0}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal .list-group-item:first-child{border-bottom-left-radius:8px;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{border-top-right-radius:8px;border-bottom-left-radius:0}.list-group-horizontal .list-group-item.active{margin-top:0}.list-group-horizontal .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width:400px){.list-group-horizontal-xs{flex-direction:row}.list-group-horizontal-xs .list-group-item:first-child{border-bottom-left-radius:8px;border-top-right-radius:0}.list-group-horizontal-xs .list-group-item:last-child{border-top-right-radius:8px;border-bottom-left-radius:0}.list-group-horizontal-xs .list-group-item.active{margin-top:0}.list-group-horizontal-xs .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xs .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:616px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm .list-group-item:first-child{border-bottom-left-radius:8px;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{border-top-right-radius:8px;border-bottom-left-radius:0}.list-group-horizontal-sm .list-group-item.active{margin-top:0}.list-group-horizontal-sm .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md .list-group-item:first-child{border-bottom-left-radius:8px;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{border-top-right-radius:8px;border-bottom-left-radius:0}.list-group-horizontal-md .list-group-item.active{margin-top:0}.list-group-horizontal-md .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:980px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg .list-group-item:first-child{border-bottom-left-radius:8px;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{border-top-right-radius:8px;border-bottom-left-radius:0}.list-group-horizontal-lg .list-group-item.active{margin-top:0}.list-group-horizontal-lg .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width:1240px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl .list-group-item:first-child{border-bottom-left-radius:8px;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{border-top-right-radius:8px;border-bottom-left-radius:0}.list-group-horizontal-xl .list-group-item.active{margin-top:0}.list-group-horizontal-xl .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush .list-group-item{border-right-width:0;border-left-width:0;border-radius:0}.list-group-flush .list-group-item:first-child{border-top-width:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#947c14;background-color:#fff1b8}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#947c14;background-color:#ffec9f}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#947c14;border-color:#947c14}.list-group-item-secondary{color:#212529;background-color:#c1c2c3}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#212529;background-color:#b4b5b6}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#212529;border-color:#212529}.list-group-item-success{color:#256938;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#256938;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#256938;border-color:#256938}.list-group-item-info{color:#1c6673;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#1c6673;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#1c6673;border-color:#1c6673}.list-group-item-warning{color:#947617;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#947617;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#947617;border-color:#947617}.list-group-item-danger{color:#822d38;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#822d38;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#822d38;border-color:#822d38}.list-group-item-light{color:#8d9295;background-color:#fbfcfd}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#8d9295;background-color:#eaeff5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#8d9295;border-color:#8d9295}.list-group-item-dark{color:#363b41;background-color:#ccced0}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#363b41;background-color:#bfc1c4}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#363b41;border-color:#363b41}.list-group-item-primary-light{color:#949490;background-color:#fffefb}.list-group-item-primary-light.list-group-item-action:focus,.list-group-item-primary-light.list-group-item-action:hover{color:#949490;background-color:#fff8e2}.list-group-item-primary-light.list-group-item-action.active{color:#fff;background-color:#949490;border-color:#949490}.list-group-item-secondary-light{color:#949698;background-color:#fff}.list-group-item-secondary-light.list-group-item-action:focus,.list-group-item-secondary-light.list-group-item-action:hover{color:#949698;background-color:#f2f2f2}.list-group-item-secondary-light.list-group-item-action.active{color:#fff;background-color:#949698;border-color:#949698}.list-group-item-tertiary{color:#235193;background-color:#c2dafc}.list-group-item-tertiary.list-group-item-action:focus,.list-group-item-tertiary.list-group-item-action:hover{color:#235193;background-color:#aacbfb}.list-group-item-tertiary.list-group-item-action.active{color:#fff;background-color:#235193;border-color:#235193}.list-group-item-tertiary-light{color:#868f98;background-color:#f7fbff}.list-group-item-tertiary-light.list-group-item-action:focus,.list-group-item-tertiary-light.list-group-item-action:hover{color:#868f98;background-color:#deeeff}.list-group-item-tertiary-light.list-group-item-action.active{color:#fff;background-color:#868f98;border-color:#868f98}.list-group-item-white{color:#949698;background-color:#fff}.list-group-item-white.list-group-item-action:focus,.list-group-item-white.list-group-item-action:hover{color:#949698;background-color:#f2f2f2}.list-group-item-white.list-group-item-action.active{color:#fff;background-color:#949698;border-color:#949698}.list-group-item-black{color:#212529;background-color:#c1c2c3}.list-group-item-black.list-group-item-action:focus,.list-group-item-black.list-group-item-action:hover{color:#212529;background-color:#b4b5b6}.list-group-item-black.list-group-item-action.active{color:#fff;background-color:#212529;border-color:#212529}.list-group-item-blue{color:#235193;background-color:#c2dafc}.list-group-item-blue.list-group-item-action:focus,.list-group-item-blue.list-group-item-action:hover{color:#235193;background-color:#aacbfb}.list-group-item-blue.list-group-item-action.active{color:#fff;background-color:#235193;border-color:#235193}.list-group-item-light-blue{color:#868f98;background-color:#f7fbff}.list-group-item-light-blue.list-group-item-action:focus,.list-group-item-light-blue.list-group-item-action:hover{color:#868f98;background-color:#deeeff}.list-group-item-light-blue.list-group-item-action.active{color:#fff;background-color:#868f98;border-color:#868f98}.list-group-item-yellow{color:#947c14;background-color:#fff1b8}.list-group-item-yellow.list-group-item-action:focus,.list-group-item-yellow.list-group-item-action:hover{color:#947c14;background-color:#ffec9f}.list-group-item-yellow.list-group-item-action.active{color:#fff;background-color:#947c14;border-color:#947c14}.list-group-item-light-yellow{color:#949490;background-color:#fffefb}.list-group-item-light-yellow.list-group-item-action:focus,.list-group-item-light-yellow.list-group-item-action:hover{color:#949490;background-color:#fff8e2}.list-group-item-light-yellow.list-group-item-action.active{color:#fff;background-color:#949490;border-color:#949490}.list-group-item-orange{color:#945b14;background-color:#ffdfb8}.list-group-item-orange.list-group-item-action:focus,.list-group-item-orange.list-group-item-action:hover{color:#945b14;background-color:#ffd49f}.list-group-item-orange.list-group-item-action.active{color:#fff;background-color:#945b14;border-color:#945b14}.list-group-item-light-orange{color:#948872;background-color:#fff7ea}.list-group-item-light-orange.list-group-item-action:focus,.list-group-item-light-orange.list-group-item-action:hover{color:#948872;background-color:#ffedd1}.list-group-item-light-orange.list-group-item-action.active{color:#fff;background-color:#948872;border-color:#948872}.list-group-item-red{color:#942f31;background-color:#ffc8c8}.list-group-item-red.list-group-item-action:focus,.list-group-item-red.list-group-item-action:hover{color:#942f31;background-color:#ffafaf}.list-group-item-red.list-group-item-action.active{color:#fff;background-color:#942f31;border-color:#942f31}.list-group-item-light-red{color:#948889;background-color:#fff7f7}.list-group-item-light-red.list-group-item-action:focus,.list-group-item-light-red.list-group-item-action:hover{color:#948889;background-color:#ffdede}.list-group-item-light-red.list-group-item-action.active{color:#fff;background-color:#948889;border-color:#948889}.list-group-item-medium{color:#7f8488;background-color:#f4f5f6}.list-group-item-medium.list-group-item-action:focus,.list-group-item-medium.list-group-item-action:hover{color:#7f8488;background-color:#e6e8eb}.list-group-item-medium.list-group-item-action.active{color:#fff;background-color:#7f8488;border-color:#7f8488}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#212529;text-shadow:0 1px 0 #fff;opacity:.5}@media(max-width:1200px){.close{font-size:calc(1.275rem + .3vw)}}.close:hover{color:#212529;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(33,37,41,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media(prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(33,37,41,.2);border-radius:8px;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#212529}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #d6dbdf;border-top-left-radius:7px;border-top-right-radius:7px}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #d6dbdf;border-bottom-right-radius:7px;border-bottom-left-radius:7px}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media(min-width:616px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media(min-width:980px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width:1240px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:Noto Sans,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow:before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{top:0;border-width:.4rem .4rem 0;border-top-color:#212529}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#212529}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#212529}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#212529}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#212529;border-radius:8px}.popover{top:0;left:0;z-index:1060;max-width:276px;font-family:Noto Sans,sans-serif;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(33,37,41,.2);border-radius:8px}.popover,.popover .arrow{position:absolute;display:block}.popover .arrow{width:1rem;height:.5rem;margin:0 8px}.popover .arrow:after,.popover .arrow:before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(33,37,41,.25)}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:8px 0}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(33,37,41,.25)}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{top:0;border-width:0 .5rem .5rem;border-bottom-color:rgba(33,37,41,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{top:1px;border-width:0 .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:8px 0}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(33,37,41,.25)}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:7px;border-top-right-radius:7px}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner:after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8'%3E%3Cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{transform:rotate(1turn)}}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid;border-right:.25em solid transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#fc0!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#cca300!important}.bg-secondary{background-color:#212529!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#0a0c0d!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f1f6f9!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#cddfea!important}.bg-dark{background-color:#495057!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#32373b!important}.bg-primary-light{background-color:#fffaf0!important}a.bg-primary-light:focus,a.bg-primary-light:hover,button.bg-primary-light:focus,button.bg-primary-light:hover{background-color:#ffe9bd!important}.bg-secondary-light{background-color:#fff!important}a.bg-secondary-light:focus,a.bg-secondary-light:hover,button.bg-secondary-light:focus,button.bg-secondary-light:hover{background-color:#e6e6e6!important}.bg-tertiary{background-color:#257af4!important}a.bg-tertiary:focus,a.bg-tertiary:hover,button.bg-tertiary:focus,button.bg-tertiary:hover{background-color:#0b60db!important}.bg-tertiary-light{background-color:#e3f1fe!important}a.bg-tertiary-light:focus,a.bg-tertiary-light:hover,button.bg-tertiary-light:focus,button.bg-tertiary-light:hover{background-color:#b2d8fc!important}a.bg-white:focus,a.bg-white:hover,button.bg-white:focus,button.bg-white:hover{background-color:#e6e6e6!important}.bg-black{background-color:#212529!important}a.bg-black:focus,a.bg-black:hover,button.bg-black:focus,button.bg-black:hover{background-color:#0a0c0d!important}.bg-blue{background-color:#257af4!important}a.bg-blue:focus,a.bg-blue:hover,button.bg-blue:focus,button.bg-blue:hover{background-color:#0b60db!important}.bg-light-blue{background-color:#e3f1fe!important}a.bg-light-blue:focus,a.bg-light-blue:hover,button.bg-light-blue:focus,button.bg-light-blue:hover{background-color:#b2d8fc!important}.bg-yellow{background-color:#fc0!important}a.bg-yellow:focus,a.bg-yellow:hover,button.bg-yellow:focus,button.bg-yellow:hover{background-color:#cca300!important}.bg-light-yellow{background-color:#fffaf0!important}a.bg-light-yellow:focus,a.bg-light-yellow:hover,button.bg-light-yellow:focus,button.bg-light-yellow:hover{background-color:#ffe9bd!important}.bg-orange{background-color:#ff8c00!important}a.bg-orange:focus,a.bg-orange:hover,button.bg-orange:focus,button.bg-orange:hover{background-color:#cc7000!important}.bg-light-orange{background-color:#ffe4b5!important}a.bg-light-orange:focus,a.bg-light-orange:hover,button.bg-light-orange:focus,button.bg-light-orange:hover{background-color:#ffd182!important}.bg-red{background-color:#ff3939!important}a.bg-red:focus,a.bg-red:hover,button.bg-red:focus,button.bg-red:hover{background-color:#ff0606!important}.bg-light-red{background-color:#ffe4e1!important}a.bg-light-red:focus,a.bg-light-red:hover,button.bg-light-red:focus,button.bg-light-red:hover{background-color:#ffb6ae!important}.bg-medium{background-color:#d6dbdf!important}a.bg-medium:focus,a.bg-medium:hover,button.bg-medium:focus,button.bg-medium:hover{background-color:#b9c2c9!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #d6dbdf!important}.border-top{border-top:1px solid #d6dbdf!important}.border-right{border-right:1px solid #d6dbdf!important}.border-bottom{border-bottom:1px solid #d6dbdf!important}.border-left{border-left:1px solid #d6dbdf!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#fc0!important}.border-secondary{border-color:#212529!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f1f6f9!important}.border-dark{border-color:#495057!important}.border-primary-light{border-color:#fffaf0!important}.border-secondary-light{border-color:#fff!important}.border-tertiary{border-color:#257af4!important}.border-tertiary-light{border-color:#e3f1fe!important}.border-black{border-color:#212529!important}.border-blue{border-color:#257af4!important}.border-light-blue{border-color:#e3f1fe!important}.border-yellow{border-color:#fc0!important}.border-light-yellow{border-color:#fffaf0!important}.border-orange{border-color:#ff8c00!important}.border-light-orange{border-color:#ffe4b5!important}.border-red{border-color:#ff3939!important}.border-light-red{border-color:#ffe4e1!important}.border-medium{border-color:#d6dbdf!important}.border-white{border-color:#fff!important}.rounded,.rounded-sm{border-radius:8px!important}.rounded-top{border-top-left-radius:8px!important}.rounded-right,.rounded-top{border-top-right-radius:8px!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:8px!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:8px!important}.rounded-left{border-top-left-radius:8px!important}.rounded-lg{border-radius:8px!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media(min-width:400px){.d-xs-none{display:none!important}.d-xs-inline{display:inline!important}.d-xs-inline-block{display:inline-block!important}.d-xs-block{display:block!important}.d-xs-table{display:table!important}.d-xs-table-row{display:table-row!important}.d-xs-table-cell{display:table-cell!important}.d-xs-flex{display:flex!important}.d-xs-inline-flex{display:inline-flex!important}}@media(min-width:616px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media(min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media(min-width:980px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media(min-width:1240px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.8571428571%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media(min-width:400px){.flex-xs-row{flex-direction:row!important}.flex-xs-column{flex-direction:column!important}.flex-xs-row-reverse{flex-direction:row-reverse!important}.flex-xs-column-reverse{flex-direction:column-reverse!important}.flex-xs-wrap{flex-wrap:wrap!important}.flex-xs-nowrap{flex-wrap:nowrap!important}.flex-xs-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xs-fill{flex:1 1 auto!important}.flex-xs-grow-0{flex-grow:0!important}.flex-xs-grow-1{flex-grow:1!important}.flex-xs-shrink-0{flex-shrink:0!important}.flex-xs-shrink-1{flex-shrink:1!important}.justify-content-xs-start{justify-content:flex-start!important}.justify-content-xs-end{justify-content:flex-end!important}.justify-content-xs-center{justify-content:center!important}.justify-content-xs-between{justify-content:space-between!important}.justify-content-xs-around{justify-content:space-around!important}.align-items-xs-start{align-items:flex-start!important}.align-items-xs-end{align-items:flex-end!important}.align-items-xs-center{align-items:center!important}.align-items-xs-baseline{align-items:baseline!important}.align-items-xs-stretch{align-items:stretch!important}.align-content-xs-start{align-content:flex-start!important}.align-content-xs-end{align-content:flex-end!important}.align-content-xs-center{align-content:center!important}.align-content-xs-between{align-content:space-between!important}.align-content-xs-around{align-content:space-around!important}.align-content-xs-stretch{align-content:stretch!important}.align-self-xs-auto{align-self:auto!important}.align-self-xs-start{align-self:flex-start!important}.align-self-xs-end{align-self:flex-end!important}.align-self-xs-center{align-self:center!important}.align-self-xs-baseline{align-self:baseline!important}.align-self-xs-stretch{align-self:stretch!important}}@media(min-width:616px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media(min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media(min-width:980px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media(min-width:1240px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media(min-width:400px){.float-xs-left{float:left!important}.float-xs-right{float:right!important}.float-xs-none{float:none!important}}@media(min-width:616px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media(min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media(min-width:980px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media(min-width:1240px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports(position:sticky){.sticky-top{position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 2px 14px rgba(108,117,125,.2)!important}.shadow{box-shadow:0 8px 20px rgba(108,117,125,.2)!important}.shadow-lg{box-shadow:0 12px 32px rgba(108,117,125,.2)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:transparent}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:8px!important}.mt-1,.my-1{margin-top:8px!important}.mr-1,.mx-1{margin-right:8px!important}.mb-1,.my-1{margin-bottom:8px!important}.ml-1,.mx-1{margin-left:8px!important}.m-2{margin:16px!important}.mt-2,.my-2{margin-top:16px!important}.mr-2,.mx-2{margin-right:16px!important}.mb-2,.my-2{margin-bottom:16px!important}.ml-2,.mx-2{margin-left:16px!important}.m-3{margin:24px!important}.mt-3,.my-3{margin-top:24px!important}.mr-3,.mx-3{margin-right:24px!important}.mb-3,.my-3{margin-bottom:24px!important}.ml-3,.mx-3{margin-left:24px!important}.m-4{margin:32px!important}.mt-4,.my-4{margin-top:32px!important}.mr-4,.mx-4{margin-right:32px!important}.mb-4,.my-4{margin-bottom:32px!important}.ml-4,.mx-4{margin-left:32px!important}.m-5{margin:40px!important}.mt-5,.my-5{margin-top:40px!important}.mr-5,.mx-5{margin-right:40px!important}.mb-5,.my-5{margin-bottom:40px!important}.ml-5,.mx-5{margin-left:40px!important}.m-6{margin:48px!important}.mt-6,.my-6{margin-top:48px!important}.mr-6,.mx-6{margin-right:48px!important}.mb-6,.my-6{margin-bottom:48px!important}.ml-6,.mx-6{margin-left:48px!important}.m-7{margin:56px!important}.mt-7,.my-7{margin-top:56px!important}.mr-7,.mx-7{margin-right:56px!important}.mb-7,.my-7{margin-bottom:56px!important}.ml-7,.mx-7{margin-left:56px!important}.m-8{margin:64px!important}.mt-8,.my-8{margin-top:64px!important}.mr-8,.mx-8{margin-right:64px!important}.mb-8,.my-8{margin-bottom:64px!important}.ml-8,.mx-8{margin-left:64px!important}.m-9{margin:72px!important}.mt-9,.my-9{margin-top:72px!important}.mr-9,.mx-9{margin-right:72px!important}.mb-9,.my-9{margin-bottom:72px!important}.ml-9,.mx-9{margin-left:72px!important}.m-10{margin:80px!important}.mt-10,.my-10{margin-top:80px!important}.mr-10,.mx-10{margin-right:80px!important}.mb-10,.my-10{margin-bottom:80px!important}.ml-10,.mx-10{margin-left:80px!important}.m-12{margin:96px!important}.mt-12,.my-12{margin-top:96px!important}.mr-12,.mx-12{margin-right:96px!important}.mb-12,.my-12{margin-bottom:96px!important}.ml-12,.mx-12{margin-left:96px!important}.m-15{margin:120px!important}.mt-15,.my-15{margin-top:120px!important}.mr-15,.mx-15{margin-right:120px!important}.mb-15,.my-15{margin-bottom:120px!important}.ml-15,.mx-15{margin-left:120px!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:8px!important}.pt-1,.py-1{padding-top:8px!important}.pr-1,.px-1{padding-right:8px!important}.pb-1,.py-1{padding-bottom:8px!important}.pl-1,.px-1{padding-left:8px!important}.p-2{padding:16px!important}.pt-2,.py-2{padding-top:16px!important}.pr-2,.px-2{padding-right:16px!important}.pb-2,.py-2{padding-bottom:16px!important}.pl-2,.px-2{padding-left:16px!important}.p-3{padding:24px!important}.pt-3,.py-3{padding-top:24px!important}.pr-3,.px-3{padding-right:24px!important}.pb-3,.py-3{padding-bottom:24px!important}.pl-3,.px-3{padding-left:24px!important}.p-4{padding:32px!important}.pt-4,.py-4{padding-top:32px!important}.pr-4,.px-4{padding-right:32px!important}.pb-4,.py-4{padding-bottom:32px!important}.pl-4,.px-4{padding-left:32px!important}.p-5{padding:40px!important}.pt-5,.py-5{padding-top:40px!important}.pr-5,.px-5{padding-right:40px!important}.pb-5,.py-5{padding-bottom:40px!important}.pl-5,.px-5{padding-left:40px!important}.p-6{padding:48px!important}.pt-6,.py-6{padding-top:48px!important}.pr-6,.px-6{padding-right:48px!important}.pb-6,.py-6{padding-bottom:48px!important}.pl-6,.px-6{padding-left:48px!important}.p-7{padding:56px!important}.pt-7,.py-7{padding-top:56px!important}.pr-7,.px-7{padding-right:56px!important}.pb-7,.py-7{padding-bottom:56px!important}.pl-7,.px-7{padding-left:56px!important}.p-8{padding:64px!important}.pt-8,.py-8{padding-top:64px!important}.pr-8,.px-8{padding-right:64px!important}.pb-8,.py-8{padding-bottom:64px!important}.pl-8,.px-8{padding-left:64px!important}.p-9{padding:72px!important}.pt-9,.py-9{padding-top:72px!important}.pr-9,.px-9{padding-right:72px!important}.pb-9,.py-9{padding-bottom:72px!important}.pl-9,.px-9{padding-left:72px!important}.p-10{padding:80px!important}.pt-10,.py-10{padding-top:80px!important}.pr-10,.px-10{padding-right:80px!important}.pb-10,.py-10{padding-bottom:80px!important}.pl-10,.px-10{padding-left:80px!important}.p-12{padding:96px!important}.pt-12,.py-12{padding-top:96px!important}.pr-12,.px-12{padding-right:96px!important}.pb-12,.py-12{padding-bottom:96px!important}.pl-12,.px-12{padding-left:96px!important}.p-15{padding:120px!important}.pt-15,.py-15{padding-top:120px!important}.pr-15,.px-15{padding-right:120px!important}.pb-15,.py-15{padding-bottom:120px!important}.pl-15,.px-15{padding-left:120px!important}.m-n1{margin:-8px!important}.mt-n1,.my-n1{margin-top:-8px!important}.mr-n1,.mx-n1{margin-right:-8px!important}.mb-n1,.my-n1{margin-bottom:-8px!important}.ml-n1,.mx-n1{margin-left:-8px!important}.m-n2{margin:-16px!important}.mt-n2,.my-n2{margin-top:-16px!important}.mr-n2,.mx-n2{margin-right:-16px!important}.mb-n2,.my-n2{margin-bottom:-16px!important}.ml-n2,.mx-n2{margin-left:-16px!important}.m-n3{margin:-24px!important}.mt-n3,.my-n3{margin-top:-24px!important}.mr-n3,.mx-n3{margin-right:-24px!important}.mb-n3,.my-n3{margin-bottom:-24px!important}.ml-n3,.mx-n3{margin-left:-24px!important}.m-n4{margin:-32px!important}.mt-n4,.my-n4{margin-top:-32px!important}.mr-n4,.mx-n4{margin-right:-32px!important}.mb-n4,.my-n4{margin-bottom:-32px!important}.ml-n4,.mx-n4{margin-left:-32px!important}.m-n5{margin:-40px!important}.mt-n5,.my-n5{margin-top:-40px!important}.mr-n5,.mx-n5{margin-right:-40px!important}.mb-n5,.my-n5{margin-bottom:-40px!important}.ml-n5,.mx-n5{margin-left:-40px!important}.m-n6{margin:-48px!important}.mt-n6,.my-n6{margin-top:-48px!important}.mr-n6,.mx-n6{margin-right:-48px!important}.mb-n6,.my-n6{margin-bottom:-48px!important}.ml-n6,.mx-n6{margin-left:-48px!important}.m-n7{margin:-56px!important}.mt-n7,.my-n7{margin-top:-56px!important}.mr-n7,.mx-n7{margin-right:-56px!important}.mb-n7,.my-n7{margin-bottom:-56px!important}.ml-n7,.mx-n7{margin-left:-56px!important}.m-n8{margin:-64px!important}.mt-n8,.my-n8{margin-top:-64px!important}.mr-n8,.mx-n8{margin-right:-64px!important}.mb-n8,.my-n8{margin-bottom:-64px!important}.ml-n8,.mx-n8{margin-left:-64px!important}.m-n9{margin:-72px!important}.mt-n9,.my-n9{margin-top:-72px!important}.mr-n9,.mx-n9{margin-right:-72px!important}.mb-n9,.my-n9{margin-bottom:-72px!important}.ml-n9,.mx-n9{margin-left:-72px!important}.m-n10{margin:-80px!important}.mt-n10,.my-n10{margin-top:-80px!important}.mr-n10,.mx-n10{margin-right:-80px!important}.mb-n10,.my-n10{margin-bottom:-80px!important}.ml-n10,.mx-n10{margin-left:-80px!important}.m-n12{margin:-96px!important}.mt-n12,.my-n12{margin-top:-96px!important}.mr-n12,.mx-n12{margin-right:-96px!important}.mb-n12,.my-n12{margin-bottom:-96px!important}.ml-n12,.mx-n12{margin-left:-96px!important}.m-n15{margin:-120px!important}.mt-n15,.my-n15{margin-top:-120px!important}.mr-n15,.mx-n15{margin-right:-120px!important}.mb-n15,.my-n15{margin-bottom:-120px!important}.ml-n15,.mx-n15{margin-left:-120px!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media(min-width:400px){.m-xs-0{margin:0!important}.mt-xs-0,.my-xs-0{margin-top:0!important}.mr-xs-0,.mx-xs-0{margin-right:0!important}.mb-xs-0,.my-xs-0{margin-bottom:0!important}.ml-xs-0,.mx-xs-0{margin-left:0!important}.m-xs-1{margin:8px!important}.mt-xs-1,.my-xs-1{margin-top:8px!important}.mr-xs-1,.mx-xs-1{margin-right:8px!important}.mb-xs-1,.my-xs-1{margin-bottom:8px!important}.ml-xs-1,.mx-xs-1{margin-left:8px!important}.m-xs-2{margin:16px!important}.mt-xs-2,.my-xs-2{margin-top:16px!important}.mr-xs-2,.mx-xs-2{margin-right:16px!important}.mb-xs-2,.my-xs-2{margin-bottom:16px!important}.ml-xs-2,.mx-xs-2{margin-left:16px!important}.m-xs-3{margin:24px!important}.mt-xs-3,.my-xs-3{margin-top:24px!important}.mr-xs-3,.mx-xs-3{margin-right:24px!important}.mb-xs-3,.my-xs-3{margin-bottom:24px!important}.ml-xs-3,.mx-xs-3{margin-left:24px!important}.m-xs-4{margin:32px!important}.mt-xs-4,.my-xs-4{margin-top:32px!important}.mr-xs-4,.mx-xs-4{margin-right:32px!important}.mb-xs-4,.my-xs-4{margin-bottom:32px!important}.ml-xs-4,.mx-xs-4{margin-left:32px!important}.m-xs-5{margin:40px!important}.mt-xs-5,.my-xs-5{margin-top:40px!important}.mr-xs-5,.mx-xs-5{margin-right:40px!important}.mb-xs-5,.my-xs-5{margin-bottom:40px!important}.ml-xs-5,.mx-xs-5{margin-left:40px!important}.m-xs-6{margin:48px!important}.mt-xs-6,.my-xs-6{margin-top:48px!important}.mr-xs-6,.mx-xs-6{margin-right:48px!important}.mb-xs-6,.my-xs-6{margin-bottom:48px!important}.ml-xs-6,.mx-xs-6{margin-left:48px!important}.m-xs-7{margin:56px!important}.mt-xs-7,.my-xs-7{margin-top:56px!important}.mr-xs-7,.mx-xs-7{margin-right:56px!important}.mb-xs-7,.my-xs-7{margin-bottom:56px!important}.ml-xs-7,.mx-xs-7{margin-left:56px!important}.m-xs-8{margin:64px!important}.mt-xs-8,.my-xs-8{margin-top:64px!important}.mr-xs-8,.mx-xs-8{margin-right:64px!important}.mb-xs-8,.my-xs-8{margin-bottom:64px!important}.ml-xs-8,.mx-xs-8{margin-left:64px!important}.m-xs-9{margin:72px!important}.mt-xs-9,.my-xs-9{margin-top:72px!important}.mr-xs-9,.mx-xs-9{margin-right:72px!important}.mb-xs-9,.my-xs-9{margin-bottom:72px!important}.ml-xs-9,.mx-xs-9{margin-left:72px!important}.m-xs-10{margin:80px!important}.mt-xs-10,.my-xs-10{margin-top:80px!important}.mr-xs-10,.mx-xs-10{margin-right:80px!important}.mb-xs-10,.my-xs-10{margin-bottom:80px!important}.ml-xs-10,.mx-xs-10{margin-left:80px!important}.m-xs-12{margin:96px!important}.mt-xs-12,.my-xs-12{margin-top:96px!important}.mr-xs-12,.mx-xs-12{margin-right:96px!important}.mb-xs-12,.my-xs-12{margin-bottom:96px!important}.ml-xs-12,.mx-xs-12{margin-left:96px!important}.m-xs-15{margin:120px!important}.mt-xs-15,.my-xs-15{margin-top:120px!important}.mr-xs-15,.mx-xs-15{margin-right:120px!important}.mb-xs-15,.my-xs-15{margin-bottom:120px!important}.ml-xs-15,.mx-xs-15{margin-left:120px!important}.p-xs-0{padding:0!important}.pt-xs-0,.py-xs-0{padding-top:0!important}.pr-xs-0,.px-xs-0{padding-right:0!important}.pb-xs-0,.py-xs-0{padding-bottom:0!important}.pl-xs-0,.px-xs-0{padding-left:0!important}.p-xs-1{padding:8px!important}.pt-xs-1,.py-xs-1{padding-top:8px!important}.pr-xs-1,.px-xs-1{padding-right:8px!important}.pb-xs-1,.py-xs-1{padding-bottom:8px!important}.pl-xs-1,.px-xs-1{padding-left:8px!important}.p-xs-2{padding:16px!important}.pt-xs-2,.py-xs-2{padding-top:16px!important}.pr-xs-2,.px-xs-2{padding-right:16px!important}.pb-xs-2,.py-xs-2{padding-bottom:16px!important}.pl-xs-2,.px-xs-2{padding-left:16px!important}.p-xs-3{padding:24px!important}.pt-xs-3,.py-xs-3{padding-top:24px!important}.pr-xs-3,.px-xs-3{padding-right:24px!important}.pb-xs-3,.py-xs-3{padding-bottom:24px!important}.pl-xs-3,.px-xs-3{padding-left:24px!important}.p-xs-4{padding:32px!important}.pt-xs-4,.py-xs-4{padding-top:32px!important}.pr-xs-4,.px-xs-4{padding-right:32px!important}.pb-xs-4,.py-xs-4{padding-bottom:32px!important}.pl-xs-4,.px-xs-4{padding-left:32px!important}.p-xs-5{padding:40px!important}.pt-xs-5,.py-xs-5{padding-top:40px!important}.pr-xs-5,.px-xs-5{padding-right:40px!important}.pb-xs-5,.py-xs-5{padding-bottom:40px!important}.pl-xs-5,.px-xs-5{padding-left:40px!important}.p-xs-6{padding:48px!important}.pt-xs-6,.py-xs-6{padding-top:48px!important}.pr-xs-6,.px-xs-6{padding-right:48px!important}.pb-xs-6,.py-xs-6{padding-bottom:48px!important}.pl-xs-6,.px-xs-6{padding-left:48px!important}.p-xs-7{padding:56px!important}.pt-xs-7,.py-xs-7{padding-top:56px!important}.pr-xs-7,.px-xs-7{padding-right:56px!important}.pb-xs-7,.py-xs-7{padding-bottom:56px!important}.pl-xs-7,.px-xs-7{padding-left:56px!important}.p-xs-8{padding:64px!important}.pt-xs-8,.py-xs-8{padding-top:64px!important}.pr-xs-8,.px-xs-8{padding-right:64px!important}.pb-xs-8,.py-xs-8{padding-bottom:64px!important}.pl-xs-8,.px-xs-8{padding-left:64px!important}.p-xs-9{padding:72px!important}.pt-xs-9,.py-xs-9{padding-top:72px!important}.pr-xs-9,.px-xs-9{padding-right:72px!important}.pb-xs-9,.py-xs-9{padding-bottom:72px!important}.pl-xs-9,.px-xs-9{padding-left:72px!important}.p-xs-10{padding:80px!important}.pt-xs-10,.py-xs-10{padding-top:80px!important}.pr-xs-10,.px-xs-10{padding-right:80px!important}.pb-xs-10,.py-xs-10{padding-bottom:80px!important}.pl-xs-10,.px-xs-10{padding-left:80px!important}.p-xs-12{padding:96px!important}.pt-xs-12,.py-xs-12{padding-top:96px!important}.pr-xs-12,.px-xs-12{padding-right:96px!important}.pb-xs-12,.py-xs-12{padding-bottom:96px!important}.pl-xs-12,.px-xs-12{padding-left:96px!important}.p-xs-15{padding:120px!important}.pt-xs-15,.py-xs-15{padding-top:120px!important}.pr-xs-15,.px-xs-15{padding-right:120px!important}.pb-xs-15,.py-xs-15{padding-bottom:120px!important}.pl-xs-15,.px-xs-15{padding-left:120px!important}.m-xs-n1{margin:-8px!important}.mt-xs-n1,.my-xs-n1{margin-top:-8px!important}.mr-xs-n1,.mx-xs-n1{margin-right:-8px!important}.mb-xs-n1,.my-xs-n1{margin-bottom:-8px!important}.ml-xs-n1,.mx-xs-n1{margin-left:-8px!important}.m-xs-n2{margin:-16px!important}.mt-xs-n2,.my-xs-n2{margin-top:-16px!important}.mr-xs-n2,.mx-xs-n2{margin-right:-16px!important}.mb-xs-n2,.my-xs-n2{margin-bottom:-16px!important}.ml-xs-n2,.mx-xs-n2{margin-left:-16px!important}.m-xs-n3{margin:-24px!important}.mt-xs-n3,.my-xs-n3{margin-top:-24px!important}.mr-xs-n3,.mx-xs-n3{margin-right:-24px!important}.mb-xs-n3,.my-xs-n3{margin-bottom:-24px!important}.ml-xs-n3,.mx-xs-n3{margin-left:-24px!important}.m-xs-n4{margin:-32px!important}.mt-xs-n4,.my-xs-n4{margin-top:-32px!important}.mr-xs-n4,.mx-xs-n4{margin-right:-32px!important}.mb-xs-n4,.my-xs-n4{margin-bottom:-32px!important}.ml-xs-n4,.mx-xs-n4{margin-left:-32px!important}.m-xs-n5{margin:-40px!important}.mt-xs-n5,.my-xs-n5{margin-top:-40px!important}.mr-xs-n5,.mx-xs-n5{margin-right:-40px!important}.mb-xs-n5,.my-xs-n5{margin-bottom:-40px!important}.ml-xs-n5,.mx-xs-n5{margin-left:-40px!important}.m-xs-n6{margin:-48px!important}.mt-xs-n6,.my-xs-n6{margin-top:-48px!important}.mr-xs-n6,.mx-xs-n6{margin-right:-48px!important}.mb-xs-n6,.my-xs-n6{margin-bottom:-48px!important}.ml-xs-n6,.mx-xs-n6{margin-left:-48px!important}.m-xs-n7{margin:-56px!important}.mt-xs-n7,.my-xs-n7{margin-top:-56px!important}.mr-xs-n7,.mx-xs-n7{margin-right:-56px!important}.mb-xs-n7,.my-xs-n7{margin-bottom:-56px!important}.ml-xs-n7,.mx-xs-n7{margin-left:-56px!important}.m-xs-n8{margin:-64px!important}.mt-xs-n8,.my-xs-n8{margin-top:-64px!important}.mr-xs-n8,.mx-xs-n8{margin-right:-64px!important}.mb-xs-n8,.my-xs-n8{margin-bottom:-64px!important}.ml-xs-n8,.mx-xs-n8{margin-left:-64px!important}.m-xs-n9{margin:-72px!important}.mt-xs-n9,.my-xs-n9{margin-top:-72px!important}.mr-xs-n9,.mx-xs-n9{margin-right:-72px!important}.mb-xs-n9,.my-xs-n9{margin-bottom:-72px!important}.ml-xs-n9,.mx-xs-n9{margin-left:-72px!important}.m-xs-n10{margin:-80px!important}.mt-xs-n10,.my-xs-n10{margin-top:-80px!important}.mr-xs-n10,.mx-xs-n10{margin-right:-80px!important}.mb-xs-n10,.my-xs-n10{margin-bottom:-80px!important}.ml-xs-n10,.mx-xs-n10{margin-left:-80px!important}.m-xs-n12{margin:-96px!important}.mt-xs-n12,.my-xs-n12{margin-top:-96px!important}.mr-xs-n12,.mx-xs-n12{margin-right:-96px!important}.mb-xs-n12,.my-xs-n12{margin-bottom:-96px!important}.ml-xs-n12,.mx-xs-n12{margin-left:-96px!important}.m-xs-n15{margin:-120px!important}.mt-xs-n15,.my-xs-n15{margin-top:-120px!important}.mr-xs-n15,.mx-xs-n15{margin-right:-120px!important}.mb-xs-n15,.my-xs-n15{margin-bottom:-120px!important}.ml-xs-n15,.mx-xs-n15{margin-left:-120px!important}.m-xs-auto{margin:auto!important}.mt-xs-auto,.my-xs-auto{margin-top:auto!important}.mr-xs-auto,.mx-xs-auto{margin-right:auto!important}.mb-xs-auto,.my-xs-auto{margin-bottom:auto!important}.ml-xs-auto,.mx-xs-auto{margin-left:auto!important}}@media(min-width:616px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:8px!important}.mt-sm-1,.my-sm-1{margin-top:8px!important}.mr-sm-1,.mx-sm-1{margin-right:8px!important}.mb-sm-1,.my-sm-1{margin-bottom:8px!important}.ml-sm-1,.mx-sm-1{margin-left:8px!important}.m-sm-2{margin:16px!important}.mt-sm-2,.my-sm-2{margin-top:16px!important}.mr-sm-2,.mx-sm-2{margin-right:16px!important}.mb-sm-2,.my-sm-2{margin-bottom:16px!important}.ml-sm-2,.mx-sm-2{margin-left:16px!important}.m-sm-3{margin:24px!important}.mt-sm-3,.my-sm-3{margin-top:24px!important}.mr-sm-3,.mx-sm-3{margin-right:24px!important}.mb-sm-3,.my-sm-3{margin-bottom:24px!important}.ml-sm-3,.mx-sm-3{margin-left:24px!important}.m-sm-4{margin:32px!important}.mt-sm-4,.my-sm-4{margin-top:32px!important}.mr-sm-4,.mx-sm-4{margin-right:32px!important}.mb-sm-4,.my-sm-4{margin-bottom:32px!important}.ml-sm-4,.mx-sm-4{margin-left:32px!important}.m-sm-5{margin:40px!important}.mt-sm-5,.my-sm-5{margin-top:40px!important}.mr-sm-5,.mx-sm-5{margin-right:40px!important}.mb-sm-5,.my-sm-5{margin-bottom:40px!important}.ml-sm-5,.mx-sm-5{margin-left:40px!important}.m-sm-6{margin:48px!important}.mt-sm-6,.my-sm-6{margin-top:48px!important}.mr-sm-6,.mx-sm-6{margin-right:48px!important}.mb-sm-6,.my-sm-6{margin-bottom:48px!important}.ml-sm-6,.mx-sm-6{margin-left:48px!important}.m-sm-7{margin:56px!important}.mt-sm-7,.my-sm-7{margin-top:56px!important}.mr-sm-7,.mx-sm-7{margin-right:56px!important}.mb-sm-7,.my-sm-7{margin-bottom:56px!important}.ml-sm-7,.mx-sm-7{margin-left:56px!important}.m-sm-8{margin:64px!important}.mt-sm-8,.my-sm-8{margin-top:64px!important}.mr-sm-8,.mx-sm-8{margin-right:64px!important}.mb-sm-8,.my-sm-8{margin-bottom:64px!important}.ml-sm-8,.mx-sm-8{margin-left:64px!important}.m-sm-9{margin:72px!important}.mt-sm-9,.my-sm-9{margin-top:72px!important}.mr-sm-9,.mx-sm-9{margin-right:72px!important}.mb-sm-9,.my-sm-9{margin-bottom:72px!important}.ml-sm-9,.mx-sm-9{margin-left:72px!important}.m-sm-10{margin:80px!important}.mt-sm-10,.my-sm-10{margin-top:80px!important}.mr-sm-10,.mx-sm-10{margin-right:80px!important}.mb-sm-10,.my-sm-10{margin-bottom:80px!important}.ml-sm-10,.mx-sm-10{margin-left:80px!important}.m-sm-12{margin:96px!important}.mt-sm-12,.my-sm-12{margin-top:96px!important}.mr-sm-12,.mx-sm-12{margin-right:96px!important}.mb-sm-12,.my-sm-12{margin-bottom:96px!important}.ml-sm-12,.mx-sm-12{margin-left:96px!important}.m-sm-15{margin:120px!important}.mt-sm-15,.my-sm-15{margin-top:120px!important}.mr-sm-15,.mx-sm-15{margin-right:120px!important}.mb-sm-15,.my-sm-15{margin-bottom:120px!important}.ml-sm-15,.mx-sm-15{margin-left:120px!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:8px!important}.pt-sm-1,.py-sm-1{padding-top:8px!important}.pr-sm-1,.px-sm-1{padding-right:8px!important}.pb-sm-1,.py-sm-1{padding-bottom:8px!important}.pl-sm-1,.px-sm-1{padding-left:8px!important}.p-sm-2{padding:16px!important}.pt-sm-2,.py-sm-2{padding-top:16px!important}.pr-sm-2,.px-sm-2{padding-right:16px!important}.pb-sm-2,.py-sm-2{padding-bottom:16px!important}.pl-sm-2,.px-sm-2{padding-left:16px!important}.p-sm-3{padding:24px!important}.pt-sm-3,.py-sm-3{padding-top:24px!important}.pr-sm-3,.px-sm-3{padding-right:24px!important}.pb-sm-3,.py-sm-3{padding-bottom:24px!important}.pl-sm-3,.px-sm-3{padding-left:24px!important}.p-sm-4{padding:32px!important}.pt-sm-4,.py-sm-4{padding-top:32px!important}.pr-sm-4,.px-sm-4{padding-right:32px!important}.pb-sm-4,.py-sm-4{padding-bottom:32px!important}.pl-sm-4,.px-sm-4{padding-left:32px!important}.p-sm-5{padding:40px!important}.pt-sm-5,.py-sm-5{padding-top:40px!important}.pr-sm-5,.px-sm-5{padding-right:40px!important}.pb-sm-5,.py-sm-5{padding-bottom:40px!important}.pl-sm-5,.px-sm-5{padding-left:40px!important}.p-sm-6{padding:48px!important}.pt-sm-6,.py-sm-6{padding-top:48px!important}.pr-sm-6,.px-sm-6{padding-right:48px!important}.pb-sm-6,.py-sm-6{padding-bottom:48px!important}.pl-sm-6,.px-sm-6{padding-left:48px!important}.p-sm-7{padding:56px!important}.pt-sm-7,.py-sm-7{padding-top:56px!important}.pr-sm-7,.px-sm-7{padding-right:56px!important}.pb-sm-7,.py-sm-7{padding-bottom:56px!important}.pl-sm-7,.px-sm-7{padding-left:56px!important}.p-sm-8{padding:64px!important}.pt-sm-8,.py-sm-8{padding-top:64px!important}.pr-sm-8,.px-sm-8{padding-right:64px!important}.pb-sm-8,.py-sm-8{padding-bottom:64px!important}.pl-sm-8,.px-sm-8{padding-left:64px!important}.p-sm-9{padding:72px!important}.pt-sm-9,.py-sm-9{padding-top:72px!important}.pr-sm-9,.px-sm-9{padding-right:72px!important}.pb-sm-9,.py-sm-9{padding-bottom:72px!important}.pl-sm-9,.px-sm-9{padding-left:72px!important}.p-sm-10{padding:80px!important}.pt-sm-10,.py-sm-10{padding-top:80px!important}.pr-sm-10,.px-sm-10{padding-right:80px!important}.pb-sm-10,.py-sm-10{padding-bottom:80px!important}.pl-sm-10,.px-sm-10{padding-left:80px!important}.p-sm-12{padding:96px!important}.pt-sm-12,.py-sm-12{padding-top:96px!important}.pr-sm-12,.px-sm-12{padding-right:96px!important}.pb-sm-12,.py-sm-12{padding-bottom:96px!important}.pl-sm-12,.px-sm-12{padding-left:96px!important}.p-sm-15{padding:120px!important}.pt-sm-15,.py-sm-15{padding-top:120px!important}.pr-sm-15,.px-sm-15{padding-right:120px!important}.pb-sm-15,.py-sm-15{padding-bottom:120px!important}.pl-sm-15,.px-sm-15{padding-left:120px!important}.m-sm-n1{margin:-8px!important}.mt-sm-n1,.my-sm-n1{margin-top:-8px!important}.mr-sm-n1,.mx-sm-n1{margin-right:-8px!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-8px!important}.ml-sm-n1,.mx-sm-n1{margin-left:-8px!important}.m-sm-n2{margin:-16px!important}.mt-sm-n2,.my-sm-n2{margin-top:-16px!important}.mr-sm-n2,.mx-sm-n2{margin-right:-16px!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-16px!important}.ml-sm-n2,.mx-sm-n2{margin-left:-16px!important}.m-sm-n3{margin:-24px!important}.mt-sm-n3,.my-sm-n3{margin-top:-24px!important}.mr-sm-n3,.mx-sm-n3{margin-right:-24px!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-24px!important}.ml-sm-n3,.mx-sm-n3{margin-left:-24px!important}.m-sm-n4{margin:-32px!important}.mt-sm-n4,.my-sm-n4{margin-top:-32px!important}.mr-sm-n4,.mx-sm-n4{margin-right:-32px!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-32px!important}.ml-sm-n4,.mx-sm-n4{margin-left:-32px!important}.m-sm-n5{margin:-40px!important}.mt-sm-n5,.my-sm-n5{margin-top:-40px!important}.mr-sm-n5,.mx-sm-n5{margin-right:-40px!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-40px!important}.ml-sm-n5,.mx-sm-n5{margin-left:-40px!important}.m-sm-n6{margin:-48px!important}.mt-sm-n6,.my-sm-n6{margin-top:-48px!important}.mr-sm-n6,.mx-sm-n6{margin-right:-48px!important}.mb-sm-n6,.my-sm-n6{margin-bottom:-48px!important}.ml-sm-n6,.mx-sm-n6{margin-left:-48px!important}.m-sm-n7{margin:-56px!important}.mt-sm-n7,.my-sm-n7{margin-top:-56px!important}.mr-sm-n7,.mx-sm-n7{margin-right:-56px!important}.mb-sm-n7,.my-sm-n7{margin-bottom:-56px!important}.ml-sm-n7,.mx-sm-n7{margin-left:-56px!important}.m-sm-n8{margin:-64px!important}.mt-sm-n8,.my-sm-n8{margin-top:-64px!important}.mr-sm-n8,.mx-sm-n8{margin-right:-64px!important}.mb-sm-n8,.my-sm-n8{margin-bottom:-64px!important}.ml-sm-n8,.mx-sm-n8{margin-left:-64px!important}.m-sm-n9{margin:-72px!important}.mt-sm-n9,.my-sm-n9{margin-top:-72px!important}.mr-sm-n9,.mx-sm-n9{margin-right:-72px!important}.mb-sm-n9,.my-sm-n9{margin-bottom:-72px!important}.ml-sm-n9,.mx-sm-n9{margin-left:-72px!important}.m-sm-n10{margin:-80px!important}.mt-sm-n10,.my-sm-n10{margin-top:-80px!important}.mr-sm-n10,.mx-sm-n10{margin-right:-80px!important}.mb-sm-n10,.my-sm-n10{margin-bottom:-80px!important}.ml-sm-n10,.mx-sm-n10{margin-left:-80px!important}.m-sm-n12{margin:-96px!important}.mt-sm-n12,.my-sm-n12{margin-top:-96px!important}.mr-sm-n12,.mx-sm-n12{margin-right:-96px!important}.mb-sm-n12,.my-sm-n12{margin-bottom:-96px!important}.ml-sm-n12,.mx-sm-n12{margin-left:-96px!important}.m-sm-n15{margin:-120px!important}.mt-sm-n15,.my-sm-n15{margin-top:-120px!important}.mr-sm-n15,.mx-sm-n15{margin-right:-120px!important}.mb-sm-n15,.my-sm-n15{margin-bottom:-120px!important}.ml-sm-n15,.mx-sm-n15{margin-left:-120px!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media(min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:8px!important}.mt-md-1,.my-md-1{margin-top:8px!important}.mr-md-1,.mx-md-1{margin-right:8px!important}.mb-md-1,.my-md-1{margin-bottom:8px!important}.ml-md-1,.mx-md-1{margin-left:8px!important}.m-md-2{margin:16px!important}.mt-md-2,.my-md-2{margin-top:16px!important}.mr-md-2,.mx-md-2{margin-right:16px!important}.mb-md-2,.my-md-2{margin-bottom:16px!important}.ml-md-2,.mx-md-2{margin-left:16px!important}.m-md-3{margin:24px!important}.mt-md-3,.my-md-3{margin-top:24px!important}.mr-md-3,.mx-md-3{margin-right:24px!important}.mb-md-3,.my-md-3{margin-bottom:24px!important}.ml-md-3,.mx-md-3{margin-left:24px!important}.m-md-4{margin:32px!important}.mt-md-4,.my-md-4{margin-top:32px!important}.mr-md-4,.mx-md-4{margin-right:32px!important}.mb-md-4,.my-md-4{margin-bottom:32px!important}.ml-md-4,.mx-md-4{margin-left:32px!important}.m-md-5{margin:40px!important}.mt-md-5,.my-md-5{margin-top:40px!important}.mr-md-5,.mx-md-5{margin-right:40px!important}.mb-md-5,.my-md-5{margin-bottom:40px!important}.ml-md-5,.mx-md-5{margin-left:40px!important}.m-md-6{margin:48px!important}.mt-md-6,.my-md-6{margin-top:48px!important}.mr-md-6,.mx-md-6{margin-right:48px!important}.mb-md-6,.my-md-6{margin-bottom:48px!important}.ml-md-6,.mx-md-6{margin-left:48px!important}.m-md-7{margin:56px!important}.mt-md-7,.my-md-7{margin-top:56px!important}.mr-md-7,.mx-md-7{margin-right:56px!important}.mb-md-7,.my-md-7{margin-bottom:56px!important}.ml-md-7,.mx-md-7{margin-left:56px!important}.m-md-8{margin:64px!important}.mt-md-8,.my-md-8{margin-top:64px!important}.mr-md-8,.mx-md-8{margin-right:64px!important}.mb-md-8,.my-md-8{margin-bottom:64px!important}.ml-md-8,.mx-md-8{margin-left:64px!important}.m-md-9{margin:72px!important}.mt-md-9,.my-md-9{margin-top:72px!important}.mr-md-9,.mx-md-9{margin-right:72px!important}.mb-md-9,.my-md-9{margin-bottom:72px!important}.ml-md-9,.mx-md-9{margin-left:72px!important}.m-md-10{margin:80px!important}.mt-md-10,.my-md-10{margin-top:80px!important}.mr-md-10,.mx-md-10{margin-right:80px!important}.mb-md-10,.my-md-10{margin-bottom:80px!important}.ml-md-10,.mx-md-10{margin-left:80px!important}.m-md-12{margin:96px!important}.mt-md-12,.my-md-12{margin-top:96px!important}.mr-md-12,.mx-md-12{margin-right:96px!important}.mb-md-12,.my-md-12{margin-bottom:96px!important}.ml-md-12,.mx-md-12{margin-left:96px!important}.m-md-15{margin:120px!important}.mt-md-15,.my-md-15{margin-top:120px!important}.mr-md-15,.mx-md-15{margin-right:120px!important}.mb-md-15,.my-md-15{margin-bottom:120px!important}.ml-md-15,.mx-md-15{margin-left:120px!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:8px!important}.pt-md-1,.py-md-1{padding-top:8px!important}.pr-md-1,.px-md-1{padding-right:8px!important}.pb-md-1,.py-md-1{padding-bottom:8px!important}.pl-md-1,.px-md-1{padding-left:8px!important}.p-md-2{padding:16px!important}.pt-md-2,.py-md-2{padding-top:16px!important}.pr-md-2,.px-md-2{padding-right:16px!important}.pb-md-2,.py-md-2{padding-bottom:16px!important}.pl-md-2,.px-md-2{padding-left:16px!important}.p-md-3{padding:24px!important}.pt-md-3,.py-md-3{padding-top:24px!important}.pr-md-3,.px-md-3{padding-right:24px!important}.pb-md-3,.py-md-3{padding-bottom:24px!important}.pl-md-3,.px-md-3{padding-left:24px!important}.p-md-4{padding:32px!important}.pt-md-4,.py-md-4{padding-top:32px!important}.pr-md-4,.px-md-4{padding-right:32px!important}.pb-md-4,.py-md-4{padding-bottom:32px!important}.pl-md-4,.px-md-4{padding-left:32px!important}.p-md-5{padding:40px!important}.pt-md-5,.py-md-5{padding-top:40px!important}.pr-md-5,.px-md-5{padding-right:40px!important}.pb-md-5,.py-md-5{padding-bottom:40px!important}.pl-md-5,.px-md-5{padding-left:40px!important}.p-md-6{padding:48px!important}.pt-md-6,.py-md-6{padding-top:48px!important}.pr-md-6,.px-md-6{padding-right:48px!important}.pb-md-6,.py-md-6{padding-bottom:48px!important}.pl-md-6,.px-md-6{padding-left:48px!important}.p-md-7{padding:56px!important}.pt-md-7,.py-md-7{padding-top:56px!important}.pr-md-7,.px-md-7{padding-right:56px!important}.pb-md-7,.py-md-7{padding-bottom:56px!important}.pl-md-7,.px-md-7{padding-left:56px!important}.p-md-8{padding:64px!important}.pt-md-8,.py-md-8{padding-top:64px!important}.pr-md-8,.px-md-8{padding-right:64px!important}.pb-md-8,.py-md-8{padding-bottom:64px!important}.pl-md-8,.px-md-8{padding-left:64px!important}.p-md-9{padding:72px!important}.pt-md-9,.py-md-9{padding-top:72px!important}.pr-md-9,.px-md-9{padding-right:72px!important}.pb-md-9,.py-md-9{padding-bottom:72px!important}.pl-md-9,.px-md-9{padding-left:72px!important}.p-md-10{padding:80px!important}.pt-md-10,.py-md-10{padding-top:80px!important}.pr-md-10,.px-md-10{padding-right:80px!important}.pb-md-10,.py-md-10{padding-bottom:80px!important}.pl-md-10,.px-md-10{padding-left:80px!important}.p-md-12{padding:96px!important}.pt-md-12,.py-md-12{padding-top:96px!important}.pr-md-12,.px-md-12{padding-right:96px!important}.pb-md-12,.py-md-12{padding-bottom:96px!important}.pl-md-12,.px-md-12{padding-left:96px!important}.p-md-15{padding:120px!important}.pt-md-15,.py-md-15{padding-top:120px!important}.pr-md-15,.px-md-15{padding-right:120px!important}.pb-md-15,.py-md-15{padding-bottom:120px!important}.pl-md-15,.px-md-15{padding-left:120px!important}.m-md-n1{margin:-8px!important}.mt-md-n1,.my-md-n1{margin-top:-8px!important}.mr-md-n1,.mx-md-n1{margin-right:-8px!important}.mb-md-n1,.my-md-n1{margin-bottom:-8px!important}.ml-md-n1,.mx-md-n1{margin-left:-8px!important}.m-md-n2{margin:-16px!important}.mt-md-n2,.my-md-n2{margin-top:-16px!important}.mr-md-n2,.mx-md-n2{margin-right:-16px!important}.mb-md-n2,.my-md-n2{margin-bottom:-16px!important}.ml-md-n2,.mx-md-n2{margin-left:-16px!important}.m-md-n3{margin:-24px!important}.mt-md-n3,.my-md-n3{margin-top:-24px!important}.mr-md-n3,.mx-md-n3{margin-right:-24px!important}.mb-md-n3,.my-md-n3{margin-bottom:-24px!important}.ml-md-n3,.mx-md-n3{margin-left:-24px!important}.m-md-n4{margin:-32px!important}.mt-md-n4,.my-md-n4{margin-top:-32px!important}.mr-md-n4,.mx-md-n4{margin-right:-32px!important}.mb-md-n4,.my-md-n4{margin-bottom:-32px!important}.ml-md-n4,.mx-md-n4{margin-left:-32px!important}.m-md-n5{margin:-40px!important}.mt-md-n5,.my-md-n5{margin-top:-40px!important}.mr-md-n5,.mx-md-n5{margin-right:-40px!important}.mb-md-n5,.my-md-n5{margin-bottom:-40px!important}.ml-md-n5,.mx-md-n5{margin-left:-40px!important}.m-md-n6{margin:-48px!important}.mt-md-n6,.my-md-n6{margin-top:-48px!important}.mr-md-n6,.mx-md-n6{margin-right:-48px!important}.mb-md-n6,.my-md-n6{margin-bottom:-48px!important}.ml-md-n6,.mx-md-n6{margin-left:-48px!important}.m-md-n7{margin:-56px!important}.mt-md-n7,.my-md-n7{margin-top:-56px!important}.mr-md-n7,.mx-md-n7{margin-right:-56px!important}.mb-md-n7,.my-md-n7{margin-bottom:-56px!important}.ml-md-n7,.mx-md-n7{margin-left:-56px!important}.m-md-n8{margin:-64px!important}.mt-md-n8,.my-md-n8{margin-top:-64px!important}.mr-md-n8,.mx-md-n8{margin-right:-64px!important}.mb-md-n8,.my-md-n8{margin-bottom:-64px!important}.ml-md-n8,.mx-md-n8{margin-left:-64px!important}.m-md-n9{margin:-72px!important}.mt-md-n9,.my-md-n9{margin-top:-72px!important}.mr-md-n9,.mx-md-n9{margin-right:-72px!important}.mb-md-n9,.my-md-n9{margin-bottom:-72px!important}.ml-md-n9,.mx-md-n9{margin-left:-72px!important}.m-md-n10{margin:-80px!important}.mt-md-n10,.my-md-n10{margin-top:-80px!important}.mr-md-n10,.mx-md-n10{margin-right:-80px!important}.mb-md-n10,.my-md-n10{margin-bottom:-80px!important}.ml-md-n10,.mx-md-n10{margin-left:-80px!important}.m-md-n12{margin:-96px!important}.mt-md-n12,.my-md-n12{margin-top:-96px!important}.mr-md-n12,.mx-md-n12{margin-right:-96px!important}.mb-md-n12,.my-md-n12{margin-bottom:-96px!important}.ml-md-n12,.mx-md-n12{margin-left:-96px!important}.m-md-n15{margin:-120px!important}.mt-md-n15,.my-md-n15{margin-top:-120px!important}.mr-md-n15,.mx-md-n15{margin-right:-120px!important}.mb-md-n15,.my-md-n15{margin-bottom:-120px!important}.ml-md-n15,.mx-md-n15{margin-left:-120px!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media(min-width:980px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:8px!important}.mt-lg-1,.my-lg-1{margin-top:8px!important}.mr-lg-1,.mx-lg-1{margin-right:8px!important}.mb-lg-1,.my-lg-1{margin-bottom:8px!important}.ml-lg-1,.mx-lg-1{margin-left:8px!important}.m-lg-2{margin:16px!important}.mt-lg-2,.my-lg-2{margin-top:16px!important}.mr-lg-2,.mx-lg-2{margin-right:16px!important}.mb-lg-2,.my-lg-2{margin-bottom:16px!important}.ml-lg-2,.mx-lg-2{margin-left:16px!important}.m-lg-3{margin:24px!important}.mt-lg-3,.my-lg-3{margin-top:24px!important}.mr-lg-3,.mx-lg-3{margin-right:24px!important}.mb-lg-3,.my-lg-3{margin-bottom:24px!important}.ml-lg-3,.mx-lg-3{margin-left:24px!important}.m-lg-4{margin:32px!important}.mt-lg-4,.my-lg-4{margin-top:32px!important}.mr-lg-4,.mx-lg-4{margin-right:32px!important}.mb-lg-4,.my-lg-4{margin-bottom:32px!important}.ml-lg-4,.mx-lg-4{margin-left:32px!important}.m-lg-5{margin:40px!important}.mt-lg-5,.my-lg-5{margin-top:40px!important}.mr-lg-5,.mx-lg-5{margin-right:40px!important}.mb-lg-5,.my-lg-5{margin-bottom:40px!important}.ml-lg-5,.mx-lg-5{margin-left:40px!important}.m-lg-6{margin:48px!important}.mt-lg-6,.my-lg-6{margin-top:48px!important}.mr-lg-6,.mx-lg-6{margin-right:48px!important}.mb-lg-6,.my-lg-6{margin-bottom:48px!important}.ml-lg-6,.mx-lg-6{margin-left:48px!important}.m-lg-7{margin:56px!important}.mt-lg-7,.my-lg-7{margin-top:56px!important}.mr-lg-7,.mx-lg-7{margin-right:56px!important}.mb-lg-7,.my-lg-7{margin-bottom:56px!important}.ml-lg-7,.mx-lg-7{margin-left:56px!important}.m-lg-8{margin:64px!important}.mt-lg-8,.my-lg-8{margin-top:64px!important}.mr-lg-8,.mx-lg-8{margin-right:64px!important}.mb-lg-8,.my-lg-8{margin-bottom:64px!important}.ml-lg-8,.mx-lg-8{margin-left:64px!important}.m-lg-9{margin:72px!important}.mt-lg-9,.my-lg-9{margin-top:72px!important}.mr-lg-9,.mx-lg-9{margin-right:72px!important}.mb-lg-9,.my-lg-9{margin-bottom:72px!important}.ml-lg-9,.mx-lg-9{margin-left:72px!important}.m-lg-10{margin:80px!important}.mt-lg-10,.my-lg-10{margin-top:80px!important}.mr-lg-10,.mx-lg-10{margin-right:80px!important}.mb-lg-10,.my-lg-10{margin-bottom:80px!important}.ml-lg-10,.mx-lg-10{margin-left:80px!important}.m-lg-12{margin:96px!important}.mt-lg-12,.my-lg-12{margin-top:96px!important}.mr-lg-12,.mx-lg-12{margin-right:96px!important}.mb-lg-12,.my-lg-12{margin-bottom:96px!important}.ml-lg-12,.mx-lg-12{margin-left:96px!important}.m-lg-15{margin:120px!important}.mt-lg-15,.my-lg-15{margin-top:120px!important}.mr-lg-15,.mx-lg-15{margin-right:120px!important}.mb-lg-15,.my-lg-15{margin-bottom:120px!important}.ml-lg-15,.mx-lg-15{margin-left:120px!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:8px!important}.pt-lg-1,.py-lg-1{padding-top:8px!important}.pr-lg-1,.px-lg-1{padding-right:8px!important}.pb-lg-1,.py-lg-1{padding-bottom:8px!important}.pl-lg-1,.px-lg-1{padding-left:8px!important}.p-lg-2{padding:16px!important}.pt-lg-2,.py-lg-2{padding-top:16px!important}.pr-lg-2,.px-lg-2{padding-right:16px!important}.pb-lg-2,.py-lg-2{padding-bottom:16px!important}.pl-lg-2,.px-lg-2{padding-left:16px!important}.p-lg-3{padding:24px!important}.pt-lg-3,.py-lg-3{padding-top:24px!important}.pr-lg-3,.px-lg-3{padding-right:24px!important}.pb-lg-3,.py-lg-3{padding-bottom:24px!important}.pl-lg-3,.px-lg-3{padding-left:24px!important}.p-lg-4{padding:32px!important}.pt-lg-4,.py-lg-4{padding-top:32px!important}.pr-lg-4,.px-lg-4{padding-right:32px!important}.pb-lg-4,.py-lg-4{padding-bottom:32px!important}.pl-lg-4,.px-lg-4{padding-left:32px!important}.p-lg-5{padding:40px!important}.pt-lg-5,.py-lg-5{padding-top:40px!important}.pr-lg-5,.px-lg-5{padding-right:40px!important}.pb-lg-5,.py-lg-5{padding-bottom:40px!important}.pl-lg-5,.px-lg-5{padding-left:40px!important}.p-lg-6{padding:48px!important}.pt-lg-6,.py-lg-6{padding-top:48px!important}.pr-lg-6,.px-lg-6{padding-right:48px!important}.pb-lg-6,.py-lg-6{padding-bottom:48px!important}.pl-lg-6,.px-lg-6{padding-left:48px!important}.p-lg-7{padding:56px!important}.pt-lg-7,.py-lg-7{padding-top:56px!important}.pr-lg-7,.px-lg-7{padding-right:56px!important}.pb-lg-7,.py-lg-7{padding-bottom:56px!important}.pl-lg-7,.px-lg-7{padding-left:56px!important}.p-lg-8{padding:64px!important}.pt-lg-8,.py-lg-8{padding-top:64px!important}.pr-lg-8,.px-lg-8{padding-right:64px!important}.pb-lg-8,.py-lg-8{padding-bottom:64px!important}.pl-lg-8,.px-lg-8{padding-left:64px!important}.p-lg-9{padding:72px!important}.pt-lg-9,.py-lg-9{padding-top:72px!important}.pr-lg-9,.px-lg-9{padding-right:72px!important}.pb-lg-9,.py-lg-9{padding-bottom:72px!important}.pl-lg-9,.px-lg-9{padding-left:72px!important}.p-lg-10{padding:80px!important}.pt-lg-10,.py-lg-10{padding-top:80px!important}.pr-lg-10,.px-lg-10{padding-right:80px!important}.pb-lg-10,.py-lg-10{padding-bottom:80px!important}.pl-lg-10,.px-lg-10{padding-left:80px!important}.p-lg-12{padding:96px!important}.pt-lg-12,.py-lg-12{padding-top:96px!important}.pr-lg-12,.px-lg-12{padding-right:96px!important}.pb-lg-12,.py-lg-12{padding-bottom:96px!important}.pl-lg-12,.px-lg-12{padding-left:96px!important}.p-lg-15{padding:120px!important}.pt-lg-15,.py-lg-15{padding-top:120px!important}.pr-lg-15,.px-lg-15{padding-right:120px!important}.pb-lg-15,.py-lg-15{padding-bottom:120px!important}.pl-lg-15,.px-lg-15{padding-left:120px!important}.m-lg-n1{margin:-8px!important}.mt-lg-n1,.my-lg-n1{margin-top:-8px!important}.mr-lg-n1,.mx-lg-n1{margin-right:-8px!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-8px!important}.ml-lg-n1,.mx-lg-n1{margin-left:-8px!important}.m-lg-n2{margin:-16px!important}.mt-lg-n2,.my-lg-n2{margin-top:-16px!important}.mr-lg-n2,.mx-lg-n2{margin-right:-16px!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-16px!important}.ml-lg-n2,.mx-lg-n2{margin-left:-16px!important}.m-lg-n3{margin:-24px!important}.mt-lg-n3,.my-lg-n3{margin-top:-24px!important}.mr-lg-n3,.mx-lg-n3{margin-right:-24px!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-24px!important}.ml-lg-n3,.mx-lg-n3{margin-left:-24px!important}.m-lg-n4{margin:-32px!important}.mt-lg-n4,.my-lg-n4{margin-top:-32px!important}.mr-lg-n4,.mx-lg-n4{margin-right:-32px!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-32px!important}.ml-lg-n4,.mx-lg-n4{margin-left:-32px!important}.m-lg-n5{margin:-40px!important}.mt-lg-n5,.my-lg-n5{margin-top:-40px!important}.mr-lg-n5,.mx-lg-n5{margin-right:-40px!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-40px!important}.ml-lg-n5,.mx-lg-n5{margin-left:-40px!important}.m-lg-n6{margin:-48px!important}.mt-lg-n6,.my-lg-n6{margin-top:-48px!important}.mr-lg-n6,.mx-lg-n6{margin-right:-48px!important}.mb-lg-n6,.my-lg-n6{margin-bottom:-48px!important}.ml-lg-n6,.mx-lg-n6{margin-left:-48px!important}.m-lg-n7{margin:-56px!important}.mt-lg-n7,.my-lg-n7{margin-top:-56px!important}.mr-lg-n7,.mx-lg-n7{margin-right:-56px!important}.mb-lg-n7,.my-lg-n7{margin-bottom:-56px!important}.ml-lg-n7,.mx-lg-n7{margin-left:-56px!important}.m-lg-n8{margin:-64px!important}.mt-lg-n8,.my-lg-n8{margin-top:-64px!important}.mr-lg-n8,.mx-lg-n8{margin-right:-64px!important}.mb-lg-n8,.my-lg-n8{margin-bottom:-64px!important}.ml-lg-n8,.mx-lg-n8{margin-left:-64px!important}.m-lg-n9{margin:-72px!important}.mt-lg-n9,.my-lg-n9{margin-top:-72px!important}.mr-lg-n9,.mx-lg-n9{margin-right:-72px!important}.mb-lg-n9,.my-lg-n9{margin-bottom:-72px!important}.ml-lg-n9,.mx-lg-n9{margin-left:-72px!important}.m-lg-n10{margin:-80px!important}.mt-lg-n10,.my-lg-n10{margin-top:-80px!important}.mr-lg-n10,.mx-lg-n10{margin-right:-80px!important}.mb-lg-n10,.my-lg-n10{margin-bottom:-80px!important}.ml-lg-n10,.mx-lg-n10{margin-left:-80px!important}.m-lg-n12{margin:-96px!important}.mt-lg-n12,.my-lg-n12{margin-top:-96px!important}.mr-lg-n12,.mx-lg-n12{margin-right:-96px!important}.mb-lg-n12,.my-lg-n12{margin-bottom:-96px!important}.ml-lg-n12,.mx-lg-n12{margin-left:-96px!important}.m-lg-n15{margin:-120px!important}.mt-lg-n15,.my-lg-n15{margin-top:-120px!important}.mr-lg-n15,.mx-lg-n15{margin-right:-120px!important}.mb-lg-n15,.my-lg-n15{margin-bottom:-120px!important}.ml-lg-n15,.mx-lg-n15{margin-left:-120px!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media(min-width:1240px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:8px!important}.mt-xl-1,.my-xl-1{margin-top:8px!important}.mr-xl-1,.mx-xl-1{margin-right:8px!important}.mb-xl-1,.my-xl-1{margin-bottom:8px!important}.ml-xl-1,.mx-xl-1{margin-left:8px!important}.m-xl-2{margin:16px!important}.mt-xl-2,.my-xl-2{margin-top:16px!important}.mr-xl-2,.mx-xl-2{margin-right:16px!important}.mb-xl-2,.my-xl-2{margin-bottom:16px!important}.ml-xl-2,.mx-xl-2{margin-left:16px!important}.m-xl-3{margin:24px!important}.mt-xl-3,.my-xl-3{margin-top:24px!important}.mr-xl-3,.mx-xl-3{margin-right:24px!important}.mb-xl-3,.my-xl-3{margin-bottom:24px!important}.ml-xl-3,.mx-xl-3{margin-left:24px!important}.m-xl-4{margin:32px!important}.mt-xl-4,.my-xl-4{margin-top:32px!important}.mr-xl-4,.mx-xl-4{margin-right:32px!important}.mb-xl-4,.my-xl-4{margin-bottom:32px!important}.ml-xl-4,.mx-xl-4{margin-left:32px!important}.m-xl-5{margin:40px!important}.mt-xl-5,.my-xl-5{margin-top:40px!important}.mr-xl-5,.mx-xl-5{margin-right:40px!important}.mb-xl-5,.my-xl-5{margin-bottom:40px!important}.ml-xl-5,.mx-xl-5{margin-left:40px!important}.m-xl-6{margin:48px!important}.mt-xl-6,.my-xl-6{margin-top:48px!important}.mr-xl-6,.mx-xl-6{margin-right:48px!important}.mb-xl-6,.my-xl-6{margin-bottom:48px!important}.ml-xl-6,.mx-xl-6{margin-left:48px!important}.m-xl-7{margin:56px!important}.mt-xl-7,.my-xl-7{margin-top:56px!important}.mr-xl-7,.mx-xl-7{margin-right:56px!important}.mb-xl-7,.my-xl-7{margin-bottom:56px!important}.ml-xl-7,.mx-xl-7{margin-left:56px!important}.m-xl-8{margin:64px!important}.mt-xl-8,.my-xl-8{margin-top:64px!important}.mr-xl-8,.mx-xl-8{margin-right:64px!important}.mb-xl-8,.my-xl-8{margin-bottom:64px!important}.ml-xl-8,.mx-xl-8{margin-left:64px!important}.m-xl-9{margin:72px!important}.mt-xl-9,.my-xl-9{margin-top:72px!important}.mr-xl-9,.mx-xl-9{margin-right:72px!important}.mb-xl-9,.my-xl-9{margin-bottom:72px!important}.ml-xl-9,.mx-xl-9{margin-left:72px!important}.m-xl-10{margin:80px!important}.mt-xl-10,.my-xl-10{margin-top:80px!important}.mr-xl-10,.mx-xl-10{margin-right:80px!important}.mb-xl-10,.my-xl-10{margin-bottom:80px!important}.ml-xl-10,.mx-xl-10{margin-left:80px!important}.m-xl-12{margin:96px!important}.mt-xl-12,.my-xl-12{margin-top:96px!important}.mr-xl-12,.mx-xl-12{margin-right:96px!important}.mb-xl-12,.my-xl-12{margin-bottom:96px!important}.ml-xl-12,.mx-xl-12{margin-left:96px!important}.m-xl-15{margin:120px!important}.mt-xl-15,.my-xl-15{margin-top:120px!important}.mr-xl-15,.mx-xl-15{margin-right:120px!important}.mb-xl-15,.my-xl-15{margin-bottom:120px!important}.ml-xl-15,.mx-xl-15{margin-left:120px!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:8px!important}.pt-xl-1,.py-xl-1{padding-top:8px!important}.pr-xl-1,.px-xl-1{padding-right:8px!important}.pb-xl-1,.py-xl-1{padding-bottom:8px!important}.pl-xl-1,.px-xl-1{padding-left:8px!important}.p-xl-2{padding:16px!important}.pt-xl-2,.py-xl-2{padding-top:16px!important}.pr-xl-2,.px-xl-2{padding-right:16px!important}.pb-xl-2,.py-xl-2{padding-bottom:16px!important}.pl-xl-2,.px-xl-2{padding-left:16px!important}.p-xl-3{padding:24px!important}.pt-xl-3,.py-xl-3{padding-top:24px!important}.pr-xl-3,.px-xl-3{padding-right:24px!important}.pb-xl-3,.py-xl-3{padding-bottom:24px!important}.pl-xl-3,.px-xl-3{padding-left:24px!important}.p-xl-4{padding:32px!important}.pt-xl-4,.py-xl-4{padding-top:32px!important}.pr-xl-4,.px-xl-4{padding-right:32px!important}.pb-xl-4,.py-xl-4{padding-bottom:32px!important}.pl-xl-4,.px-xl-4{padding-left:32px!important}.p-xl-5{padding:40px!important}.pt-xl-5,.py-xl-5{padding-top:40px!important}.pr-xl-5,.px-xl-5{padding-right:40px!important}.pb-xl-5,.py-xl-5{padding-bottom:40px!important}.pl-xl-5,.px-xl-5{padding-left:40px!important}.p-xl-6{padding:48px!important}.pt-xl-6,.py-xl-6{padding-top:48px!important}.pr-xl-6,.px-xl-6{padding-right:48px!important}.pb-xl-6,.py-xl-6{padding-bottom:48px!important}.pl-xl-6,.px-xl-6{padding-left:48px!important}.p-xl-7{padding:56px!important}.pt-xl-7,.py-xl-7{padding-top:56px!important}.pr-xl-7,.px-xl-7{padding-right:56px!important}.pb-xl-7,.py-xl-7{padding-bottom:56px!important}.pl-xl-7,.px-xl-7{padding-left:56px!important}.p-xl-8{padding:64px!important}.pt-xl-8,.py-xl-8{padding-top:64px!important}.pr-xl-8,.px-xl-8{padding-right:64px!important}.pb-xl-8,.py-xl-8{padding-bottom:64px!important}.pl-xl-8,.px-xl-8{padding-left:64px!important}.p-xl-9{padding:72px!important}.pt-xl-9,.py-xl-9{padding-top:72px!important}.pr-xl-9,.px-xl-9{padding-right:72px!important}.pb-xl-9,.py-xl-9{padding-bottom:72px!important}.pl-xl-9,.px-xl-9{padding-left:72px!important}.p-xl-10{padding:80px!important}.pt-xl-10,.py-xl-10{padding-top:80px!important}.pr-xl-10,.px-xl-10{padding-right:80px!important}.pb-xl-10,.py-xl-10{padding-bottom:80px!important}.pl-xl-10,.px-xl-10{padding-left:80px!important}.p-xl-12{padding:96px!important}.pt-xl-12,.py-xl-12{padding-top:96px!important}.pr-xl-12,.px-xl-12{padding-right:96px!important}.pb-xl-12,.py-xl-12{padding-bottom:96px!important}.pl-xl-12,.px-xl-12{padding-left:96px!important}.p-xl-15{padding:120px!important}.pt-xl-15,.py-xl-15{padding-top:120px!important}.pr-xl-15,.px-xl-15{padding-right:120px!important}.pb-xl-15,.py-xl-15{padding-bottom:120px!important}.pl-xl-15,.px-xl-15{padding-left:120px!important}.m-xl-n1{margin:-8px!important}.mt-xl-n1,.my-xl-n1{margin-top:-8px!important}.mr-xl-n1,.mx-xl-n1{margin-right:-8px!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-8px!important}.ml-xl-n1,.mx-xl-n1{margin-left:-8px!important}.m-xl-n2{margin:-16px!important}.mt-xl-n2,.my-xl-n2{margin-top:-16px!important}.mr-xl-n2,.mx-xl-n2{margin-right:-16px!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-16px!important}.ml-xl-n2,.mx-xl-n2{margin-left:-16px!important}.m-xl-n3{margin:-24px!important}.mt-xl-n3,.my-xl-n3{margin-top:-24px!important}.mr-xl-n3,.mx-xl-n3{margin-right:-24px!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-24px!important}.ml-xl-n3,.mx-xl-n3{margin-left:-24px!important}.m-xl-n4{margin:-32px!important}.mt-xl-n4,.my-xl-n4{margin-top:-32px!important}.mr-xl-n4,.mx-xl-n4{margin-right:-32px!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-32px!important}.ml-xl-n4,.mx-xl-n4{margin-left:-32px!important}.m-xl-n5{margin:-40px!important}.mt-xl-n5,.my-xl-n5{margin-top:-40px!important}.mr-xl-n5,.mx-xl-n5{margin-right:-40px!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-40px!important}.ml-xl-n5,.mx-xl-n5{margin-left:-40px!important}.m-xl-n6{margin:-48px!important}.mt-xl-n6,.my-xl-n6{margin-top:-48px!important}.mr-xl-n6,.mx-xl-n6{margin-right:-48px!important}.mb-xl-n6,.my-xl-n6{margin-bottom:-48px!important}.ml-xl-n6,.mx-xl-n6{margin-left:-48px!important}.m-xl-n7{margin:-56px!important}.mt-xl-n7,.my-xl-n7{margin-top:-56px!important}.mr-xl-n7,.mx-xl-n7{margin-right:-56px!important}.mb-xl-n7,.my-xl-n7{margin-bottom:-56px!important}.ml-xl-n7,.mx-xl-n7{margin-left:-56px!important}.m-xl-n8{margin:-64px!important}.mt-xl-n8,.my-xl-n8{margin-top:-64px!important}.mr-xl-n8,.mx-xl-n8{margin-right:-64px!important}.mb-xl-n8,.my-xl-n8{margin-bottom:-64px!important}.ml-xl-n8,.mx-xl-n8{margin-left:-64px!important}.m-xl-n9{margin:-72px!important}.mt-xl-n9,.my-xl-n9{margin-top:-72px!important}.mr-xl-n9,.mx-xl-n9{margin-right:-72px!important}.mb-xl-n9,.my-xl-n9{margin-bottom:-72px!important}.ml-xl-n9,.mx-xl-n9{margin-left:-72px!important}.m-xl-n10{margin:-80px!important}.mt-xl-n10,.my-xl-n10{margin-top:-80px!important}.mr-xl-n10,.mx-xl-n10{margin-right:-80px!important}.mb-xl-n10,.my-xl-n10{margin-bottom:-80px!important}.ml-xl-n10,.mx-xl-n10{margin-left:-80px!important}.m-xl-n12{margin:-96px!important}.mt-xl-n12,.my-xl-n12{margin-top:-96px!important}.mr-xl-n12,.mx-xl-n12{margin-right:-96px!important}.mb-xl-n12,.my-xl-n12{margin-bottom:-96px!important}.ml-xl-n12,.mx-xl-n12{margin-left:-96px!important}.m-xl-n15{margin:-120px!important}.mt-xl-n15,.my-xl-n15{margin-top:-120px!important}.mr-xl-n15,.mx-xl-n15{margin-right:-120px!important}.mb-xl-n15,.my-xl-n15{margin-bottom:-120px!important}.ml-xl-n15,.mx-xl-n15{margin-left:-120px!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media(min-width:400px){.text-xs-left{text-align:left!important}.text-xs-right{text-align:right!important}.text-xs-center{text-align:center!important}}@media(min-width:616px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media(min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media(min-width:980px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media(min-width:1240px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-primary{color:#fc0!important}a.text-primary:focus,a.text-primary:hover{color:#b38f00!important}.text-secondary{color:#212529!important}a.text-secondary:focus,a.text-secondary:hover{color:#000!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f1f6f9!important}a.text-light:focus,a.text-light:hover{color:#bbd4e2!important}.text-dark{color:#495057!important}a.text-dark:focus,a.text-dark:hover{color:#262a2d!important}.text-primary-light{color:#fffaf0!important}a.text-primary-light:focus,a.text-primary-light:hover{color:#ffe1a4!important}.text-secondary-light{color:#fff!important}a.text-secondary-light:focus,a.text-secondary-light:hover{color:#d9d9d9!important}.text-tertiary{color:#257af4!important}a.text-tertiary:focus,a.text-tertiary:hover{color:#0a56c3!important}.text-tertiary-light{color:#e3f1fe!important}a.text-tertiary-light:focus,a.text-tertiary-light:hover{color:#99ccfb!important}.text-white{color:#fff!important}a.text-white:focus,a.text-white:hover{color:#d9d9d9!important}.text-black{color:#212529!important}a.text-black:focus,a.text-black:hover{color:#000!important}.text-blue{color:#257af4!important}a.text-blue:focus,a.text-blue:hover{color:#0a56c3!important}.text-light-blue{color:#e3f1fe!important}a.text-light-blue:focus,a.text-light-blue:hover{color:#99ccfb!important}.text-yellow{color:#fc0!important}a.text-yellow:focus,a.text-yellow:hover{color:#b38f00!important}.text-light-yellow{color:#fffaf0!important}a.text-light-yellow:focus,a.text-light-yellow:hover{color:#ffe1a4!important}.text-orange{color:#ff8c00!important}a.text-orange:focus,a.text-orange:hover{color:#b36200!important}.text-light-orange{color:#ffe4b5!important}a.text-light-orange:focus,a.text-light-orange:hover{color:#ffc869!important}.text-red{color:#ff3939!important}a.text-red:focus,a.text-red:hover{color:#ec0000!important}.text-light-red{color:#ffe4e1!important}a.text-light-red:focus,a.text-light-red:hover{color:#ff9f95!important}.text-medium{color:#d6dbdf!important}a.text-medium:focus,a.text-medium:hover{color:#abb5bd!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(33,37,41,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #d6dbdf;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:980px!important}.navbar{display:none}.badge{border:1px solid #212529}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#d6dbdf}.table .thead-dark th{color:inherit;border-color:#d6dbdf}} \ No newline at end of file diff --git a/website/css/greenhouse.css b/website/css/greenhouse.css new file mode 100644 index 00000000000..76812a169e8 --- /dev/null +++ b/website/css/greenhouse.css @@ -0,0 +1 @@ +#main{padding-bottom:0;padding-top:0}#wrapper{max-width:1078px;padding:0}body>#wrapper>#main>#wrapper>#content,body>#wrapper>#main>#wrapper>#logo,body>#wrapper>#main>#wrapper>h1{display:none}body>#wrapper>#main>#wrapper>#board_title{margin-top:0}body>#wrapper>#main>#logo{margin-top:80px}body>#wrapper>#main>:last-child{margin-bottom:120px} \ No newline at end of file diff --git a/website/css/main.css b/website/css/main.css index 9b676804eba..229b74cb3f7 100644 --- a/website/css/main.css +++ b/website/css/main.css @@ -1,1039 +1 @@ -@media screen and (max-width: 978.98px) { - .btn { - padding: 8px 16px; - } -} - -@media screen and (max-width: 978.98px) { - .btn-lg { - padding: 12px 24px; - } -} - -.btn-primary { - color: #212529; -} -.btn-primary:active, .btn-primary:hover { - color: #212529; -} - -.btn-outline-primary { - background: #fffaf0; - border-color: #ffcc00; - color: #212529; -} -.btn-outline-primary:active, .btn-outline-primary:hover { - background: #ffcc00; - border-color: #ffcc00; - color: #212529; -} - -.btn-secondary { - border-color: #212529; - color: #fff; -} -.btn-secondary:active, .btn-secondary:hover { - background: #fff; - border-color: #212529; - color: #212529; -} - -.btn-outline-secondary { - background: #fff; - border-color: #212529; - color: #212529; -} -.btn-outline-secondary:active, .btn-outline-secondary:hover { - background: #212529; - border-color: #212529; - color: #fff; -} - -.btn-tertiary { - border-color: #257af4; - color: #fff; -} -.btn-tertiary:active, .btn-tertiary:hover { - background: #257af4; - border-color: #257af4; - color: #fff; -} - -.btn-outline-tertiary { - background: #e3f1fe; - color: #257af4; -} -.btn-outline-tertiary:active, .btn-outline-tertiary:hover { - background: #257af4; - color: #fff; -} - -.btns { - align-items: center; - display: flex; - justify-content: center; -} -.btns .btn + .btn { - margin-left: 24px; -} -.btns .btn-lg + .btn-lg { - margin-left: 40px; -} - -.card { - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2); - overflow: hidden; - position: relative; - transition: box-shadow 0.2s, transform 0.2s; - width: 100%; -} -.card-body { - position: relative; - z-index: 10; -} - -.card.is-large .card-body { - padding: 40px; -} - -.card.bg-primary-light { - border-color: #ffcc00; -} - -.card.has-dark-border { - border-color: #6c757d; -} - -.card.has-pattern:before, -.card.has-pattern:after { - background-repeat: no-repeat; - background-size: auto 100%; - bottom: 0; - content: ""; - display: block; - position: absolute; - top: 0; - width: 72px; -} - -.card.has-pattern:before { - background-image: url(../images/backgrounds/bg-card-pattern-blue-1.png); - background-position: left top; - left: 0; -} - -.card.has-pattern:after { - background-image: url(../images/backgrounds/bg-card-pattern-blue-2.png); - background-position: right top; - right: 0; -} - -a.card:active, -a.card:hover, -.card.has-hover:active, -.card.has-hover:hover { - box-shadow: 0 12px 32px rgba(108, 117, 125, 0.2); - transform: translateY(-8px); -} - -a.card:after, -.card.has-hover:after, -.card.has-highlight:after { - content: ""; - display: block; - height: 8px; - margin-top: auto; - transition: background 0.2s; - width: 100%; -} - -a.card:active:after, -a.card:hover:after, -.card.has-hover:active:after, -.card.has-hover:hover:after, -.card.has-highlight:after { - background: #e3f1fe; -} - -.case-study-cards { - -moz-column-gap: 40px; - column-gap: 40px; - display: grid; - grid-template-columns: 1fr; - row-gap: 40px; - padding-bottom: 40px; - position: relative; -} -.case-study-cards > div { - align-items: stretch; - display: flex; -} -.case-study-cards:before { - background: #d6dbdf; - bottom: 0; - content: ""; - display: block; - left: 20px; - position: absolute; - top: 40px; - width: 100vw; -} -@media screen and (min-width: 980px) { - .case-study-cards { - grid-template-columns: repeat(2, minmax(0, 1fr)); - row-gap: 80px; - padding-bottom: 120px; - } - .case-study-cards:before { - left: -40px; - top: 120px; - } -} - -.case-study-card { - align-items: stretch; - flex-direction: row; - flex-shrink: 0; - left: 0; - transition: 0.2s box-shadow, 0.4s left, 0.4s width, 0s z-index; - transition-delay: 0s, 0.6s, 0.6s, 0s; - width: 100%; - z-index: 2; -} -@media screen and (max-width: 979.98px) { - .case-study-card .row { - min-height: 0 !important; - } -} -@media screen and (min-width: 980px) { - .case-study-card:active, .case-study-card:hover { - box-shadow: 0 12px 32px rgba(108, 117, 125, 0.2); - } - .case-study-card:not(.is-open) { - cursor: pointer; - } - .case-study-card.is-open { - transform: none !important; - transition-delay: 0s, 0s, 0s, 0s; - width: calc(200% + 40px); - z-index: 10; - } - .case-study-card.is-closing { - z-index: 10; - } - .case-study-card.open-left.is-open { - left: calc(-100% - 40px); - } - .case-study-card:before { - background: no-repeat url(../images/backgrounds/bg-card-pattern-red.png); - background-position: right center; - background-size: contain; - content: ""; - display: block; - height: calc(100% - 80px); - max-height: 224px; - max-width: 234px; - position: absolute; - right: 0; - top: 40px; - transform: translateX(30%); - transition: 0.4s transform; - transition-delay: 0.6s; - width: 100%; - z-index: 1; - } -} -@media screen and (min-width: 980px) and (min-width: 1240px) { - .case-study-card:before { - transform: translateX(10%); - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open:before { - transform: translateX(60%); - transition-delay: 0s; - } -} -@media screen and (min-width: 980px) { - .case-study-card-wrap { - align-items: stretch; - display: flex; - flex-shrink: 0; - min-height: 304px; - position: relative; - transition: 0.4s width; - transition-delay: 0.6s; - width: calc(200% + 42px); - z-index: 2; - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open .case-study-card-wrap { - transition-delay: 0s; - width: 100%; - } -} -@media screen and (min-width: 980px) { - .case-study-card-body { - display: flex; - flex-direction: column; - padding-right: 80px !important; - } - .case-study-card-body > .row { - align-self: stretch; - } -} -@media screen and (min-width: 980px) { - .case-study-card-toggle { - background: #fff; - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2); - border-radius: 100%; - cursor: pointer; - height: 56px; - position: relative; - width: 56px; - } - .case-study-card-toggle:before, .case-study-card-toggle:after { - background: #257af4; - content: ""; - display: block; - height: 4px; - left: calc(50% - 15px); - position: absolute; - top: calc(50% - 2px); - transition: opacity 0.2s, transform 0.2s; - width: 30px; - } - .case-study-card-toggle:after { - transform: rotate(90deg); - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open .case-study-card-toggle:before { - opacity: 0; - transform: rotate(-90deg); - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open .case-study-card-toggle:after { - transform: rotate(0); - } -} -@media screen and (min-width: 980px) { - .case-study-card .col-lg-3, -.case-study-card .col-lg-auto { - opacity: 0; - transform: translateX(24px); - transition: 0.4s opacity, 0.4s transform; - } -} -@media screen and (min-width: 980px) { - .case-study-card .col-lg-3 { - transition-delay: 0s; - } -} -@media screen and (min-width: 980px) { - .case-study-card .col-lg-auto { - transition-delay: 0.2s; - } -} -@media screen and (min-width: 980px) and (min-width: 980px) { - .case-study-card .col-lg-auto { - max-width: 605px; - width: calc(100% - 319px); - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open .col-lg-3, .case-study-card.is-open .col-lg-auto { - opacity: 1; - transform: none; - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open .col-lg-3 { - transition-delay: 0.4s; - } -} -@media screen and (min-width: 980px) { - .case-study-card.is-open .col-lg-auto { - transition-delay: 0.2s; - } -} - -.footer-copy { - white-space: nowrap; -} - -form .form-control { - border: 1px solid #6c757d; - border-radius: 6px; - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2); - color: #212529; - height: auto; - line-height: 20px; - min-height: 44px; - padding: 12px 16px; - width: 100%; -} -form .form-control:focus { - border-color: #212529; - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2); - color: #212529; -} -form .form-control::-moz-placeholder { - color: #6c757d; -} -form .form-control:-ms-input-placeholder { - color: #6c757d; -} -form .form-control::placeholder { - color: #6c757d; -} -form select.form-control { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} -form select.form-control:not([data-chosen]) { - color: #6c757d; -} -form .btn-secondary:active, -form .btn-secondary:hover { - color: #212529; - background: #ffcc00; - border-color: #ffcc00; -} - -.hero { - background-repeat: no-repeat; - background-position: center; - background-size: cover; - overflow: visible; - position: relative; -} -.hero-bg { - background-repeat: no-repeat; - background-position: center; - background-size: cover; - display: block; - height: 100%; - left: 50%; - position: absolute; - top: 0; - transform: translateX(-50%); - z-index: 1; -} -.hero > .container { - position: relative; - z-index: 2; -} - -.hero.has-offset { - margin-bottom: -160px; - padding-bottom: 160px; -} - -hr { - background: #f1f6f9; - border: 0; - display: block; - height: 4px; - margin: 0; - width: 100%; -} - -hr.is-small { - height: 2px; -} - -hr.is-large { - height: 8px; -} - -hr.is-medium { - background: #d6dbdf; -} - -hr.is-dark { - background: #495057; -} - -hr.is-yellow { - background: linear-gradient(90deg, #ff8c00 0, #ff8c00 8px, #ffcc00 16px, rgba(255, 204, 0, 0) 100%); - -webkit-clip-path: polygon(8px 100%, 0 100%, 0 0, 8px 0, 8px 100%, 16px 100%, 16px 0, 100% 0, 100% 100%); - clip-path: polygon(8px 100%, 0 100%, 0 0, 8px 0, 8px 100%, 16px 100%, 16px 0, 100% 0, 100% 100%); - height: 8px; -} - -.icon { - display: block; - height: 48px; - margin-bottom: 24px; - -o-object-fit: contain; - object-fit: contain; - -o-object-position: center; - object-position: center; -} -@media screen and (min-width: 576px) { - .icon { - height: 64px; - } -} -@media screen and (min-width: 980px) { - .icon { - height: 80px; - } -} - -img { - max-width: 100%; -} - -.kicker { - color: #6c757d; - font-family: "Hind Siliguri", sans-serif; - font-size: 0.875rem; - font-weight: 600; - letter-spacing: 1px; - margin: 0; -} - -@media screen and (max-width: 978.98px) { - .lead { - font-size: 1.125rem; - } -} - -.navbar-clickhouse { - border-bottom: 4px solid #f1f6f9 !important; - height: 142px !important; -} -.navbar-clickhouse > .container { - flex-wrap: wrap !important; -} -.navbar-super { - flex-shrink: 0; - width: 100%; -} -.navbar-super ul { - list-style: none; -} -.navbar-super li:not(:last-child) { - margin-bottom: 0; - margin-right: 24px; -} -.navbar-super a { - align-items: center; - color: #212529; - display: flex; - font-size: 0.875rem; -} -.navbar-super a:active, .navbar-super a:hover { - color: #257af4; - text-decoration: none; -} -.navbar-super img { - flex-shrink: 0; - margin-right: 4px; -} -.navbar-brand-clickhouse { - background: no-repeat url(/images/logo-clickhouse.svg); - background-size: contain; - flex-shrink: 0; - height: 28px; - margin-right: 48px; - padding: 0; - width: 180px; -} -.navbar-nav { - align-items: center; - height: 46px; -} -.navbar .nav-item:not(:last-child) { - margin-bottom: 0; - margin-right: 24px; -} -.navbar .nav-link { - color: #212529; -} -.navbar .nav-link:active, .navbar .nav-link:hover { - color: #257af4; -} -.navbar .navbar-nav { - flex-direction: row; -} -@media screen and (max-width: 978.98px) { - .navbar > .container { - padding-left: 20px; - padding-right: 20px; - } - .navbar .navbar-toggler { - height: 24px; - padding: 0; - width: 24px; - } - .navbar .navbar-toggler:focus { - outline: none; - } - .navbar .navbar-toggler-icon { - background: no-repeat url(../images/icons/icon-menu.svg); - background-position: center; - background-size: contain; - height: 24px; - width: 24px; - } - .navbar .navbar-collapse { - background: #fff; - border-bottom: 4px solid #f1f6f9; - height: 56px; - left: 0; - padding: 0 20px 16px; - position: absolute; - right: 0; - top: 100%; - } - .navbar .nav-link { - font-size: 0.875rem; - white-space: nowrap; - } -} -@media screen and (max-width: 615.98px) { - .navbar .navbar-collapse { - height: auto; - } - .navbar .navbar-nav { - flex-direction: column; - height: auto; - } - .navbar .nav-item:not(:last-child) { - margin-bottom: 16px; - margin-right: 0; - } -} -@media screen and (max-width: 399.98px) { - .navbar { - height: 80px; - } -} - -.page { - overflow: hidden; - width: 100vw; -} - -.photo-frame { - background: rgba(255, 255, 255, 0.6); - border-radius: 100%; - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2); - display: block; - margin-bottom: 24px; - max-width: 160px; - overflow: hidden; - position: relative; - width: 100%; -} -.photo-frame:before { - content: ""; - display: block; - padding-bottom: 100%; - width: 100%; -} -.photo-frame img { - display: block; - height: 100%; - left: 0; - -o-object-fit: contain; - object-fit: contain; - -o-object-position: center; - object-position: center; - position: absolute; - top: 0; - width: 100%; -} - -.pullquote { - position: relative; - width: 70%; -} -.pullquote:before { - background: no-repeat url(../images/backgrounds/bg-quotes.svg); - background-position: center; - background-size: 100%; - bottom: 0; - content: ""; - display: block; - mix-blend-mode: multiply; - position: absolute; - right: 56px; - top: 0; - width: calc(100% - 16px); - z-index: 2; -} -.pullquote-bg { - bottom: 0; - display: block; - position: absolute; - right: 0; - top: 0; - width: calc(50vw + 28.5714285714%); - z-index: 1; -} -.pullquote-body { - padding: 64px 40px 64px 0; - position: relative; - z-index: 3; -} -.pullquote-quote { - font-family: "Hind Siliguri", sans-serif; - font-size: 32px; - font-weight: 700; -} -.pullquote-citation { - font-size: 1.125rem; -} - -.section { - background-repeat: no-repeat; - background-position: center; - background-size: cover; - overflow: visible; - position: relative; -} -.section-bg { - background-repeat: no-repeat; - background-position: center; - background-size: cover; - display: block; - height: 100%; - left: 50%; - position: absolute; - top: 0; - transform: translateX(-50%); - z-index: 1; -} -.section > .container { - position: relative; - z-index: 2; -} - -.social-icons { - align-items: center; - display: flex; -} -.social-icons > a { - aspect-ratio: 24/24; - background: #6c757d; - display: block; - height: 24px; - width: 24px; - -webkit-mask-position: center; - mask-position: center; - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - -webkit-mask-size: contain; - mask-size: contain; - transition: 0.2s background; -} -.social-icons > a:active, .social-icons > a:hover { - background: #212529; -} -.social-icons > a + a { - margin-left: 32px; -} -.social-icons-facebook { - -webkit-mask-image: url("/images/icons/icon-facebook-gray.svg"); - mask-image: url("/images/icons/icon-facebook-gray.svg"); -} -.social-icons-twitter { - -webkit-mask-image: url("/images/icons/icon-twitter-gray.svg"); - mask-image: url("/images/icons/icon-twitter-gray.svg"); - width: 31px; -} -.social-icons-linkedin { - -webkit-mask-image: url("/images/icons/icon-linkedin-gray.svg"); - mask-image: url("/images/icons/icon-linkedin-gray.svg"); -} -.social-icons-linkedin-alt { - -webkit-mask-image: url("/images/icons/icon-linkedin-alt-gray.svg"); - mask-image: url("/images/icons/icon-linkedin-alt-gray.svg"); -} - -.social-icons.size-small > a { - height: 20px; - width: 20px; -} -.social-icons.size-small > a:active, .social-icons.size-small > a:hover { - background: #212529; -} -.social-icons.size-small > a + a { - margin-left: 16px; -} - -.tabs { - position: relative; -} -.tabs:before { - background: #fff; - border-radius: 7px 7px 0 0; - content: ""; - display: block; - height: 8px; - left: 1px; - position: absolute; - right: 1px; - top: 68px; - z-index: 10; -} -@media screen and (min-width: 1240px) { - .tabs:before { - top: 76px; - } -} -.tabs-body { - background: #fff; - border-color: #6c757d; - border-radius: 8px; - border-style: solid; - border-width: 1px; - box-shadow: 0 8px 20px rgba(108, 117, 125, 0.2); - padding: 24px; -} -@media screen and (min-width: 980px) { - .tabs-body { - padding: 32px; - } -} -@media screen and (min-width: 1240px) { - .tabs-body { - padding: 40px; - } -} -.tabs .nav-tabs { - border-bottom: 0; - flex-wrap: nowrap; - height: 76px; - margin: -20px -20px -9px; - -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 20px, #000 calc(100% - 20px), transparent 100%); - mask-image: linear-gradient(90deg, transparent 0%, #000 20px, #000 calc(100% - 20px), transparent 100%); - overflow: scroll; - overflow-x: scroll; - overflow-y: visible; - padding: 20px 20px 0; - position: relative; -} -@media screen and (min-width: 940px) { - .tabs .nav-tabs { - overflow: visible; - } -} -@media screen and (min-width: 1240px) { - .tabs .nav-tabs { - height: 84px; - } -} -.tabs .nav-link { - align-items: center; - border-bottom: 0; - color: #6c757d; - display: flex; - font-size: 0.875rem; - flex-shrink: 0; - height: 56px; - justify-content: center; - padding: 0 12px 8px; - text-align: center; - white-space: nowrap; -} -@media screen and (min-width: 1240px) { - .tabs .nav-link { - height: 64px; - padding: 0 16px 8px; - } -} -.tabs .nav-link.active { - background: #fff; - box-shadow: 0 -4px 8px rgba(108, 117, 125, 0.1); - font-weight: 700; - padding: 0 16px 8px; -} -@media screen and (min-width: 980px) { - .tabs .nav-link.active { - padding: 0 24px 8px; - } -} -@media screen and (min-width: 1240px) { - .tabs .nav-link.active { - padding: 0 32px 8px; - } -} - -.tab-pane pre { - background: #212529; - border-radius: 16px; - color: #fff; - padding: 24px 16px; -} -@media screen and (min-width: 1240px) { - .tab-pane pre { - padding: 32px 24px; - } -} - -.trailing-link { - align-items: center; - color: #212529; - display: flex; - font-size: 0.875rem; - font-weight: 700; -} -.trailing-link:after { - background: no-repeat url(../images/icons/icon-arrow.svg); - background-position: right center; - background-size: contain; - content: ""; - display: block; - height: 12px; - transition: 0.2s transform; - width: 20px; -} -.trailing-link:active, .trailing-link:hover { - color: #212529; - text-decoration: none; -} -.trailing-link:active:after, .trailing-link:hover:after { - transform: translateX(8px); -} -.trailing-link.span-full:after { - margin-left: auto; -} - -ul { - list-style-type: square; - padding-left: 1.25em; -} -ul li:not(:last-child) { - margin-bottom: 16px; -} -ul li::marker { - color: #ff3939; -} - -ul.has-separators { - list-style: none; - padding: 0; -} -ul.has-separators li:not(:last-child) { - border-bottom: 4px solid #f1f6f9; - margin-bottom: 24px; - padding-bottom: 24px; -} - -.bg-gradient-secondary { - background-image: linear-gradient(58deg, #FF6443 3%, #FE561D 24%, #E32F0D 93%); -} - -.bg-gradient-light-orange { - background-image: linear-gradient(90deg, rgba(255, 203, 128, 0) 0%, #FFCB80 100%); -} - -.bg-offset-right { - bottom: 0; - left: -24px; - position: absolute; - top: 0; - width: calc(100vw + 24px); - z-index: -1; -} -@media screen and (min-width: 1240px) { - .bg-offset-right { - left: -96px; - width: calc(100vw + 96px); - } -} - -.bg-inset-right { - bottom: 0; - left: 40px; - position: absolute; - top: 0; - width: calc(100vw - 40px); - z-index: -1; -} -@media screen and (min-width: 980px) { - .bg-inset-right { - left: 96px; - width: calc(100vw - 96px); - } -} - -.has-border-left { - border-left: 8px solid #f1f6f9; - padding-left: 16px; -} - -.font-xl { - font-size: 1.25rem; -} - -.font-lg { - font-size: 1.125rem; -} - -.font-sm { - font-size: 0.875rem; -} - -.font-xs { - font-size: 0.625rem; -} - -.font-weight-semibold { - font-weight: 600; -} - -.display-5 { - color: #212529; - font-size: 20px; - font-weight: 500; -} - -.display-6 { - color: #212529; - font-size: 14px; - font-weight: 700; -} - -.text-decoration-underline { - text-decoration: underline; -} - -.text-upper { - text-transform: uppercase; -} -.base-hero { - height:22.5vw; - max-height:324px; - min-height:280px; -} -.index-hero { - background-image:url('/images/backgrounds/bg-hero-home.svg'); - height:68vw; - max-height:980px; - max-width:2448px; - width:170vw; -} -.other-hero { - background-image: url('/images/backgrounds/bg-hero.svg'); - max-width: 2448px; - width: 170vw; -} -.bg-footer-cta { - background-image:url('/images/backgrounds/bg-footer-cta.svg'); - width:2448px; -} -.quickstart-bg { - background-image:url('/images/backgrounds/bg-quick-start.svg'); - height:40vw; - top:220px; - width:170vw; -} +@media screen and (max-width:978.98px){.btn{padding:8px 16px}}@media screen and (max-width:978.98px){.btn-lg{padding:12px 24px}}.btn-primary,.btn-primary:active,.btn-primary:hover{color:#212529}.btn-outline-primary{background:#fffaf0;border-color:#fc0;color:#212529}.btn-outline-primary:active,.btn-outline-primary:hover{background:#fc0;border-color:#fc0;color:#212529}.btn-secondary{border-color:#212529;color:#fff}.btn-outline-secondary,.btn-secondary:active,.btn-secondary:hover{background:#fff;border-color:#212529;color:#212529}.btn-outline-secondary:active,.btn-outline-secondary:hover{background:#212529;border-color:#212529;color:#fff}.btn-tertiary{border-color:#257af4;color:#fff}.btn-tertiary:active,.btn-tertiary:hover{background:#257af4;border-color:#257af4;color:#fff}.btn-outline-tertiary{background:#e3f1fe;color:#257af4}.btn-outline-tertiary:active,.btn-outline-tertiary:hover{background:#257af4;color:#fff}.btns{align-items:center;display:flex;justify-content:center}.btns .btn+.btn{margin-left:24px}.btns .btn-lg+.btn-lg{margin-left:40px}.card{box-shadow:0 8px 20px rgba(108,117,125,.2);overflow:hidden;transition:box-shadow .2s,transform .2s;width:100%}.card,.card-body{position:relative}.card-body{z-index:10}.card.is-large .card-body{padding:40px}.card.bg-primary-light{border-color:#fc0}.card.has-dark-border{border-color:#6c757d}.card.has-pattern:after,.card.has-pattern:before{background-repeat:no-repeat;background-size:auto 100%;bottom:0;content:"";display:block;position:absolute;top:0;width:72px}.card.has-pattern:before{background-image:url(../images/backgrounds/bg-card-pattern-blue-1.png);background-position:0 0;left:0}.card.has-pattern:after{background-image:url(../images/backgrounds/bg-card-pattern-blue-2.png);background-position:100% 0;right:0}.card.has-hover:active,.card.has-hover:hover,a.card:active,a.card:hover{box-shadow:0 12px 32px rgba(108,117,125,.2);transform:translateY(-8px)}.card.has-highlight:after,.card.has-hover:after,a.card:after{content:"";display:block;height:8px;margin-top:auto;transition:background .2s;width:100%}.card.has-highlight:after,.card.has-hover:active:after,.card.has-hover:hover:after,a.card:active:after,a.card:hover:after{background:#e3f1fe}.case-study-cards{-moz-column-gap:40px;column-gap:40px;display:grid;grid-template-columns:1fr;row-gap:40px;padding-bottom:40px;position:relative}.case-study-cards>div{align-items:stretch;display:flex}.case-study-cards:before{background:#d6dbdf;bottom:0;content:"";display:block;left:20px;position:absolute;top:40px;width:100vw}@media screen and (min-width:980px){.case-study-cards{grid-template-columns:repeat(2,minmax(0,1fr));row-gap:80px;padding-bottom:120px}.case-study-cards:before{left:-40px;top:120px}}.case-study-card{align-items:stretch;flex-direction:row;flex-shrink:0;left:0;transition:box-shadow .2s,left .4s,width .4s,z-index 0s;transition-delay:0s,.6s,.6s,0s;width:100%;z-index:2}@media screen and (max-width:979.98px){.case-study-card .row{min-height:0!important}}@media screen and (min-width:980px){.case-study-card:active,.case-study-card:hover{box-shadow:0 12px 32px rgba(108,117,125,.2)}.case-study-card:not(.is-open){cursor:pointer}.case-study-card.is-open{transform:none!important;transition-delay:0s,0s,0s,0s;width:calc(200% + 40px);z-index:10}.case-study-card.is-closing{z-index:10}.case-study-card.open-left.is-open{left:calc(-100% - 40px)}.case-study-card:before{background:no-repeat url(../images/backgrounds/bg-card-pattern-red.png);background-position:100%;background-size:contain;content:"";display:block;height:calc(100% - 80px);max-height:224px;max-width:234px;position:absolute;right:0;top:40px;transform:translateX(30%);transition:transform .4s;transition-delay:.6s;width:100%;z-index:1}}@media screen and (min-width:980px)and (min-width:1240px){.case-study-card:before{transform:translateX(10%)}}@media screen and (min-width:980px){.case-study-card.is-open:before{transform:translateX(60%);transition-delay:0s}}@media screen and (min-width:980px){.case-study-card-wrap{align-items:stretch;display:flex;flex-shrink:0;min-height:304px;position:relative;transition:width .4s;transition-delay:.6s;width:calc(200% + 42px);z-index:2}}@media screen and (min-width:980px){.case-study-card.is-open .case-study-card-wrap{transition-delay:0s;width:100%}}@media screen and (min-width:980px){.case-study-card-body{display:flex;flex-direction:column;padding-right:80px!important}.case-study-card-body>.row{align-self:stretch}}@media screen and (min-width:980px){.case-study-card-toggle{background:#fff;box-shadow:0 8px 20px rgba(108,117,125,.2);border-radius:100%;cursor:pointer;height:56px;position:relative;width:56px}.case-study-card-toggle:after,.case-study-card-toggle:before{background:#257af4;content:"";display:block;height:4px;left:calc(50% - 15px);position:absolute;top:calc(50% - 2px);transition:opacity .2s,transform .2s;width:30px}.case-study-card-toggle:after{transform:rotate(90deg)}}@media screen and (min-width:980px){.case-study-card.is-open .case-study-card-toggle:before{opacity:0;transform:rotate(-90deg)}}@media screen and (min-width:980px){.case-study-card.is-open .case-study-card-toggle:after{transform:rotate(0)}}@media screen and (min-width:980px){.case-study-card .col-lg-3,.case-study-card .col-lg-auto{opacity:0;transform:translateX(24px);transition:opacity .4s,transform .4s}}@media screen and (min-width:980px){.case-study-card .col-lg-3{transition-delay:0s}}@media screen and (min-width:980px){.case-study-card .col-lg-auto{transition-delay:.2s}}@media screen and (min-width:980px)and (min-width:980px){.case-study-card .col-lg-auto{max-width:605px;width:calc(100% - 319px)}}@media screen and (min-width:980px){.case-study-card.is-open .col-lg-3,.case-study-card.is-open .col-lg-auto{opacity:1;transform:none}}@media screen and (min-width:980px){.case-study-card.is-open .col-lg-3{transition-delay:.4s}}@media screen and (min-width:980px){.case-study-card.is-open .col-lg-auto{transition-delay:.2s}}.footer-copy{white-space:nowrap}form .form-control{border:1px solid #6c757d;border-radius:6px;height:auto;line-height:20px;min-height:44px;padding:12px 16px;width:100%}form .form-control,form .form-control:focus{box-shadow:0 8px 20px rgba(108,117,125,.2);color:#212529}form .form-control:focus{border-color:#212529}form .form-control::-moz-placeholder{color:#6c757d}form .form-control:-ms-input-placeholder{color:#6c757d}form .form-control::placeholder{color:#6c757d}form select.form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}form select.form-control:not([data-chosen]){color:#6c757d}form .btn-secondary:active,form .btn-secondary:hover{color:#212529;background:#fc0;border-color:#fc0}.hero{overflow:visible;position:relative}.hero,.hero-bg{background-repeat:no-repeat;background-position:50%;background-size:cover}.hero-bg{display:block;height:100%;left:50%;position:absolute;top:0;transform:translateX(-50%);z-index:1}.hero>.container{position:relative;z-index:2}.hero.has-offset{margin-bottom:-160px;padding-bottom:160px}.base-hero{height:22.5vw;max-height:324px;min-height:280px}.index-hero{background-image:url(/images/backgrounds/bg-hero-home.svg);height:68vw;max-height:980px}.index-hero,.other-hero{max-width:2448px;width:170vw}.other-hero{background-image:url(/images/backgrounds/bg-hero.svg)}.bg-footer-cta{background-image:url(/images/backgrounds/bg-footer-cta.svg);width:2448px}.quickstart-bg{background-image:url(/images/backgrounds/bg-quick-start.svg);height:40vw;top:220px;width:170vw}hr{background:#f1f6f9;border:0;display:block;height:4px;margin:0;width:100%}hr.is-small{height:2px}hr.is-large{height:8px}hr.is-medium{background:#d6dbdf}hr.is-dark{background:#495057}hr.is-yellow{background:linear-gradient(90deg,#ff8c00,#ff8c00 8px,#fc0 16px,rgba(255,204,0,0));-webkit-clip-path:polygon(8px 100%,0 100%,0 0,8px 0,8px 100%,16px 100%,16px 0,100% 0,100% 100%);clip-path:polygon(8px 100%,0 100%,0 0,8px 0,8px 100%,16px 100%,16px 0,100% 0,100% 100%);height:8px}.icon{display:block;height:48px;margin-bottom:24px;-o-object-fit:contain;object-fit:contain;-o-object-position:center;object-position:center}@media screen and (min-width:576px){.icon{height:64px}}@media screen and (min-width:980px){.icon{height:80px}}img{max-width:100%}.kicker{color:#6c757d;font-family:Hind Siliguri,sans-serif;font-size:.875rem;font-weight:600;letter-spacing:1px;margin:0}@media screen and (max-width:978.98px){.lead{font-size:1.125rem}}.navbar-clickhouse{border-bottom:4px solid #f1f6f9;height:142px}.navbar-clickhouse>.container{flex-wrap:wrap}.navbar-super{flex-shrink:0;width:100%}.navbar-super ul{list-style:none}.navbar-super li:not(:last-child){margin-bottom:0;margin-right:24px}.navbar-super a{align-items:center;color:#212529;display:flex;font-size:.875rem}.navbar-super a:active,.navbar-super a:hover{color:#257af4;text-decoration:none}.navbar-super img{flex-shrink:0;margin-right:4px}.navbar-brand-clickhouse{background:no-repeat url(../images/logo-clickhouse.svg);background-size:contain;flex-shrink:0;height:28px;margin-right:48px;padding:0;width:180px}.navbar-nav{align-items:center;height:46px}.navbar .nav-item:not(:last-child){margin-bottom:0;margin-right:24px}.navbar .nav-link{color:#212529}.navbar .nav-link:active,.navbar .nav-link:hover{color:#257af4}.navbar .navbar-nav{flex-direction:row}@media screen and (max-width:978.98px){.navbar>.container{padding-left:20px;padding-right:20px}.navbar .navbar-toggler{height:24px;padding:0;width:24px}.navbar .navbar-toggler:focus{outline:none}.navbar .navbar-toggler-icon{background:no-repeat url(../images/icons/icon-menu.svg);background-position:50%;background-size:contain;height:24px;width:24px}.navbar .navbar-collapse{background:#fff;border-bottom:4px solid #f1f6f9;height:56px;left:0;padding:0 20px 16px;position:absolute;right:0;top:100%}.navbar .nav-link{font-size:.875rem;white-space:nowrap}}@media screen and (max-width:615.98px){.navbar .navbar-collapse{height:auto}.navbar .navbar-nav{flex-direction:column;height:auto}.navbar .nav-item:not(:last-child){margin-bottom:16px;margin-right:0}}@media screen and (max-width:399.98px){.navbar{height:80px}}.page{overflow:hidden;width:100vw}.photo-frame{background:hsla(0,0%,100%,.6);border-radius:100%;box-shadow:0 8px 20px rgba(108,117,125,.2);display:block;margin-bottom:24px;max-width:160px;overflow:hidden;position:relative;width:100%}.photo-frame:before{content:"";display:block;padding-bottom:100%;width:100%}.photo-frame img{display:block;height:100%;left:0;-o-object-fit:contain;object-fit:contain;-o-object-position:center;object-position:center;position:absolute;top:0;width:100%}.pullquote{position:relative;width:70%}.pullquote:before{background:no-repeat url(../images/backgrounds/bg-quotes.svg);background-position:50%;background-size:100%;content:"";mix-blend-mode:multiply;right:56px;width:calc(100% - 16px);z-index:2}.pullquote-bg,.pullquote:before{bottom:0;display:block;position:absolute;top:0}.pullquote-bg{right:0;width:calc(50vw + 28.57143%);z-index:1}.pullquote-body{padding:64px 40px 64px 0;position:relative;z-index:3}.pullquote-quote{font-family:Hind Siliguri,sans-serif;font-size:32px;font-weight:700}.pullquote-citation{font-size:1.125rem}.section{overflow:visible;position:relative}.section,.section-bg{background-repeat:no-repeat;background-position:50%;background-size:cover}.section-bg{display:block;height:100%;left:50%;position:absolute;top:0;transform:translateX(-50%);z-index:1}.section>.container{position:relative;z-index:2}.social-icons{align-items:center;display:flex}.social-icons>a{aspect-ratio:24/24;background:#6c757d;display:block;height:24px;width:24px;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-size:contain;mask-size:contain;transition:background .2s}.social-icons>a:active,.social-icons>a:hover{background:#212529}.social-icons>a+a{margin-left:32px}.social-icons-facebook{-webkit-mask-image:url(/images/icons/icon-facebook-gray.svg);mask-image:url(/images/icons/icon-facebook-gray.svg)}.social-icons-twitter{-webkit-mask-image:url(/images/icons/icon-twitter-gray.svg);mask-image:url(/images/icons/icon-twitter-gray.svg);width:31px}.social-icons-linkedin{-webkit-mask-image:url(/images/icons/icon-linkedin-gray.svg);mask-image:url(/images/icons/icon-linkedin-gray.svg)}.social-icons-linkedin-alt{-webkit-mask-image:url(/images/icons/icon-linkedin-alt-gray.svg);mask-image:url(/images/icons/icon-linkedin-alt-gray.svg)}.social-icons.size-small>a{height:20px;width:20px}.social-icons.size-small>a:active,.social-icons.size-small>a:hover{background:#212529}.social-icons.size-small>a+a{margin-left:16px}.tabs{position:relative}.tabs:before{background:#fff;border-radius:7px 7px 0 0;content:"";display:block;height:8px;left:1px;position:absolute;right:1px;top:68px;z-index:10}@media screen and (min-width:1240px){.tabs:before{top:76px}}.tabs-body{background:#fff;border-radius:8px;border:1px solid #6c757d;box-shadow:0 8px 20px rgba(108,117,125,.2);padding:24px}@media screen and (min-width:980px){.tabs-body{padding:32px}}@media screen and (min-width:1240px){.tabs-body{padding:40px}}.tabs .nav-tabs{border-bottom:0;flex-wrap:nowrap;height:76px;margin:-20px -20px -9px;-webkit-mask-image:linear-gradient(90deg,transparent,#000 20px,#000 calc(100% - 20px),transparent);mask-image:linear-gradient(90deg,transparent,#000 20px,#000 calc(100% - 20px),transparent);overflow:scroll;overflow-x:scroll;overflow-y:visible;padding:20px 20px 0;position:relative}@media screen and (min-width:940px){.tabs .nav-tabs{overflow:visible}}@media screen and (min-width:1240px){.tabs .nav-tabs{height:84px}}.tabs .nav-link{align-items:center;border-bottom:0;color:#6c757d;display:flex;font-size:.875rem;flex-shrink:0;height:56px;justify-content:center;padding:0 12px 8px;text-align:center;white-space:nowrap}@media screen and (min-width:1240px){.tabs .nav-link{height:64px;padding:0 16px 8px}}.tabs .nav-link.active{background:#fff;box-shadow:0 -4px 8px rgba(108,117,125,.1);font-weight:700;padding:0 16px 8px}@media screen and (min-width:980px){.tabs .nav-link.active{padding:0 24px 8px}}@media screen and (min-width:1240px){.tabs .nav-link.active{padding:0 32px 8px}}.tab-pane pre{background:#212529;border-radius:16px;color:#fff;padding:24px 16px}@media screen and (min-width:1240px){.tab-pane pre{padding:32px 24px}}.trailing-link{align-items:center;color:#212529;display:flex;font-size:.875rem;font-weight:700}.trailing-link:after{background:no-repeat url(../images/icons/icon-arrow.svg);background-position:100%;background-size:contain;content:"";display:block;height:12px;transition:transform .2s;width:20px}.trailing-link:active,.trailing-link:hover{color:#212529;text-decoration:none}.trailing-link:active:after,.trailing-link:hover:after{transform:translateX(8px)}.trailing-link.span-full:after{margin-left:auto}ul{color:#495057;list-style-type:square;padding-left:1.25em}ul li:not(:last-child){margin-bottom:16px}ul li::marker{color:#ff3939}ul.has-separators{list-style:none;padding:0}ul.has-separators li:not(:last-child){border-bottom:4px solid #f1f6f9;margin-bottom:24px;padding-bottom:24px}.bg-gradient-secondary{background-image:linear-gradient(58deg,#ff6443 3%,#fe561d 24%,#e32f0d 93%)}.bg-gradient-light-orange{background-image:linear-gradient(90deg,rgba(255,203,128,0),#ffcb80)}.bg-offset-right{bottom:0;left:-24px;position:absolute;top:0;width:calc(100vw + 24px);z-index:-1}@media screen and (min-width:1240px){.bg-offset-right{left:-96px;width:calc(100vw + 96px)}}.bg-inset-right{bottom:0;left:40px;position:absolute;top:0;width:calc(100vw - 40px);z-index:-1}@media screen and (min-width:980px){.bg-inset-right{left:96px;width:calc(100vw - 96px)}}.has-border-left{border-left:8px solid #f1f6f9;padding-left:16px}.font-xl{font-size:1.25rem}.font-lg{font-size:1.125rem}.font-sm{font-size:.875rem}.font-xs{font-size:.625rem}.font-weight-semibold{font-weight:600}.display-5{color:#212529;font-size:20px;font-weight:500}.display-6{color:#212529;font-size:14px;font-weight:700}.text-decoration-underline{text-decoration:underline}.text-upper{text-transform:uppercase} \ No newline at end of file diff --git a/website/js/main.js b/website/js/main.js index 9466b6849ba..97bb490d9f1 100644 --- a/website/js/main.js +++ b/website/js/main.js @@ -1,158 +1 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ "../../website/src/js/components/case-study-card.js": -/*!**************************************************************************************!*\ - !*** /Users/cody/Sites/tech.clickhouse/website/src/js/components/case-study-card.js ***! - \**************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -eval("function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nvar CaseStudyCard = /*#__PURE__*/function () {\n function CaseStudyCard($el) {\n _classCallCheck(this, CaseStudyCard);\n\n this.onOpen = this.onOpen.bind(this);\n this.onToggle = this.onToggle.bind(this);\n this.$el = $el;\n this.$el.addEventListener('click', this.onOpen);\n this.$el.querySelector('.case-study-card-toggle').addEventListener('click', this.onToggle);\n this.open = false;\n }\n\n _createClass(CaseStudyCard, [{\n key: \"onOpen\",\n value: function onOpen() {\n this.open = true;\n this.$el.classList.toggle('is-open', this.open);\n this.$el.classList.toggle('is-closing', !this.open);\n this.closeOthers();\n }\n }, {\n key: \"onToggle\",\n value: function onToggle(event) {\n event.stopPropagation();\n this.open = !this.$el.classList.contains('is-open');\n this.$el.classList.toggle('is-open', this.open);\n this.$el.classList.toggle('is-closing', !this.open);\n this.closeOthers();\n }\n }, {\n key: \"closeOthers\",\n value: function closeOthers() {\n var _this = this;\n\n if (this.open) {\n document.querySelectorAll('.case-study-card').forEach(function ($el) {\n if (!$el.isSameNode(_this.$el)) {\n $el.classList.toggle('is-closing', $el.classList.contains('is-open'));\n $el.classList.toggle('is-open', false);\n }\n });\n }\n }\n }]);\n\n return CaseStudyCard;\n}();\n\ndocument.querySelectorAll('.case-study-card').forEach(function ($el) {\n return new CaseStudyCard($el);\n});\n\n//# sourceURL=webpack:////Users/cody/Sites/tech.clickhouse/website/src/js/components/case-study-card.js?"); - -/***/ }), - -/***/ "../../website/src/js/main.js": -/*!****************************************************************!*\ - !*** /Users/cody/Sites/tech.clickhouse/website/src/js/main.js ***! - \****************************************************************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _components_case_study_card__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./components/case-study-card */ \"../../website/src/js/components/case-study-card.js\");\n/* harmony import */ var _components_case_study_card__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_components_case_study_card__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _utilities_equalize_heights__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utilities/equalize-heights */ \"../../website/src/js/utilities/equalize-heights.js\");\n/* harmony import */ var _utilities_equalize_heights__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_utilities_equalize_heights__WEBPACK_IMPORTED_MODULE_1__);\n\n\n\n//# sourceURL=webpack:////Users/cody/Sites/tech.clickhouse/website/src/js/main.js?"); - -/***/ }), - -/***/ "../../website/src/js/utilities/equalize-heights.js": -/*!**************************************************************************************!*\ - !*** /Users/cody/Sites/tech.clickhouse/website/src/js/utilities/equalize-heights.js ***! - \**************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports) { - -eval("function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\nfunction _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\nvar $allElements = document.querySelectorAll('[equalize-heights]');\nvar groupedElements = {};\n$allElements.forEach(function ($el) {\n var group = $el.getAttribute('equalize-heights');\n groupedElements[group] = groupedElements[group] || [];\n groupedElements[group].push($el);\n});\n\nfunction resizeElements() {\n Object.entries(groupedElements).forEach(function (_ref) {\n var _ref2 = _slicedToArray(_ref, 2),\n group = _ref2[0],\n $elements = _ref2[1];\n\n $elements.forEach(function ($el) {\n var styles = window.getComputedStyle($el);\n\n if ('none' === styles.getPropertyValue('display')) {\n $el.style.display = 'block';\n }\n\n $el.style.minHeight = 'auto';\n });\n var minHeight = $elements.reduce(function (max, $el) {\n if ($el.offsetHeight > max) {\n max = $el.offsetHeight;\n }\n\n return max;\n }, 0);\n $elements.forEach(function ($el) {\n $el.style.display = null;\n $el.style.minHeight = \"\".concat(minHeight, \"px\");\n });\n });\n}\n\nwindow.addEventListener('resize', resizeElements);\nwindow.addEventListener('orientationchange', resizeElements);\nresizeElements();\n\n//# sourceURL=webpack:////Users/cody/Sites/tech.clickhouse/website/src/js/utilities/equalize-heights.js?"); - -/***/ }), - -/***/ "../../website/src/scss/bootstrap.scss": -/*!*************************************************************************!*\ - !*** /Users/cody/Sites/tech.clickhouse/website/src/scss/bootstrap.scss ***! - \*************************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (__webpack_require__.p + \"./css//bootstrap.css\");\n\n//# sourceURL=webpack:////Users/cody/Sites/tech.clickhouse/website/src/scss/bootstrap.scss?"); - -/***/ }), - -/***/ "../../website/src/scss/main.scss": -/*!********************************************************************!*\ - !*** /Users/cody/Sites/tech.clickhouse/website/src/scss/main.scss ***! - \********************************************************************/ -/*! exports provided: default */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony default export */ __webpack_exports__[\"default\"] = (__webpack_require__.p + \"./css//main.css\");\n\n//# sourceURL=webpack:////Users/cody/Sites/tech.clickhouse/website/src/scss/main.scss?"); - -/***/ }), - -/***/ 0: -/*!*****************************************************************************************************************************************************************************************************!*\ - !*** multi /Users/cody/Sites/tech.clickhouse/website/src/scss/bootstrap.scss /Users/cody/Sites/tech.clickhouse/website/src/scss/main.scss /Users/cody/Sites/tech.clickhouse/website/src/js/main.js ***! - \*****************************************************************************************************************************************************************************************************/ -/*! no static exports found */ -/***/ (function(module, exports, __webpack_require__) { - -eval("__webpack_require__(/*! /Users/cody/Sites/tech.clickhouse/website/src/scss/bootstrap.scss */\"../../website/src/scss/bootstrap.scss\");\n__webpack_require__(/*! /Users/cody/Sites/tech.clickhouse/website/src/scss/main.scss */\"../../website/src/scss/main.scss\");\nmodule.exports = __webpack_require__(/*! /Users/cody/Sites/tech.clickhouse/website/src/js/main.js */\"../../website/src/js/main.js\");\n\n\n//# sourceURL=webpack:///multi_/Users/cody/Sites/tech.clickhouse/website/src/scss/bootstrap.scss_/Users/cody/Sites/tech.clickhouse/website/src/scss/main.scss_/Users/cody/Sites/tech.clickhouse/website/src/js/main.js?"); - -/***/ }) - -/******/ }); \ No newline at end of file +!function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){n(1),n(2),n(3),t.exports=n(4)},function(t,e,n){"use strict";n.r(e),e.default=n.p+"./css//bootstrap.css"},function(t,e,n){"use strict";n.r(e),e.default=n.p+"./css//greenhouse.css"},function(t,e,n){"use strict";n.r(e),e.default=n.p+"./css//main.css"},function(t,e,n){"use strict";n.r(e);n(5),n(6),n(7)},function(t,e){function n(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,o=new Array(e);nt&&(t=e.offsetHeight),t}),0);o.forEach((function(t){t.style.display=null,t.style.minHeight="".concat(r,"px")}))}))}r.forEach((function(t){var e=t.getAttribute("equalize-heights");i[e]=i[e]||[],i[e].push(t)})),window.addEventListener("resize",s),window.addEventListener("orientationchange",s),s()},function(t,e){window.addEventListener("load",(function(){if(-1!==window.location.search.indexOf("gh_jid=")){var t=window.scrollY,e=document.querySelector("#jobs").getBoundingClientRect().top;window.scrollTo({left:0,top:t+e}),window.setTimeout((function(){window.scrollTo({left:0,top:t+e-40})}),50)}}))}]); \ No newline at end of file diff --git a/website/src/js/main.js b/website/src/js/main.js index e86e5bda09a..460cbcc4602 100644 --- a/website/src/js/main.js +++ b/website/src/js/main.js @@ -1,2 +1,3 @@ import './components/case-study-card' import './utilities/equalize-heights' +import './utilities/greenhouse' diff --git a/website/src/js/utilities/greenhouse.js b/website/src/js/utilities/greenhouse.js new file mode 100644 index 00000000000..0b87d1a937b --- /dev/null +++ b/website/src/js/utilities/greenhouse.js @@ -0,0 +1,16 @@ +window.addEventListener('load', () => { + if (-1 !== window.location.search.indexOf('gh_jid=')) { + const scrollY = window.scrollY + const offsetTop = document.querySelector('#jobs').getBoundingClientRect().top + window.scrollTo({ + left: 0, + top: scrollY + offsetTop, + }) + window.setTimeout(() => { + window.scrollTo({ + left: 0, + top: scrollY + offsetTop - 40, + }) + }, 50) + } +}) diff --git a/website/src/scss/greenhouse.scss b/website/src/scss/greenhouse.scss new file mode 100644 index 00000000000..710b606fa15 --- /dev/null +++ b/website/src/scss/greenhouse.scss @@ -0,0 +1,27 @@ +#main { + padding-bottom: 0; + padding-top: 0; +} + +#wrapper { + max-width: 1078px; + padding: 0; +} + +body > #wrapper > #main > #wrapper > #logo, +body > #wrapper > #main > #wrapper > h1, +body > #wrapper > #main > #wrapper > #content { + display: none; +} + +body > #wrapper > #main > #wrapper > #board_title { + margin-top: 0; +} + +body > #wrapper > #main > #logo { + margin-top: 80px; +} + +body > #wrapper > #main > :last-child { + margin-bottom: 120px; +} diff --git a/website/templates/careers/greenhouse.html b/website/templates/careers/greenhouse.html new file mode 100644 index 00000000000..e4a4b3aba4f --- /dev/null +++ b/website/templates/careers/greenhouse.html @@ -0,0 +1,8 @@ +
+
+ +
+ + +
+
diff --git a/website/templates/careers/hero.html b/website/templates/careers/hero.html new file mode 100644 index 00000000000..dd4e59aeb3a --- /dev/null +++ b/website/templates/careers/hero.html @@ -0,0 +1,10 @@ +
+
+
+ +

+ {{ _('Careers') }} +

+ +
+
diff --git a/website/templates/careers/overview.html b/website/templates/careers/overview.html new file mode 100644 index 00000000000..1601bf4f4b3 --- /dev/null +++ b/website/templates/careers/overview.html @@ -0,0 +1,11 @@ +
+
+ +

+ ClickHouse is searching  for individuals who are not just knowledgeable about what they do, but want to learn more. Our ideal candidates are thinkers and doers who are not afraid to take on various roles and responsibilities as they grow with the company. If you are looking for a place to build something new, be an agent of change, and have an opportunity to have a significant impact on the company’s success, this is the place for you. +

+ +
+ +
+
diff --git a/website/templates/company/team.html b/website/templates/company/team.html index 8b4c4e26774..cc6bb75e028 100644 --- a/website/templates/company/team.html +++ b/website/templates/company/team.html @@ -322,7 +322,7 @@ From 9ee6e59f979bfd01cbb61241e9e48308c55de467 Mon Sep 17 00:00:00 2001 From: Cody Baker Date: Tue, 12 Oct 2021 16:25:24 -0600 Subject: [PATCH 256/264] Update team photos --- website/images/photos/anne-krechmer.jpg | Bin 0 -> 22606 bytes website/images/photos/claire-lucas.jpg | Bin 0 -> 22886 bytes website/images/photos/mihir-gokhale.jpg | Bin 0 -> 25840 bytes website/images/photos/peter-fenton.jpg | Bin 19254 -> 12028 bytes .../{richard-raposa.jpg => rich-raposa.jpg} | Bin website/images/photos/shavoyne-mccowan.jpg | Bin 0 -> 27762 bytes website/templates/company/team.html | 66 ++++++++++++------ 7 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 website/images/photos/anne-krechmer.jpg create mode 100644 website/images/photos/claire-lucas.jpg create mode 100644 website/images/photos/mihir-gokhale.jpg rename website/images/photos/{richard-raposa.jpg => rich-raposa.jpg} (100%) create mode 100644 website/images/photos/shavoyne-mccowan.jpg diff --git a/website/images/photos/anne-krechmer.jpg b/website/images/photos/anne-krechmer.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1333ec4774b3f79a32627c29833097d18582e632 GIT binary patch literal 22606 zcmb4~Q;=p&u&%$hZEM=LZQHhO+qP}nwrykDc2D;-&ip6#jySic)@4RkRIG}uwch8g z{Mq<903b?mwj0RjHS z{+}S=zX&MU&lUg{1PB0(2!i-8t*l7n&28H@3?JZ-ece<*QIex0 zN9Zt9Gh1w1l}K1cCJx>Xnx>fzwprLHHoL7!BPbh2SAP#szN|}*?QQG+H^;iYZESO! z+rS1k_Q@v;c1x( zYlfJ7L1ik~jSpZeQ_-Z83}|#taZ4M&lbe6}#`dcEtN3|=VdTP%&r_qiukfU?+ z4W0mrPg1MG!>{qeZLhX&%eHRY_O>@2pl&W=WR0Mu@6!c=Nfg{^%o|XYlY|>$lAG?q zvLM5BUE@W+XHq#kGuoNg7t7H!%~=_>#;TGM5dIcz?~)x|_^_?py2)+Z1_2e5I_`;N zQf(*>2&(J2EneKg0zV+PppKfSYeFP9wWux+o(yr!sRd>^8&fayn#J+K!K9`pCJV}< zh5_!rq$@7lx;gAoSJ(kpIXVZF%7uXwGRk2~^;XRmCVgXv<~J?%2$03#)*Vh%Ue_~} z7?*cto&VmZZB<;s#aLzimHE&zI@E^N`U6;P+1@s>mAb^_=SA_XYnk3=dO8Uu5p2Mk zJ60qlTMQZ)oHF%b2!cFdXRErF>NZPHbTj;XA z&e%41K%sGTB?_hpxK?terIw&|}?OgpESwSF2_X*P&3^c805~oE2^QTJ6$f# z#B_AvBHhMF7MLZb2iu~@SaDUOSUz)I-ku60SD-*@p&9zPOr(vcE~%sIy!qB`OkeM$ zgCAa0EB7d*NI@Ia7(f}01`Zqr=NY;-put)``}&U+}Q zXw&#$=owsgL1riW@Pa2nkLumPAkQ?4mITJEH~pd=HgVGJQgpF5&o{O~EEsOJ)*m}u zc}?{+M{9Gyu=PwQQ;Nteo(!d?Jl9!F+9{yR8Bp|vtI)(2Y7&+PZ-G$as-l~ymWZdW zPfANI6mf;eXL)|p_qL%pY+#TJIVs3ggK)KY-M*Qd$F%2|G9)FMeKJNcuofj9%3|5h zfG@2|(Uw#2ZL)84cnZj1+bu`v_HzxF8*>LW!%9B7({hF;Xb)SkV|D!iFodAjL+Hho z^_4C=ERuCuO(S4cJSINF;uu;BR*4yc?y+|Ub-+#Z3dkUE;cCg@xZxUzBHrS=2pJ?i z;>8L!xmgv2+t=`D13P13@~VA&p(RZvT+~?!q~}XNlI}!Lhxis(JK;w7K^K8e!r1iG zKzA;~l%&*lDRkkPJS~=L@lpbj$0kLpouzrMpgGP`q9jw&MfqwjZEWXE{KohkscjLWW_)x^N$A5Q)Z~;HcIDP}T`$0Bxozm;s}PJX zRL;AeyQ-grzdmiW?wRDYTIK459cI|%m3SUgqs;J{G_v2}NX43%o|6J6)O-E%r9_Wh zlN%FQBE#cg1R>pvlPZCK)vu@v9Tpkgd}CcS)Zo#T#(h(ampUlHztt~+!_cy<B z>IA1;sPzrG9Om7jVu^}pmod)fS+#H5V}6iifyg|$u1eb%mpH>-2s=oMKhC# zueAa`wDd$M^db-)_VnU#e5QNaB;z$oYCS6-wd_M!9p+0CKECZL^^RxNhmYzes+OAV z8rb0H9hPX3ZO;x9XqTXQb{sCs*>oLFAwZSDk=(M`obFESug>qX-KQ*2G3m_8x~7h= zBEXP{SS87>py>5Jcld%_VO*tzW8JfB1Joa@DPGoz)UaiCk#*$^%gRovz}I0pX(mWN zJk`XNsZ{k&MsroO{Up$;`#$CYj{A7gO}=?ii%YOHG1kI%aj`96Z0SV)j&+HML5Gp!!D((gBsxPA^aTYK7ML5KyQR zo2yj!kYUM!xacO|&-w9?W;#xrP*tyaGF&dl{Po0O!D}UO6Se2Ud8i85aTjh#E8$M)$83Cth>hmOovW^zr)l1#Uc=c( z&qEdQO`UpN#UdlVV(q@uD_kh4LG1Lhc4M&SgUc68QvIQ02WVU0xwDI`tZ?fd#hf0{ zXkH{!SEjpx1KEq){`+ZFrx)|`tiz0|Lr+(bb+kdY2!SvvV_WLtw7HwpT6A5-%TuhN z^NyQJ#$NvvK{VmQRY}lPW7#Y2(bTNJ71sRvqS_9Gerovi3fZIu2wtbfhAvK8i7O+t z#NBC=NW{^NPSuyqV|s5Q;%d~;?cu$y+KM4AG?nY{O(z!jGr3vah z=`k79GWA~>G%a>gRTQIwo!FWe@rGZ81?f zSEUH)b_6npY&&bmf>LO88xXdKIj-8HONsH2EHbk5vT-j@>$Qc|?I!1%36^I)hf7>? zB$!cy;53Tspe4`G*fo8jyXs@(;iTQ3ig_CFUyh$MG3)9s8BI(_{c0MfB-?otIaimO z#$}K{JS9`DPp+EY>Gj*V1UgnzO0wtbxr~xUWfy7H6wZ$XsTjb#y3|4g>N4_czSDIz zWy?vbT!-pgFu?FTx$U7=rs)_k<0$x~f{4m;MnNwwb|Caw9sQJSv^=|L<>cZVn({?r zi3qrGhI>mjn^2_?i9dQ!&E;_oouZWLrCeak*Jq8Gz95m{UAIlAe=4upOH{JJl* z8@Fo4^n{+lC>A$ZoPlrCz^e^+2_$u z6_RIcDVcPxqUw2Y=9{zTTwkzJIq`kd2x%Yh)$TDO)%@heuBC9P6H5V$Y0?73T@zG< ztGzkVy13U8vpv40+PKTMPrP74s$8A3VexEvP;ObX#8JzMQ`$ZL_3i? zd{4~5MIQ<$L(R7P5EyE>l^t@nCvh#cB3{fC@=+LGtsWOsB1plq>c3KQ~~pYj}(sD;u8czPGEcq}>{|tXAJRSN=<)*fVCL#;^?=Sx3ys zv0BH(PflrELBT_qz=2CggMU_%pGtlEaDj^mPcv@L(>vBYGx+p=ouR@GIOY&?=6 zE^|pqYy#HnzItFY`KuT_);x=Wyx!NIi zG%8#iqb2G|<2{shTAsk_$Q^`b#i7$;W-j%TMsi(OTk7MKUaRwjmUpdefQ+tP=ER9= z_!#~G5?pF=U}91d8m-5}aW+bHfd-CN_)EtJXt|G6h2E!|pk=lvdw*LVZ+gtg@hYe> zs)nH1XQB|#oM%$7yymet%0k7y#7~L_^ov>wyj)CiSoh!+dT33noiT~>Bh=BqizZV z@jP&G1j*Pf%-Ca8dtp6O-2+Ew~ytJq{tt(n$k>#ZaU%$X?JfQZy#6|HJ*|KX`}r)>ML zbjRLb5g;v2I(h9VKI~_s*hQ5z7m;s9I>LN0wk$=atsU|`79OnXmBZkXh4mCx>PJQ< zL6SKu<^-Y~>G*M{SEG9@*44O5F3nZG9MwjtDF9k3XV45^899m}Y`xJ=P~6?P9SiFI zVt*P2(iE4O8Ml^kc@7O#V3|#FqiVlqEdXwNYVEU{qGGgp=L4(Ym$tMOR7kyYF{i>0GN^ znsrrw`9tc^tg{}@GoQK9D|Z_=k^$-quL-&L{+R1+oiK6z>Nfa8b~Au zC1GLalt%kP~k~_Y*in_{mtxX5NK8*a<#5iYS#I_BPHT?EN(XPT|VQWH>0&@vPG_p{gaL z9f4qqBY0K)VIMYE#7Z(8N1un^zd?DoH(DJv#M*Kt&chYBh+>&7J~5xk2y#ktxvQzh z@>e3-(U@Q`G`QZq^7flkO_NZi?eDd5fX&PP~Ja zREFZw!+?LI@JaD((7CZkcIVLUFJ9c9R8OS?M$^h%=SBHA&o`^zO;%U;NoU?Q-_hjseCB@>&^?ZS$yTsfunhmoTB&j6?AQ?N-@7%=fV|4!`wXu?Y6u- z;v{72OT*D-Oez&t`;r5jub%(QmDU=08>uREPOYC7?*(M5rz5SV_(FmAWehUNgR?Il zflG3Px%#s+&D_g9!sf8KpU$bjUDi9LvRL#~ORsx|$bV|m(awcEFFEDgicVFvpC|Ul z+yYD07Cl!u2m|z?Z;s*3*-h@AxDKIIm>N$%3Y000PD($XjVp|A-maHPM-zUzrd|`x z?N*tO&ciKReR$1#_AsS&83lSj)-z-MNH~W%0V|8<1jZ7+?V3!^?8oD_452L3)3vsHe zHHIo+@w=zPY2Au*Ir9*pjG|c1pE5b2q{XtYVV2EpO@>^Hb2vRw<&E$r841@lIAI%4 zmD+rMec}X+MU%RniecAOUix^FDrc|;l~0OoX-^ZG8vfW^#1W`tYf1gp zL(wwI)57tavRXm4)S4m|n~lr%kX1mA2n3rbFx;}sd~>T4cjXjKeCutvP?6&^k8=eA6o8DXB zFm@Vk!xKZpaeG}`ER2QNr$yRM*b`N(@%FgHLMg)to6F|I<0Igr=b9zo!stW5>-_x~ z^$;6N(Iz`zZnSlfX5IlhQWqmkPR!~NJD=2AeW0`OKiXjgD8U=dW?v213 z6mff-WYdnxTtwT7a;gPV@VchxBxqp5ieflYU0&%@rM+sZSjnyku-xn{+`WpN@#=!5nRC}X!(iWTLd#-S#%~tAIort3!&+0+LlrEqi-Z2om8yV?O%hJQp zqTCn8W7;1P51%#ckMm9Qi#)1*&8X*9{kr#aL?D9ZfLUW)R}cIJKf9Aublg_wfR4sqZmUqL$RSJzJV*H83$xX1?oPIn6r@=KD zSYZ!KHDXup92RoR2NL{D$;dS!A`M)Hd1F4_vXCFZxv`X7?%?fUl^DjIYUl`+H#@?1 z7q8&5>z#g%s;d&L8eLoeF|Jtf)b@cB3b+3E*5Vl^<9ocqda@Yu&erID=Bmh~UWGBx z=h0T3i1vu4Svk^nYN^#S9g(8>FG0+!PMEjza!0@IjCm*H0G-`7=E1G<QQ~1+AwxY>RfBqJap^Zsza=)qht$9-NyLEQ-y{0j7_y& zyP-cT38z+D3b&={>FI04$2F;WT9+!qbm!5>gDA9{RXMq`j%baf082VUOFf_h7s@E; zK^{t7NO8saBr&;MYl&H1pWs0pSGSX|?DKVE{En#zJN0XQ%xhb|S37E(*jV~gF0kNH z=F<=vKLABEFEDs)>Sze^f?DPZeLNAz(Du!{kGbX%+;{6PM}{g-do!c$zuTebtFR{9 zc+nH)ORWrEEx0rUp-r4+{foACdD-Og1*_E6W;P~lTmN2zf6Z67dmG7Yz414BJGfC4 ze4MINOz1HTrOTNjKJA1HDwM?#f?PRv7WXBEZE^j$ZZH2DmT^1sCULKGTw^6Q+ZZ3O z&v0?7n-rMyqvi2H!JcZJdQqfY31RTB$o=@`>QBASHL_*KdDU)OJ#Q4YXJIA+TZ(q$ zX@hp`8Q5%ER41oX<8qwc$`$MUgp6ob`=yTzx$@6C%PojH))w2};(Rn1Nx3?Hwfs)a zPN;l0JaBSsbiQaNaZvG?e{$*lPgG{rw;cDix^%Y2*iu%zDtOhbdxdC_S3p^a^j0*j zOt5(hldKIL(d>5`{AIf)egGbKX8k_Z2+|C)SjSIUuz%*}m$TaGwxzX~dnI;QvtGdp z=f|DJ^zij;wSZ4O7NVsO1`$;eaATNR88?f?j@ER#<1ksZBgVEXrn%MOQMEugyFtowC}mb&QDW z1WHVR-}NJHUq~~6ADn4Y2T~;>^NPl6Xxj=X&h0d$!(L|F!SZTqi|UunxlBn*u+^t7 zA23zi8d0NM3*5_D`~X~y7a5%CD&~{b%j`dKG(qpGE2&PEFcwLuY_%OG+EwUCbEn|6 zNlZ4dLbU?W|H?kC>gwiiZE=E`knzc)yQxlsGj4Y?jh{dj=o)#mLMnm<${I4^Q}vEa;J7u; z@u8)VSW>->9G#My2u`?mPB=6Rm{qQ>-LW3KYj2Ew`cV69YH@39-{8IU&boTXEoyfX zKlv?~dpIMY+;gv*TA2^OMt0w8Wn!IHuH$m}Qm&jxf2ldeZTbUX*Kgj2aS+%snWkQK zH&>=9w$9KMttxZqhOHX7(UQSH5$%L(2r*f9OO3Hy?uW&}r{0LC$iUO11T~3%z1C?~ z?+CiRo$d(APl_GaR0`}@<5sH`ADlK@5MkX$Vn^Fumo+gXtBs%tTBm(RI#QmgaTN8E z$%LI|nOAXzb<3-K57l*mEfqiJ`wZC{*f|(hXY7yC%|vdFwwhEY3`nrNweCS!tpOkZ z2Ym$oK_4JsP%vN+aFBo2_CLQG2p9l@giORJ2#P|iXvidlsN{%BND`P>$iQp_ChQc{ zIH;V|w21bLrRe_Q@qaiFI6u%gMRnBiwSm`(?(1j?7Fqh`0+d`9Jy*iyMqK`siWTfs z%k0D!ADK#NOZo6`F$j~K0EYe3cvX)AE1&XZMmAY%4@UG*Lfts`pl)Cu8=|^ZhYmJ$ zPAo+x9>&S!o_ay6)Ux41KViPv*EUr7E>c15JltbgLG3WtTE*UBiWS616`$rG0DP5W zR&2FE51!K;Lb(OU{0%OgwgFohV@9@zs_gU$JhmMwf|EbSDhn&Z6d4~yGf;+b3(F8! zX*2IBI3COewzRSj1zU)b5&UwtJhf+7c8+oL6$98wJaQ^(l|@s-C0;2s>Ls<3Hmvua z>Y+uj;#ifpdrF5_Kw#YUy=tLi(7vU9WbL1buYz(_?X+6wz2$If=^V)OHWQIj=}^}q z*^joAD+Re0^s3y?85L@S-xM#f;JglwGZa{XHWT-AK7x=1N5f z>3=+D>@I^RLpgki!h4&)%6#+)s2QCz19mWxyLZKs@#|b#=B~}(0z7hApRSKkk17m# z#}ZnRTTxE9hE!vj3}B@ai|G_)y^RdRv-tOXv%(Q&OvI=Ms&)zVqvhAOt8ZRL@JkU$`&T=0_WEZlLfATCSq!zYT04_sBG z>JtdTh#&1|9KCBxI5w&>Y^BltLtW6P1_e1=W!O3Xh$~|g$@e>rpC^k5X9?+$BXG9h z2;T)tww9gkFYm>w z@A-fJ=&0frJwn`yoWI5jMH|6ITQdqwFa(MOz)%0+)P{SkT=EkI;g<%UZs{d+Bj0bx zv1$8Mr*x?oTqr}0{2IC|Yqvcd(=$)kDtoS69nUl`5BUg<_*pY9+gKif+GJZu<4A8z z2RewGJ@X}z6P3#{SG-bjD~*h}G$bl>>%pi&E7Fhh%}_0$)S0#;wNj}vR|FBowVj$7 zo<5v(S+UyNm>%V2@oQL<3c3<=zSUuMMO#XNxh~Oq{j3xMX(^YqOWzQG;4?u^m$|OY znVM_Ve2F~+=(cxbBP;9Q=+4Ni{V~eF(BIQ=&NyS~rQ%4wlvX|bmrNHK>9ziZ9A*S> z{k?ggi^)Ic{vx_%qH+yP(SekLQN!_BM*c`vFevx+zJXC`?7Mfs_2OlhmvvtlR;x!I zio~XS$jb-+0hkG1_Mmxqb>wwCzXnn{vZApLWzERyICB#yq*hjkqt4cYcx)dAm7}ku zx?$~+3gJ%|^84Mt-Eh8qD9=z1DUbQNamwhZqr|$Gv4n&1{7p+E8}H%i${2Sr;Cc^> zTc3~_BVcIC4rDVtb-`^{W~AP#+cRuv#4ovHzLfv?cZ~L8bL{Eu3TxoO<;eLmhBdq( zWI+cnZN)8xBM8g-HI8Ep13!-|$e!Tigj7ABAGKlUZR~)k3E`Y*%06@*a%lS;RLL_~ zC$>OorBk+a!w&ztO_gUOm)Z?rkxu^@? zcyN7K>DOYcdlR3b7S&THi^D$2TT=#5=l;l0`8oJgw!ZY7Dn3>f;b#a>pj3VkPzXD6 z_yAj44dy!oQ`boj*xrE5scI&|k{@YQPNR$uugi3|DJSbdx%!vsI-&WCh*tLbZgKGp z=#Gu~bIb9{+!hbZxf9XNEa?jhTp&MLJ>OI3_CnkQf0*&SoNVy`XdYOlET4MWB0%2!Ck zqKwE}}4&3Kt z*apg_Pj<_4N}scp>1JjRP;E$C`ZRydfu`y1`?iLIiMF25fx|l(oKZ5sJ7siO9pcz< zWY9hcPB#x-E-F|x>_5g1ul$+TegLRea5gCIW+=!g2UaYah3Y^tjwpg)Zv+lQ;R&e8Gs!}qFdV>Lb4n>JF zu7n57OI`!JKXGATtY9);a3jOYwmxE?=BVHv_4PX~#+=4%{4LOtYp!++ip49Z*r_?Z z!asnS!g0+MypZ{fn;onrg!ckaI%Ua>OiO0;N765A8Yd8W z9tdMvPv?q>VVP5c*9;uRloR$!XT)NA=*neFg%pmMzoO95^Z0vD$)=@#_Yc`hgYn1Owl`D$fajm?86gjwm9any11d6;u@qXN+1G3K|g;uEJ^8G&IkVtodc|D1YlLCaVxoS}l}jycplY>v2g6c95R*cjzgu-3R1npI`H-?xaM zDmbHZo5QrH2nV}6P}$$f<(!5~M!QX%Lgn%=@x!@n(Hi!Nq5K@bjqHIIFehu9k*sb> zU$Lgo%+lTs6}l{p6>2ND*ziEdSo3G*N4k#;`ixaMEDN!d9~j~mwzB=wOy5bz7bQ#jz38&ldxOV)MnM^BHE}kg+>g7p}1%|J1Ci>5qw>1yWP)GPvtZW;@ zG8blWg5jPyF_F_Nuw+&+t?2Kd?m$*Zc)=gETB!;NWQs~f6!#(i4tSUk1g`}D{yX-B zjs9MknqgwgkANd1NKM-L(_7H*8EuT+ik@JkgXWj`o>Ehpeuh68Q5S>_>-acFI>c`uzNUqxJo4m$ z5GhoYGb|_;$&s!3=Tlg@giTkbQl=0t{Qjm#=f=52OO7%6BYa>wQd9u9fKHMDT2+wP zkC)4KBXjkyB}1SGQ~O|=)3zdnD|5JUZ&BNC3bBJ3-h+-z8$xnR$Bdjd=^#P?8i|mB zRjy&vloH19?1Zne!chkXW-nd#uu?6ZhD}%dpFpS$skA-bHpcXm6b+vt5?=0X`9U^j z2n|i~d|+>xw^VMurGmI}N6ObRV(o@M8c<%bA2Nk8en4^wzRUM5)Hlo_zRry)`r4-G zr7aBFLha!+YHZ;jGH_3#wvlsw6z7YDhb!1AkmqFVhbqU7{ehJC0YO$D=9`zD#Y63_ zEwl`1YW)-IfA*z^pHs!pU^{L=;A%`EZiDX#V&nJQJ&&aXuI=Id!oP~O73`7EEVa^f zPjs7mq@r)~6By#&2W)r#nLaN(Gg+ofH4>(&}0_!8kTja=E(F|4SyR>`_n0Aly7TP_A8w2pn zk%s*Fc zwt$$jhL9NF5nI(}u1RNBPxHV48jr^)4)PQzF)PMQcp4idQ-@j(tSR)%VKA znBfd~N6+tR#Iy#csuO`($y-?ns3KYMBgbKx7Sk+7{9mH;Or$F98OOqu$Um9BiZN^kS_=*vaLGMo6kpQ86~1SS&JeGh z5j=(nH*ki*x`jmAPK`M=28La8`Cb}RvdX`6KePt}7k1?gK5Z^BJ=3XxGD%MoG^AS^ z(!-B1daO!mSdgYIeU3Wb2vM?aF(jp<%C?TDdu%hcbp1z>tIoxo8=}Kc1IOHBaCPMt zFCBCwl*Av8o&;De-%{}#26g;Gr2oY1o}Jv&p2FA})jJ~ZKBdh3vVc2LZI|RP`3r&h zr$WDQz6~7w;1u$YMr6vIm){{nV_M3}t(_5R4Xsb1V%cM?^eNaO*RBzhiIU4lB{L4j>hOSORt$~X*U`4cInD2L9M8PWo*%kT2oGZFnu+hVti>p z`hj(A+dPFOCkS4V=$`0f6yM;{o*I9M_eD6RWSo_FM9j)NQ>tv7V&JXilq?nWWK{+h zu8t)*yy|lgGymPF3nz#UVVFKPFwEstX2h9H>s6Jo@eWM5a*o?=idELebmw^9fK*E4 zIXOjZ*w&17WB)N)(HBkhplqCkh7~KKM--!du3Lsjl!mC)G(f4Ue(NJMD`8Rdk_o9{ z&(O6~UYbUMw}>D}`Zd-TGK9Vw?cmgfgW%tKub}jm%!o+DqDFKtOmW%V*)wtnAYOt4 zj`mBuaHoSE?=Klb8A7n!vu92MQYsU@;(Qr$Z!ANs%+=TEV54xhXkB)KpM!ZtV+`#| zV+YmP`Ye5mNsh1TGmV^)CNV2j&>b22EN|>lh#g{STcETbKznKZl(DmPfc>!KYnU(X zai&EC+nTE2Ag7c@n>9TDeHf?|ukA<{>>V=j4+x~8R*sQ=YhdCLYrdw7j6bIxbHy`b zpuYQ5GZbm~FyfX`n~>^Jj=gGl&;2p%`}mVH)Vj{ z7)~=8*V~-oEtR^sG4Lz)NVPb|)q`f0SC|-z;U9*Q7riCt%FEuijPd`-Bc&QKqeXOE#7g^uRQV6{ zCldUfA_s}T2vI4H%ACb=iaLK|n|iRK*6vaE?@lYju3oe1p;J2)? zJEL5)sb=Z4OuL6)pr5TNm#`pTm{M^C)lyOhahsTi!^e3p)v3qMUYaqhg(H!=W?^4K z$Bq>_VJkxD3`1r^?A#D3fSW7hwi#O#n_!BT9NjhsF6^SySLRF=P0JHBQiQ06D?F&m z_2t)anvpShtVZzIzXDV+60L?ML+AC4X$BHIQ}ofJfEgN}Vt;a;ynzVw|HH$?i2r(= z{%@Dlf4xrsH9-LZkp8h@MMFo#e@M7-@P97?@*_rL{Au{6zc(EMhSPH2snW4J1Vmp` ze3BR%%2qEWlG=sQLd~5`kg$|)D__rD0zlImx)d-KkX8`IR}9JgQ1sOvD?4o3E(i{P zJ4la^wNi$Zqh65hdurX=gJ+a2WpzUf^>?LR^gK-WQP(J+gog8y7C%AScfzCvuL_X8nw}MI#@x( zc={0EDR%n%^Y};B#`{3@20`=9AsSH&uR>%}Uhv_r?*c;Nd8R;TNDy}UVmiCFta0_L z+KRr{8=|-ytslS~1Zjc}0ha2trEbJl2i>kH>{^;7Xb>&iHEq!N9j#c)LbD8@&N4h3p)YI-JczdUiF zL2}U$H@oO6#c2z6aCDy3>M@8RW}+4b*NV{gW7#ycIJ}UC+e1OiSC`^9bMojEhwooF zoME;iw)S(MFEZBJwq5*0g;M84_=r?ka}cjpW$I5k#1Y^5K7hJi);XHUcwo_HcsV9|{cb#vbkfkycsPawfH z6TYE%coM~`c9ao@AAqySFSLFTBK?c(GAc?gb~;8FBJ8LW%RYIBl!{zpCROf2?kgT+heGW5S825cXvg*VX+YRx_b(w?y9zgQ)rqD=fFP+B z!lss7rBq){%}VG*NX>>SC}Mz0ioan#U7QSMV-}K;PN5KsXbK$ZVBX3J@#r_G6S!#8 zzUcue+LJNFzn#CXXBmDG7?gGc=pj}hxlrxkR}aECHp{yjanM#ggbZ`hs+hZJ^d^0Z z3;;(adMxop!b1e4`A4|&dZHH?A|Jg`2zai`$C!{_tTYq-0Muiu>|vH6Yj5-DC&Gkk zZb>Y{vJRf5=O7k>aCl2)He$4~{6=&c&SNl*Xjf7Z@kCOJkF}a~V^!M3m@+E>iR_>v zrG%tmnvK7d9+4lNK68|TpcdFCqU(Up6;gjoaEJ-*$`V%bjSxgL3#=fLH<<=WA2QJ; zsTi%|;A+y-)%_wcNP?`%!X-t8Q=NDq-g1g<^vQheMhT5-p`|e>F^X=F<}zVP9lYR^ zRyWyk(ER&!txL+U;Tr*_4?n#4sGw>OmWVCsq&tg`ZwcA)gg6A=r22@NO{f#t=d2jJ zgu)^yq&c2+y4%7@N)i;RnDW^UlTG~ZN9q(g<}Bb1bLUOw?>;J?=b6Z1=qU{8y&qK99MVynU( zHWb;ZGS9!BQ3c*@PawJLruAXHUk45$=6f@VD76FJ2DF`5<+%2-Q^NzlcYTe5eiIt3 zN>$Yht&BR^(5=%46Q1PBpd#%zbIk)DwvfenVE5{NiRg)ft zr@eE?>R%fZ;fQ7jbpgO8{jDIR=@ zy4eJCb3Ba`SLtcC!-93@crk#K4~d}-j={|Bl|NhV)X&WgrH!KHf8jAOK?qMCNo!uc zdX97#3|`0;( z?2Fu(qn`3WGA&b45aXx3z#BfrO`mqi2kC zd?g8U^`&9mmZzWemeihvyhkiDRRw=ndfkofIKlk&7f2z`HQgMv?KyuLW}DUSsT_=g(DP@1H}3lDTU^Deh3{& zrF1=_pAJHf5aCP?)ftse?Cgm0?i;R5qo|!_1UCDIJNod za@h-0uS%L0QZFw?W88zv0VKH=4gF)$pTwXCcE2TCM{*{xc^kMdgAn&5|A{?0N>NAf z?FM=%mrdnZk5p%-B1bEXiv$P|FzE9{Pyq;DeHkE(k+(KH4&G&r8Rp4XXYp?kL=wB| zk(?w-qD*bQF|coh$=p$p5f!rleTlz#YW^1lSuPk!`c;i%8Oqqlqc|G~O$qzGP6ydL z4X6$BZL6g5NMjF(wCQPx8?{E;=h3xpnF%bZT53oFdAQQAtSWRT2#p&#!`dE3(CnL) z=81Obn8*r<>RtEZ&>FuBmw}Dg+8oKpFG3<)CgGwDArdxN*e_7sC)^ePPXL}5Vd$lx z3os?oj)XMs2X#C0x*8S=36pKlTft z4cx>!PoHCW*jUUtR3|zvR+KnW2wD9M7~dEIZVq7E4Ne{gs|5rjJi}@lA_ure$MDB` z;U!jWG?6Y`{sBC*0ngG<)2s3vp8EVk6TnqqG;GnH#?{<;&cYj-8eiCv3H;Dls_) zihm4&gnYChO}?uXq_hP?++|Hq`{{vH!3Fkk z@B=-#1LDkri)2Y72SvD;i!FPV!;MqPIx-h({x8UsC99z{*wV7LVJ*0?u~d5IQJ9BH z=zsu*;7XL&lnH6>QdqH+b76ZAEDV*8NXlJQ1$nx%&}7OpS+}A7%o}gk#pR0{5xVH( z0GI-0_)GbHTu-r{h9&AwhZj0%;QKWU-^8GITRzIMRIap2U$9ekV9qlO{9qS0F4M`Q z7fUK|sLSSUoB5%ir@3V6hq$Nn0=JVtlU+;x99k(l-K-ipm~|~jqBX9xUnxY5q?o`z;2k6KF@Sv>xl@6kh9PIbgExh}1Z}utH!5QPo)3MyFrCfDwaR z&^BI`cuLqyaL}?AlB}bxlmY1-Bxvc1Kcw1AV%~M6^uiCTEWjv?f#r&#%xl=h@aOV+Ozsmk zYXO@)@!qvfwirBL*oD0Hua#&bEpSR}C0?lc1IztqJp z+OgWA{eahaAMCCBG^vu;A5F@64DkP<^&NuD zu+PZU)kEY%ycC%lDY!$+J0cM)Q0$gDa|`j6AnXUvA&k*;A{l4}_8IJ<=^WSjz{VTd z!9kUA*I5}!D2;xJPp4{CJ6sl9jWTLy$!--QnPJ(~^_0->WZ>Af{D$7zHTyZ4BRn#v zV`V@Jn7^=CRl(K*w%KazE0`!O6;}|Og^5au%P5}+AYMq7%Dr7ml1+jr=h={`1466F zh%{(FBVS0N4#=tM8~F%pgfH0bqGfVZHJ2`WemoRXVCD0hiG zpTUUXEX9LN2E~?WoJ^zjP?r+!kL=_@k_ijEA4iFMRH0ttq0=HY1#Fu3FhICyS>NRL zB9G4|QHwm&VCp2Z7aG@X2C)8@lV9SI%g1#ORhS~6+QgXcRPPPpy%ns)?-W{W5Epq! z6*UMI!V)+};_0GQQP*M6aj~hW!D|%|J%o`i+;_ zAzDx02yg z!8jRdb@Cv+Y!qBn(B{Bl2rz*E00vN>ArPTdH^v~g7Cw=eWA$lJfE=41-bL*Rk!=XU zdows812*FLgq|3Xn;NL2=_zzfgF82+5G!CBBve+Mnt}fS zH3`zkC{#7fVN#>4cFWuIV5IgLt0O7{9BQtI{AMo~6Fz^sjow5`>6B_EYuvneNE{on z4P7Ex2|Qs92$7;fL%Xu&;!Jfmdq2#Gb|9+l+iMEZwRH*jhMLSXXNf zFr75fiOm_58g>1}aj{TfRmz%83W5^RTbt)2#;OCCtx_X(S4QJ+J5vD{vtA{nEbLMY zDeXCwwd88s0;J~-?j3hS2+us-mwLf|3_`6k{H_YuTE0cbtO!h*)%2EdP^V;})E1pb zkASbwW|N_>i7JAaQe5rM0UgJ5=2cD0z&=Y8Prs7aoN8vm-9)AuceH^VM-YGBL^HTz zHGqAMMI8?=IUGpwo?Rf@quad9F#tv}EWnu?MfGE;E9nhAn>dCzZBoB3SencSk8=Wu3)}>1=9AADT`RIaK11n%{PdK$ zoe&KyvLx|%jaQ~Z+EtO>qmRfS0mhgpdQ$7iD_eqI)g>AXw1k%7#?S1{sX+_C3X98H zN`@#}b0GDcLd2I93~UTnaF3fc!BUogwlJ!xP;wz|6~?g>gL_-RdllW4QG!(I^^9`t ztJ#o656h~9oGs0YTFdhzdo@q9q=eE}hOrq)I4l7TE#AvfjWGN~r_$p6o2r#-nLFZS z>oNfaih9IHV(L1E-kC$;7eotO9ZEM#j26Q9Trk$vd>}|L$aUE&r*g*&tP*n9o zvUCkW>42?UO^PK!f)wU1L8>4K1qQtG#t&Kf3yy__ zZP@lOQVm?Y8SaRkt4OQ`rSX-Ls)Ok%NZr{AtMs0oB*RBE_H~61jG>+E0gi^|IxP&QH4>91@h3qm0F%!*jG7Cu}LQwpTZ#^Tl|A=QJTY_^dMc0fSV^*beS zIR}B*!{D5>e^8>Y7vmck6(>X~d*&E!%6+8xz`^Q2_C%UlK@Zp_kd}b2u#Z9o!UQ$1 zumPc|D(5vGK{mGv)$HEYa za`jV~wPB-JH1NNju%5%uuWJa+XFjH^ZL*#!M0)f^J}MeIW3bx?Nx_#YfG4m8Q>o?q z05i>=&lzx0(&+SII&XU%1zYRTfNfUTcBOoUgQQ+mU~v#~+$W+AJw)J@NZ%DdWza4p z=A$~*KK zR$p6S`9~ec^Qk$05RSfRrr;%|nk3Hd0b{XPs;4~HlJ)^mdca!L5330+Os*iK!HaEW zKG^*wheRayDB}fH2uBM#%mwD-1qIf}v#8u51K?}ONDA*R$HoiTOc>e$opJnZf zI}}U#LM$V^vvfoM!~h-<0RaI40RaI40RaI3000000RRFK5Cak*FcSp-+5iXv0s#R6 z0RI4P^_aW-zIU^9)x@6<^zW+a*{{>1X3aC{?*bW^e_!UV-Ts|i;XZWN&r9j)F&fsC zx&B($?VGm)#P^~-h`Hi3qT&8p)2>{69`<~Hfju?*&aT?Y5PycW>&5GEIp=?)UVc9V z&}U2YPw>{YqC8In-AXU4F>rOC$P0cyBtO#qHXgsvd-_jbdxt6q5d%l(^Uv$)qxkP} zKg$oVog&MRSGW`L{c}#DT>D^|P+A{Aw=zbi9aq&5eH>Upx98J@4vOu(t=p#y##|;E_K* zx6{R0V=3eO2-suzead(t+mG`60e({*AQ@i@)GA#CZ1 zpXVMo&DM>6#%B60q_q(jUlQfcMcnv#r10=fFMFphJzt``epdX95d#%lF_uCLEuf7N^GgTeWHVzdIQD znzgq))L2dH>hD@-!otMNGZ)K8g2#>YcIw;ner|W4uD7SQqCDpjo0+lcG2ti4`Mv3B zEniz}YWbK?JIJ(jONptOi{^5}sPLQSsmc-qO^XB4m4BK@!tax}VN1WDwKcC6-aL>4y@$i^i56?l>)3uvd z%;qL0EWi$b4tZ}==RQW8Ojua87tX?^t4nHcpP02`e8+?ObiG|Sdwg@Ww~-jS&GSuh z*5>Y}#2GXUnN1Ix(yMou%$FAITDoh-%kzVF<|a(Ud8_B9;p=gkm!b2|)v#Zu$k?1&wpP9IL3c=Aro7^F}QA%hjJxG~X=b z*`sC@PUlaZ#_dGQuRbP{VENonrcXG*0P!+n)uU%~YaA@;{vRLXB0RRI500000000015D_6TAR<5#0#GtSQegku00;pB0Ruk({{X1}06?j31`qh} z&FOu9AIM5q+0!MLTj4Z$>DoEq$B3SG1rE0Y#2RHbKB<+R5n`F-H&V| z{w(%Dlw+nwygrJCNWv)CYjX**75NJS4_l|znu4Uv8zF-%H4~oJ$khzNgUEv+5G!1g zYLTcQL<{7B8qP*^YmD8fG;qPvc_)DSB@gmuxbGwUS0Us*+TdI|;6@3#i|6Kv@A4lw z5+D|E4a46uVov*D1r3{DC!1C#IL<;dukrvq5Q@G}4zE<5>==`tO%k=8*`{(E?vEBM zbBCUKHH=x!8g}T?8Z_ybG@J-Mobm>_u4|6C)*9xxM^_rcagLASjOQUa;Wf@MiK04V zEf{Lihps@zYlUD3&(F(Nx=2T4sK#98lEfZ!#Q@P>R0y3QTDGqknsiHTENu`yV~oad zDUN-M4Gg_(az2Ra!g4x2(^UzMma?#c%@HkI5z*n%656slXLbYtp%~~PvUQiLMiS73 zP1t4NYp05U6BJ{v8#UNlmm*7Oh?=o@u$Q$VvSR|JrYQLAAThVs-E!K|meUO}(=rJ< zfz1+-l$My{^mrTvv%(c9;wsBRJA7QR$-}`YQc$s3Xi7jp<6c_MV?A@1O9>qj@o1cM zc%ed)lEFT0V>N8SBP}z`b*={nDg~=ygk>Y*#iJcFx}*w99A)!lan}`L0@}4}gg8Pa z%LHMz5t$Eof)bjr;gvSUJmW(26jK=E6C>|M>ywM#njJVFuLSvMagmf%Ua?=)wjX({h;%?B4 zHIQSjkSG$GUhAJMw4^5qZHuN_Tf-?G6D(s0grp@VIO#@`k(Xs9Cws2(P?lr1}HSS7njmB*a@7yZxfwdwio zSTLE|mX!gBXjzbVNl=8Wv}L6yN4A)4oAE!77vjbEDfsVuJMMd9mYCR#9 z2CcZ+@i7r^?Ff9l|F^r<>_QQUs0G!>%V;OfFMF*Cy z()HzKBGW`m#!_{c0~SL-MdW4KQtjm$Iu=+SC5se>sj5b1hJ}`l#^YD-=x0{Uq{!N1 zNmUIZ4CS$q(Fsjvgk@G-l$flJhwJLf_LAz7h?2!DL~Gp;j*SxfWhZYKIIY)x?X1cR zeNs@#G1(G{5viajK-(Nv|GC@*c|Jncu0RsU8KLGcSRZmLQN-B2LU9J96 zy;OU4^!VtHSpK8OOKEPj>0`^N{mInB_S<9=+lqM@-1WrEYxba>EoMCk)rppu7LQi! zL6sLmAc6=YkJy7MA_zUoD$!hBkY%zA�>sB)xL7xW@(%9GH7L=j1>k#p{i&vrLP z=(Tz;rU~@$PieNnJ(ed&8(^K8ZgEDUsI){KZN{fh<_v6$U2c@@#^@GMdB?VMA;R7 zqYrFY*Sa1(W?DXnx%EbttWrikx}NNAeVEymjk0&OvC)C)k@XuycG|K?)N!{ujbv4a POQz``DtM4MsdxX``Vqul literal 0 HcmV?d00001 diff --git a/website/images/photos/claire-lucas.jpg b/website/images/photos/claire-lucas.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4ee456304965ed5fe23b850ba66faa822da05641 GIT binary patch literal 22886 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 ?aMLA1vXlt zVo?#{UmxO?2lcEuaf_CmLD?sly3vp#eb76o#zSZz9cFO z4wjru#z+I`l?aH;ivfdMca$}XPg%dK?|s>2RjBxsL%%#biI4M$5?NH3y)ZRff~rr- zg)XTrW(4g0ta)1PLdhKkdFq>*oQX2r7&{IdZG%f(^TT^7ZMYbXL*9iVO4qEtNBAe-kn6(~x?0 z)cV5Q@@L7s+ThhWpT{@$Mn(S?OxQ8NRO!~4u4v5ebfm_0uyEJ0R^H$vB;O>A8aCMA z2Nh5id(=7_S@$ka(mf`;A<=0bDKwkaLshE}IYy0ZdzFAE~?S$St2Rc3m( z6`90jwz?*C!ZN38r+8^uqscOAO`{3q%68iFP}jwqUC#Opmlap1cho%ScQ52U@P)v2 zAarQaXoi?jat&w3QJOVllpN*F3JRxGfcn!11xUkBQri4cnoSI%D~Jdm4VPPM9t{@> zba4|FrK-;MkI98!d+-meBLTt$=T)@@<|3u{9Xi7gCs*l5=&Lg36EZlhnRggj`miB= zIaQ-k3J0xcu^Up3-|k`kd)-MVsN=Z(T;uMXeLeN7I|qPti|1Hat64UGY6`|(bz0M- z9~@xPT@9ieI+GvFhaUHS)@M7`@r{Z@wn~ssqA-9COg;bz4w-Qu0NgD W-+LJeh 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%0D!!0@e{>|7 z8$piSyPSOlZecD?4qdbqU1OKjx&>QJU4zw(f$f-tT3Ju1j{o$pX(h?0{(Q?F{N0a4 zVp^jro!^_RTt4-4DgSjz^^BRJHYl71L~xS?VY+}{9eYh!%WP*Q3s5#x;Sf3$vIrEa zT_(9zW*KQV<*TE^ILw}?GAgV_`}Hrusmkj9vlw{;Z&i5T{j->O>6NRxDNMeSGxu17 z`MtKfD;@EOc7b`d z20vjq)%|&*EEc$SXs0h;csx-e`5FGnX*K+mdqTyg0lq0n3*h!CSQj*xiBs0u$8i86 zbZ$>PCi?oN4%D`SFLg07tphAg$FF&J84b0||Ku1F!;-%z4}7Z}ItLWOdS?cra#qpy1m(lfc*NYegl2adt$cZT7^oT i{<_h@K<(AqjtAPlr-)yck~TzI;w3T3E^UMJrT+n~XV0(z literal 19254 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

3k|*hom_})fu*z#bvD{qYhbExd9j?F&%X)_h{F# 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

  • bo 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 HTOa?~NR~Zl literal 0 HcmV?d00001 diff --git a/website/templates/company/team.html b/website/templates/company/team.html index 8b4c4e26774..fb68be6af08 100644 --- a/website/templates/company/team.html +++ b/website/templates/company/team.html @@ -71,6 +71,19 @@ {{ _('Senior Director, Business Technology') }}

    + +
    @@ -85,21 +98,19 @@

    - {% if false %}
    -
    + -
    +

    {{ _('Brian Hunter') }}

    - {{ _('Account Executive') }} + {{ _('Account Executive, AMER') }}

    - {% endif %} - {% if false %}
    -
    - -
    +
    + +

    {{ _('Anne Krechmer') }}

    @@ -140,7 +150,6 @@

    - {% endif %} - {% if false %}
    -
    - -
    +
    + +

    {{ _('Claire Lucas') }}

    - {{ _('Director, Global Business Strategy & Operations') }} + {{ _('Director, Business Strategy & Ops') }} +

    + +
    +
    + + + + +

    + {{ _('Shavoyne McCowan') }} +

    +

    + {{ _('Executive Assistant') }}

    - {% endif %}
    @@ -224,10 +244,10 @@
    - +

    - {{ _('Richard Raposa') }} + {{ _('Rich Raposa') }}

    {{ _('Director, Global Learning') }} @@ -260,7 +280,7 @@

    -
    + -
    + -
    + -
    +
    @@ -322,7 +342,7 @@ From 279936632aae8e2ecc790e3c5c1b87028e02def1 Mon Sep 17 00:00:00 2001 From: Cody Baker Date: Tue, 12 Oct 2021 16:15:24 -0600 Subject: [PATCH 257/264] Add webinar signup promo to homepage --- website/templates/index/hero.html | 23 ++++++++++++----------- website/templates/index/why.html | 4 +--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/website/templates/index/hero.html b/website/templates/index/hero.html index 873bcf9487a..79ef8974ca1 100644 --- a/website/templates/index/hero.html +++ b/website/templates/index/hero.html @@ -1,41 +1,43 @@
    -
    +
    -

    +

    ClickHouse, Inc Has Arrived

    -

    +

    {{ _('ClickHouse® is an open-source, high performance columnar OLAP database management system for real-time analytics using SQL.') }}

    -
    -{% if false %}
    -
    Introducing ClickHouse inc.!
    +

    ClickHouse v21.10 Release Webinar

    -

    ClickHouse, Inc. Announces Incorporation, Along With $50M In Series A Funding. New financing will allow the open source success to build a world-class, commercial-grade cloud solution that’s secure, compliant, and convenient for any customer to use.

    +

    + 21 October 2021
    + EMEA, Americas
    + 4:00pm UTC / 9am PST +

    @@ -43,4 +45,3 @@
    -{% endif %} diff --git a/website/templates/index/why.html b/website/templates/index/why.html index a4a3c603168..58bb42ffd31 100644 --- a/website/templates/index/why.html +++ b/website/templates/index/why.html @@ -1,8 +1,6 @@ -
    +
    -
    -

    Why ClickHouse

    From 4be8cafc5c80b5340d7ac4faeed42dfe87138e5a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 13 Oct 2021 01:59:12 +0300 Subject: [PATCH 258/264] Amend --- docs/_includes/install/universal.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_includes/install/universal.sh b/docs/_includes/install/universal.sh index db1072f149f..7cba682e772 100755 --- a/docs/_includes/install/universal.sh +++ b/docs/_includes/install/universal.sh @@ -24,10 +24,10 @@ then DIR="freebsd" elif [ "${ARCH}" = "aarch64" ] then - #DIR="freebsd-aarch64" + DIR="freebsd-aarch64" elif [ "${ARCH}" = "powerpc64le" ] then - #DIR="freebsd-powerpc64le" + DIR="freebsd-powerpc64le" fi elif [ "${OS}" = "Darwin" ] then From b94aa5bc502580b903b12d155cbad907a9a54106 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 13 Oct 2021 04:59:18 +0300 Subject: [PATCH 259/264] Change the link to GitHub --- website/templates/index/community.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/templates/index/community.html b/website/templates/index/community.html index 5b2f8b8f769..08ccf0c7580 100644 --- a/website/templates/index/community.html +++ b/website/templates/index/community.html @@ -25,7 +25,7 @@
    - + From 038ca829e4bd7f3720a967695ea1aa0d9dc4ed48 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 13 Oct 2021 12:07:58 +0300 Subject: [PATCH 261/264] Add test with GLOBAL IN and totals. --- .../queries/0_stateless/02096_totals_global_in_bug.reference | 4 ++++ tests/queries/0_stateless/02096_totals_global_in_bug.sql | 2 ++ 2 files changed, 6 insertions(+) create mode 100644 tests/queries/0_stateless/02096_totals_global_in_bug.reference create mode 100644 tests/queries/0_stateless/02096_totals_global_in_bug.sql diff --git a/tests/queries/0_stateless/02096_totals_global_in_bug.reference b/tests/queries/0_stateless/02096_totals_global_in_bug.reference new file mode 100644 index 00000000000..a536e1a5329 --- /dev/null +++ b/tests/queries/0_stateless/02096_totals_global_in_bug.reference @@ -0,0 +1,4 @@ +0 +2 + +2 diff --git a/tests/queries/0_stateless/02096_totals_global_in_bug.sql b/tests/queries/0_stateless/02096_totals_global_in_bug.sql new file mode 100644 index 00000000000..ac4f2b9d2ba --- /dev/null +++ b/tests/queries/0_stateless/02096_totals_global_in_bug.sql @@ -0,0 +1,2 @@ +select sum(number) from remote('127.0.0.{2,3}', numbers(2)) where number global in (select sum(number) from numbers(2) group by number with totals) group by number with totals + From a69b0d9818d1bb9f934ff76d144e3fa5ea6390ad Mon Sep 17 00:00:00 2001 From: tavplubix Date: Wed, 13 Oct 2021 13:21:07 +0300 Subject: [PATCH 262/264] Follow-up to #29901 (#30003) * more informative logs * Update ZooKeeper.cpp * fix --- src/Common/ZooKeeper/IKeeper.h | 2 +- src/Common/ZooKeeper/TestKeeper.cpp | 8 ++++---- src/Common/ZooKeeper/TestKeeper.h | 2 +- src/Common/ZooKeeper/ZooKeeper.cpp | 18 +++++++++--------- src/Common/ZooKeeper/ZooKeeper.h | 2 +- src/Common/ZooKeeper/ZooKeeperImpl.cpp | 6 +++--- src/Common/ZooKeeper/ZooKeeperImpl.h | 2 +- src/Interpreters/Context.cpp | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Common/ZooKeeper/IKeeper.h b/src/Common/ZooKeeper/IKeeper.h index 1a816616c7c..65ebd8ee615 100644 --- a/src/Common/ZooKeeper/IKeeper.h +++ b/src/Common/ZooKeeper/IKeeper.h @@ -481,7 +481,7 @@ public: MultiCallback callback) = 0; /// Expire session and finish all pending requests - virtual void finalize() = 0; + virtual void finalize(const String & reason) = 0; }; } diff --git a/src/Common/ZooKeeper/TestKeeper.cpp b/src/Common/ZooKeeper/TestKeeper.cpp index be210644e70..065b1cf65ba 100644 --- a/src/Common/ZooKeeper/TestKeeper.cpp +++ b/src/Common/ZooKeeper/TestKeeper.cpp @@ -493,7 +493,7 @@ TestKeeper::~TestKeeper() { try { - finalize(); + finalize(__PRETTY_FUNCTION__); if (processing_thread.joinable()) processing_thread.join(); } @@ -556,12 +556,12 @@ void TestKeeper::processingThread() catch (...) { tryLogCurrentException(__PRETTY_FUNCTION__); - finalize(); + finalize(__PRETTY_FUNCTION__); } } -void TestKeeper::finalize() +void TestKeeper::finalize(const String &) { { std::lock_guard lock(push_request_mutex); @@ -661,7 +661,7 @@ void TestKeeper::pushRequest(RequestInfo && request) } catch (...) { - finalize(); + finalize(__PRETTY_FUNCTION__); throw; } } diff --git a/src/Common/ZooKeeper/TestKeeper.h b/src/Common/ZooKeeper/TestKeeper.h index b46f98c0074..e57471341e8 100644 --- a/src/Common/ZooKeeper/TestKeeper.h +++ b/src/Common/ZooKeeper/TestKeeper.h @@ -83,7 +83,7 @@ public: const Requests & requests, MultiCallback callback) override; - void finalize() override; + void finalize(const String & reason) override; struct Node { diff --git a/src/Common/ZooKeeper/ZooKeeper.cpp b/src/Common/ZooKeeper/ZooKeeper.cpp index e347e6de362..3d505c088db 100644 --- a/src/Common/ZooKeeper/ZooKeeper.cpp +++ b/src/Common/ZooKeeper/ZooKeeper.cpp @@ -269,7 +269,7 @@ Coordination::Error ZooKeeper::getChildrenImpl(const std::string & path, Strings if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::List), path)); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -330,7 +330,7 @@ Coordination::Error ZooKeeper::createImpl(const std::string & path, const std::s if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Create), path)); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -400,7 +400,7 @@ Coordination::Error ZooKeeper::removeImpl(const std::string & path, int32_t vers if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Remove), path)); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -432,7 +432,7 @@ Coordination::Error ZooKeeper::existsImpl(const std::string & path, Coordination if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Exists), path)); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -466,7 +466,7 @@ Coordination::Error ZooKeeper::getImpl(const std::string & path, std::string & r if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Get), path)); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -539,7 +539,7 @@ Coordination::Error ZooKeeper::setImpl(const std::string & path, const std::stri if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Set), path)); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -591,7 +591,7 @@ Coordination::Error ZooKeeper::multiImpl(const Coordination::Requests & requests if (future_result.wait_for(std::chrono::milliseconds(operation_timeout_ms)) != std::future_status::ready) { - impl->finalize(); + impl->finalize(fmt::format("Operation timeout on {} {}", toString(Coordination::OpNum::Multi), requests[0]->getPath())); return Coordination::Error::ZOPERATIONTIMEOUT; } else @@ -1038,9 +1038,9 @@ Coordination::Error ZooKeeper::tryMultiNoThrow(const Coordination::Requests & re } } -void ZooKeeper::finalize() +void ZooKeeper::finalize(const String & reason) { - impl->finalize(); + impl->finalize(reason); } void ZooKeeper::setZooKeeperLog(std::shared_ptr zk_log_) diff --git a/src/Common/ZooKeeper/ZooKeeper.h b/src/Common/ZooKeeper/ZooKeeper.h index 5ee25aba1fb..8e015b1f331 100644 --- a/src/Common/ZooKeeper/ZooKeeper.h +++ b/src/Common/ZooKeeper/ZooKeeper.h @@ -274,7 +274,7 @@ public: /// * The node doesn't exist FutureGet asyncTryGet(const std::string & path); - void finalize(); + void finalize(const String & reason); void setZooKeeperLog(std::shared_ptr zk_log_); diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.cpp b/src/Common/ZooKeeper/ZooKeeperImpl.cpp index cf607a3d70e..59ed906db15 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.cpp +++ b/src/Common/ZooKeeper/ZooKeeperImpl.cpp @@ -289,7 +289,7 @@ ZooKeeper::~ZooKeeper() { try { - finalize(false, false, "destructor called"); + finalize(false, false, "Destructor called"); if (send_thread.joinable()) send_thread.join(); @@ -610,7 +610,7 @@ void ZooKeeper::sendThread() catch (...) { tryLogCurrentException(log); - finalize(true, false, "exception in sendThread"); + finalize(true, false, "Exception in sendThread"); } } @@ -669,7 +669,7 @@ void ZooKeeper::receiveThread() catch (...) { tryLogCurrentException(log); - finalize(false, true, "exception in receiveThread"); + finalize(false, true, "Exception in receiveThread"); } } diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.h b/src/Common/ZooKeeper/ZooKeeperImpl.h index 53908e5b0c7..74c0148e7b6 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.h +++ b/src/Common/ZooKeeper/ZooKeeperImpl.h @@ -187,7 +187,7 @@ public: /// it will do read in another session, that read may not see the /// already performed write. - void finalize() override { finalize(false, false, "unknown"); } + void finalize(const String & reason) override { finalize(false, false, reason); } void setZooKeeperLog(std::shared_ptr zk_log_); diff --git a/src/Interpreters/Context.cpp b/src/Interpreters/Context.cpp index 1a95a642e18..e4c6de8853b 100644 --- a/src/Interpreters/Context.cpp +++ b/src/Interpreters/Context.cpp @@ -1853,7 +1853,7 @@ static void reloadZooKeeperIfChangedImpl(const ConfigurationPtr & config, const if (!zk || zk->configChanged(*config, config_name)) { if (zk) - zk->finalize(); + zk->finalize("Config changed"); zk = std::make_shared(*config, config_name, std::move(zk_log)); } From 7742b96497bfff9be35c7463bd21efce839c919b Mon Sep 17 00:00:00 2001 From: tavplubix Date: Wed, 13 Oct 2021 13:34:18 +0300 Subject: [PATCH 263/264] Remove metadata leftovers on drop database (#30054) * remove metadata leftovers on drop database * Update InterpreterDropQuery.cpp * Update DatabaseCatalog.cpp --- src/Core/Settings.h | 2 ++ src/Databases/DatabaseFactory.cpp | 1 + src/Databases/DatabaseOnDisk.cpp | 25 +++++++++++++++++-- src/Interpreters/DatabaseCatalog.cpp | 10 +++++--- src/Interpreters/DatabaseCatalog.h | 2 +- src/Interpreters/InterpreterCreateQuery.cpp | 2 +- src/Interpreters/InterpreterDropQuery.cpp | 2 +- src/Interpreters/loadMetadata.cpp | 1 + .../test_restart_server/__init__.py | 0 tests/integration/test_restart_server/test.py | 22 ++++++++++++++++ .../0_stateless/01601_detach_permanently.sql | 4 +-- 11 files changed, 60 insertions(+), 11 deletions(-) create mode 100755 tests/integration/test_restart_server/__init__.py create mode 100755 tests/integration/test_restart_server/test.py diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 6dcbf663dd5..a5767955045 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -523,6 +523,8 @@ class IColumn; M(Int64, remote_fs_read_backoff_threshold, 10000, "Max wait time when trying to read data for remote disk", 0) \ M(Int64, remote_fs_read_backoff_max_tries, 5, "Max attempts to read with backoff", 0) \ \ + M(Bool, force_remove_data_recursively_on_drop, false, "Recursively remove data on DROP query. Avoids 'Directory not empty' error, but may silently remove detached data", 0) \ + \ /** Experimental functions */ \ M(Bool, allow_experimental_funnel_functions, false, "Enable experimental functions for funnel analysis.", 0) \ M(Bool, allow_experimental_nlp_functions, false, "Enable experimental functions for natural language processing.", 0) \ diff --git a/src/Databases/DatabaseFactory.cpp b/src/Databases/DatabaseFactory.cpp index 9cf600d5cdf..fc428aae9ac 100644 --- a/src/Databases/DatabaseFactory.cpp +++ b/src/Databases/DatabaseFactory.cpp @@ -71,6 +71,7 @@ DatabasePtr DatabaseFactory::get(const ASTCreateQuery & create, const String & m /// Before 20.7 it's possible that .sql metadata file does not exist for some old database. /// In this case Ordinary database is created on server startup if the corresponding metadata directory exists. /// So we should remove metadata directory if database creation failed. + /// TODO remove this code created = fs::create_directory(metadata_path); DatabasePtr impl = getImpl(create, metadata_path, context); diff --git a/src/Databases/DatabaseOnDisk.cpp b/src/Databases/DatabaseOnDisk.cpp index d681d4f83da..ea9635530c7 100644 --- a/src/Databases/DatabaseOnDisk.cpp +++ b/src/Databases/DatabaseOnDisk.cpp @@ -39,6 +39,7 @@ namespace ErrorCodes extern const int SYNTAX_ERROR; extern const int TABLE_ALREADY_EXISTS; extern const int EMPTY_LIST_OF_COLUMNS_PASSED; + extern const int DATABASE_NOT_EMPTY; } @@ -544,8 +545,28 @@ ASTPtr DatabaseOnDisk::getCreateDatabaseQuery() const void DatabaseOnDisk::drop(ContextPtr local_context) { assert(tables.empty()); - fs::remove(local_context->getPath() + getDataPath()); - fs::remove(getMetadataPath()); + if (local_context->getSettingsRef().force_remove_data_recursively_on_drop) + { + fs::remove_all(local_context->getPath() + getDataPath()); + fs::remove_all(getMetadataPath()); + } + else + { + try + { + fs::remove(local_context->getPath() + getDataPath()); + fs::remove(getMetadataPath()); + } + catch (const fs::filesystem_error & e) + { + if (e.code() != std::errc::directory_not_empty) + throw Exception(Exception::CreateFromSTDTag{}, e); + throw Exception(ErrorCodes::DATABASE_NOT_EMPTY, "Cannot drop: {}. " + "Probably database contain some detached tables or metadata leftovers from Ordinary engine. " + "If you want to remove all data anyway, try to attach database back and drop it again " + "with enabled force_remove_data_recursively_on_drop setting", e.what()); + } + } } String DatabaseOnDisk::getObjectMetadataPath(const String & object_name) const diff --git a/src/Interpreters/DatabaseCatalog.cpp b/src/Interpreters/DatabaseCatalog.cpp index bff03be61a8..08cc260b536 100644 --- a/src/Interpreters/DatabaseCatalog.cpp +++ b/src/Interpreters/DatabaseCatalog.cpp @@ -329,7 +329,7 @@ void DatabaseCatalog::attachDatabase(const String & database_name, const Databas } -DatabasePtr DatabaseCatalog::detachDatabase(const String & database_name, bool drop, bool check_empty) +DatabasePtr DatabaseCatalog::detachDatabase(ContextPtr local_context, const String & database_name, bool drop, bool check_empty) { if (database_name == TEMPORARY_DATABASE) throw Exception("Cannot detach database with temporary tables.", ErrorCodes::DATABASE_ACCESS_DENIED); @@ -365,12 +365,14 @@ DatabasePtr DatabaseCatalog::detachDatabase(const String & database_name, bool d if (drop) { /// Delete the database. - db->drop(getContext()); + db->drop(local_context); /// Old ClickHouse versions did not store database.sql files + /// Remove metadata dir (if exists) to avoid recreation of .sql file on server startup + fs::path database_metadata_dir = fs::path(getContext()->getPath()) / "metadata" / escapeForFileName(database_name); + fs::remove(database_metadata_dir); fs::path database_metadata_file = fs::path(getContext()->getPath()) / "metadata" / (escapeForFileName(database_name) + ".sql"); - if (fs::exists(database_metadata_file)) - fs::remove(database_metadata_file); + fs::remove(database_metadata_file); } return db; diff --git a/src/Interpreters/DatabaseCatalog.h b/src/Interpreters/DatabaseCatalog.h index f2063e4199f..6079553b025 100644 --- a/src/Interpreters/DatabaseCatalog.h +++ b/src/Interpreters/DatabaseCatalog.h @@ -147,7 +147,7 @@ public: DatabasePtr getSystemDatabase() const; void attachDatabase(const String & database_name, const DatabasePtr & database); - DatabasePtr detachDatabase(const String & database_name, bool drop = false, bool check_empty = true); + DatabasePtr detachDatabase(ContextPtr local_context, const String & database_name, bool drop = false, bool check_empty = true); void updateDatabaseName(const String & old_name, const String & new_name); /// database_name must be not empty diff --git a/src/Interpreters/InterpreterCreateQuery.cpp b/src/Interpreters/InterpreterCreateQuery.cpp index c098c6e0506..530b10703c5 100644 --- a/src/Interpreters/InterpreterCreateQuery.cpp +++ b/src/Interpreters/InterpreterCreateQuery.cpp @@ -295,7 +295,7 @@ BlockIO InterpreterCreateQuery::createDatabase(ASTCreateQuery & create) assert(removed); } if (added) - DatabaseCatalog::instance().detachDatabase(database_name, false, false); + DatabaseCatalog::instance().detachDatabase(getContext(), database_name, false, false); throw; } diff --git a/src/Interpreters/InterpreterDropQuery.cpp b/src/Interpreters/InterpreterDropQuery.cpp index 509211df3b6..5394c1ecaf0 100644 --- a/src/Interpreters/InterpreterDropQuery.cpp +++ b/src/Interpreters/InterpreterDropQuery.cpp @@ -369,7 +369,7 @@ BlockIO InterpreterDropQuery::executeToDatabaseImpl(const ASTDropQuery & query, database->assertCanBeDetached(true); /// DETACH or DROP database itself - DatabaseCatalog::instance().detachDatabase(database_name, drop, database->shouldBeEmptyOnDetach()); + DatabaseCatalog::instance().detachDatabase(getContext(), database_name, drop, database->shouldBeEmptyOnDetach()); } } diff --git a/src/Interpreters/loadMetadata.cpp b/src/Interpreters/loadMetadata.cpp index 858b4281f5a..6a3db48e835 100644 --- a/src/Interpreters/loadMetadata.cpp +++ b/src/Interpreters/loadMetadata.cpp @@ -72,6 +72,7 @@ static void loadDatabase( } else if (fs::exists(fs::path(database_path))) { + /// TODO Remove this code (it's required for compatibility with versions older than 20.7) /// Database exists, but .sql file is absent. It's old-style Ordinary database (e.g. system or default) database_attach_query = "ATTACH DATABASE " + backQuoteIfNeed(database) + " ENGINE = Ordinary"; } diff --git a/tests/integration/test_restart_server/__init__.py b/tests/integration/test_restart_server/__init__.py new file mode 100755 index 00000000000..e69de29bb2d diff --git a/tests/integration/test_restart_server/test.py b/tests/integration/test_restart_server/test.py new file mode 100755 index 00000000000..47797f7c4a5 --- /dev/null +++ b/tests/integration/test_restart_server/test.py @@ -0,0 +1,22 @@ +import pytest +from helpers.cluster import ClickHouseCluster + +cluster = ClickHouseCluster(__file__) +node = cluster.add_instance('node', stay_alive=True) + +@pytest.fixture(scope="module") +def start_cluster(): + try: + cluster.start() + yield cluster + finally: + cluster.shutdown() + + +def test_drop_memory_database(start_cluster): + node.query("CREATE DATABASE test ENGINE Memory") + node.query("CREATE TABLE test.test_table(a String) ENGINE Memory") + node.query("DROP DATABASE test") + node.restart_clickhouse(kill=True) + assert node.query("SHOW DATABASES LIKE 'test'").strip() == "" + diff --git a/tests/queries/0_stateless/01601_detach_permanently.sql b/tests/queries/0_stateless/01601_detach_permanently.sql index 3bf05b872b9..97797a59af5 100644 --- a/tests/queries/0_stateless/01601_detach_permanently.sql +++ b/tests/queries/0_stateless/01601_detach_permanently.sql @@ -131,7 +131,7 @@ SELECT 'And detach permanently again to check how database drop will behave'; DETACH table test1601_detach_permanently_ordinary.test_name_reuse PERMANENTLY; SELECT 'DROP database - Directory not empty error, but database detached'; -DROP DATABASE test1601_detach_permanently_ordinary; -- { serverError 1001 } +DROP DATABASE test1601_detach_permanently_ordinary; -- { serverError 219 } ATTACH DATABASE test1601_detach_permanently_ordinary; @@ -205,7 +205,7 @@ SELECT 'And detach permanently again to check how database drop will behave'; DETACH table test1601_detach_permanently_lazy.test_name_reuse PERMANENTLY; SELECT 'DROP database - Directory not empty error, but database deteched'; -DROP DATABASE test1601_detach_permanently_lazy; -- { serverError 1001 } +DROP DATABASE test1601_detach_permanently_lazy; -- { serverError 219 } ATTACH DATABASE test1601_detach_permanently_lazy; From 923c76fc9914d66593fd69d93684db2bf5182ab3 Mon Sep 17 00:00:00 2001 From: zhangxiao871 <821008736@qq.com> Date: Wed, 13 Oct 2021 18:38:24 +0800 Subject: [PATCH 264/264] Modify comments --- src/Client/ConnectionPoolWithFailover.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Client/ConnectionPoolWithFailover.cpp b/src/Client/ConnectionPoolWithFailover.cpp index c0b4965aae3..aaffe85ae2e 100644 --- a/src/Client/ConnectionPoolWithFailover.cpp +++ b/src/Client/ConnectionPoolWithFailover.cpp @@ -73,8 +73,8 @@ IConnectionPool::Entry ConnectionPoolWithFailover::get(const ConnectionTimeouts ++last_used; /* Consider nested_pools.size() equals to 5 * last_used = 1 -> get_priority: 0 1 2 3 4 - * last_used = 2 -> get_priority: 5 0 1 2 3 - * last_used = 3 -> get_priority: 5 4 0 1 2 + * last_used = 2 -> get_priority: 4 0 1 2 3 + * last_used = 3 -> get_priority: 4 3 0 1 2 * ... * */ get_priority = [&](size_t i) { ++i; return i < last_used ? nested_pools.size() - i : i - last_used; };
    + + + + +

    + {{ _('Mihir Gokhale') }} +

    +

    + {{ _('Associate, Business Strategy & Ops') }} +

    +