From abae7dfffec2618cc5acb87371e13635c0eea8f1 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Tue, 31 Mar 2020 16:14:59 +0300 Subject: [PATCH 001/208] Initial implementation of splitting string into Alpha-Num tokens with SIMD intrinsics. --- .../MergeTree/MergeTreeIndexFullText.cpp | 53 +++++++++++++++++++ .../tests/gtest_SplitTokenExtractor.cpp | 0 2 files changed, 53 insertions(+) create mode 100644 dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp b/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp index 4b3bd954496..5e4bf15418c 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp @@ -606,8 +606,60 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size { *token_start = *pos; *token_len = 0; + while (*pos < len) { +#if __SSE2__ + // NOTE: we assume that `data` string is padded from the right with 15 zero-bytes. + const __m128i haystack = _mm_loadu_si128(reinterpret_cast(data + *pos)); + const size_t haystack_length = 16; + +#if __SSE4_2__ + // With the help of https://www.strchr.com/strcmp_and_strlen_using_sse_4.2 + static const auto alnum_chars_ranges = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Z', 'A', 'z', 'a', '9', '0'); + // Every bit represents if `haystack` character is in the ranges (1) or not(0) + const auto result_bitmask = _mm_cvtsi128_si32(_mm_cmpestrm(alnum_chars_ranges, 6, haystack, haystack_length, _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS)); +#else + // NOTE: -1 and +1 required since SSE2 has no `>=` and `<=` instructions on packed 8-bit integers (epi8). + static const auto number_begin = _mm_set1_epi8('0' - 1); + static const auto number_end = _mm_set1_epi8('9' + 1); + static const auto alpha_lower_begin = _mm_set1_epi8('a' - 1); + static const auto alpha_lower_end = _mm_set1_epi8('z' + 1); + static const auto alpha_upper_begin = _mm_set1_epi8('A' - 1); + static const auto alpha_upper_end = _mm_set1_epi8('Z' + 1); + + // every bit represents if `haystack` character `c` statisfies condition: + // (c > '0' - 1 && c < '9' + 1) || (c > 'a' - 1 && c < 'z' + 1) || (c > 'A' - 1 && c < 'Z' + 1) + const int result_bitmask = _mm_movemask_epi8(_mm_or_si128(_mm_or_si128( + _mm_and_si128(_mm_cmpgt_epi8(haystack, number_begin), _mm_cmplt_epi8(haystack, number_end)), + _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_lower_begin), _mm_cmplt_epi8(haystack, alpha_lower_end))), + _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_upper_begin), _mm_cmplt_epi8(haystack, alpha_upper_end)))); +#endif + // NOTE: __builtin_ctz family explicitly state that result is UNDEFINED if argument is 0 + if (result_bitmask == 0) + { + // end of token started on previous haystack + if (*token_len != 0) + return true; + + *pos += haystack_length; + continue; + } + + const auto start = getTrailingZeroBits(result_bitmask); + if (*token_len == 0) + *token_start = *pos + start; + + const auto l = getTrailingZeroBits(~(result_bitmask >> start)); + *token_len += l; + + *pos += start + l; + if (start + l == 16) + // check if there are leftovers in next `haystack` + continue; + + return true; +#else if (isASCII(data[*pos]) && !isAlphaNumericASCII(data[*pos])) { /// Finish current token if any @@ -621,6 +673,7 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size ++*pos; ++*token_len; } +#endif } return *token_len > 0; } diff --git a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp new file mode 100644 index 00000000000..e69de29bb2d From 9d6c88c78e7fcd8c650b0b7f1461ee5c7649806c Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Thu, 2 Apr 2020 00:27:21 +0300 Subject: [PATCH 002/208] SplitTokenExtractor::next unit-tests --- .../tests/gtest_SplitTokenExtractor.cpp | 168 ++++++++++++++++++ 1 file changed, 168 insertions(+) diff --git a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp index e69de29bb2d..6be6650369e 100644 --- a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -0,0 +1,168 @@ +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace +{ +using namespace DB; +} + +struct SplitTokenExtractorTestCase +{ + const char * description; + const std::string source; + const std::vector tokens; +}; + +std::ostream & operator<<(std::ostream & ostr, const SplitTokenExtractorTestCase & test_case) +{ + return ostr << test_case.description; +} + +class SplitTokenExtractorTest : public ::testing::TestWithParam +{ +public: + void SetUp() override + { + const auto & param = GetParam(); + const auto & source = param.source; + data = std::make_unique>(source.data(), source.data() + source.size()); + } + + std::unique_ptr> data; +}; + +TEST_P(SplitTokenExtractorTest, next) +{ + const auto & param = GetParam(); + + SplitTokenExtractor token_extractor; + + size_t i = 0; + + size_t pos = 0; + size_t token_start = 0; + size_t token_len = 0; + + for (const auto & expected_token : param.tokens) + { + SCOPED_TRACE(++i); + EXPECT_TRUE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)); + EXPECT_EQ(expected_token, param.source.substr(token_start, token_len)) + << " token_start:" << token_start << " token_len: " << token_len; + } +} + +#define BINARY_STRING(str) std::string{str, sizeof(str)-1} + +INSTANTIATE_TEST_SUITE_P(ShortSingleToken, + SplitTokenExtractorTest, + ::testing::ValuesIn(std::initializer_list{ + { + "Empty input sequence produces no tokens.", + "", + {} + }, + { + "Short single token", + "foo", + {"foo"} + }, + { + "Short single token surruonded by whitespace", + "\t\vfoo\n\r", + {"foo"} + } + }) +); + +INSTANTIATE_TEST_SUITE_P(UTF8, + SplitTokenExtractorTest, + ::testing::ValuesIn(std::initializer_list{ + { + "Single token with mixed ASCII and UTF-8 chars", + BINARY_STRING("abc\u0442" "123\u0447XYZ\u043A"), + {"abc\u0442" "123\u0447XYZ\u043A"} + }, + { + "Multiple UTF-8 tokens", + BINARY_STRING("\u043F\u0440\u0438\u0432\u0435\u0442, u043C\u0438\u0440!"), + {"\u043F\u0440\u0438\u0432\u0435\u0442", "u043C\u0438\u0440"} + }, + }) +); + +INSTANTIATE_TEST_SUITE_P(MultipleTokens, + SplitTokenExtractorTest, + ::testing::ValuesIn(std::initializer_list{ + { + "Multiple tokens separated by whitespace", + BINARY_STRING("\nabc 123\tXYZ\r"), + { + "abc", "123", "XYZ" + } + }, + { + "Multiple tokens separated by non-printable chars", + BINARY_STRING("\0abc\1" "123\2XYZ\4"), + { + "abc", "123", "XYZ" + } + }, + { + "ASCII table is split into numeric, upper case and lower case letters", + + BINARY_STRING("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16" + "\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO" + "PQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87" + "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c" + "\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1" + "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6" + "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb" + "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" + "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), + { + "0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" + } + } + }) +); + + +INSTANTIATE_TEST_SUITE_P(SIMD_Cases, + SplitTokenExtractorTest, + ::testing::ValuesIn(std::initializer_list{ + { + "First 16 bytes are empty, then a shor token", + " abcdef", + {"abcdef"} + }, + { + "Token crosses bounday of 16-byte chunk", + " abcdef", + {"abcdef"} + }, + { + "Token ends at the end of 16-byte chunk", + " abcdef", + {"abcdef"} + }, + { + "Token crosses bondaries of multiple 16-byte chunks", + "abcdefghijklmnopqrstuvwxyz", + {"abcdefghijklmnopqrstuvwxyz"} + }, + }) +); From 90cb6a25cf1d10d6e45d83112dcdc6fc713415c6 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Thu, 2 Apr 2020 00:28:02 +0300 Subject: [PATCH 003/208] Fixed compilation issues and fixed several bugs in SplitTokenExtractor::next * Handling all characters above 0x80 as symbols (fixes UTF8 tokens) * Properly handling tokens that end exactly on haystack boundary. --- .../MergeTree/MergeTreeIndexFullText.cpp | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp b/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp index 5e4bf15418c..68d67a0c787 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp @@ -19,6 +19,10 @@ #include +#include +#include +#include + namespace DB { @@ -609,16 +613,17 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size while (*pos < len) { -#if __SSE2__ +#if defined(__SSE2__) // NOTE: we assume that `data` string is padded from the right with 15 zero-bytes. const __m128i haystack = _mm_loadu_si128(reinterpret_cast(data + *pos)); const size_t haystack_length = 16; -#if __SSE4_2__ +#if defined(__SSE4_2__) // With the help of https://www.strchr.com/strcmp_and_strlen_using_sse_4.2 - static const auto alnum_chars_ranges = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'Z', 'A', 'z', 'a', '9', '0'); + static const auto alnum_chars_ranges = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, + '\xFF', '\x80', 'z', 'a', 'Z', 'A', '9', '0'); // Every bit represents if `haystack` character is in the ranges (1) or not(0) - const auto result_bitmask = _mm_cvtsi128_si32(_mm_cmpestrm(alnum_chars_ranges, 6, haystack, haystack_length, _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS)); + const int result_bitmask = _mm_cvtsi128_si32(_mm_cmpestrm(alnum_chars_ranges, 8, haystack, haystack_length, _SIDD_CMP_RANGES)); #else // NOTE: -1 and +1 required since SSE2 has no `>=` and `<=` instructions on packed 8-bit integers (epi8). static const auto number_begin = _mm_set1_epi8('0' - 1); @@ -627,13 +632,16 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size static const auto alpha_lower_end = _mm_set1_epi8('z' + 1); static const auto alpha_upper_begin = _mm_set1_epi8('A' - 1); static const auto alpha_upper_end = _mm_set1_epi8('Z' + 1); + static const auto zero = _mm_set1_epi8(0); // every bit represents if `haystack` character `c` statisfies condition: - // (c > '0' - 1 && c < '9' + 1) || (c > 'a' - 1 && c < 'z' + 1) || (c > 'A' - 1 && c < 'Z' + 1) - const int result_bitmask = _mm_movemask_epi8(_mm_or_si128(_mm_or_si128( - _mm_and_si128(_mm_cmpgt_epi8(haystack, number_begin), _mm_cmplt_epi8(haystack, number_end)), - _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_lower_begin), _mm_cmplt_epi8(haystack, alpha_lower_end))), - _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_upper_begin), _mm_cmplt_epi8(haystack, alpha_upper_end)))); + // (c < 0) || (c > '0' - 1 && c < '9' + 1) || (c > 'a' - 1 && c < 'z' + 1) || (c > 'A' - 1 && c < 'Z' + 1) + // < 0 since _mm_cmplt_epi8 threats chars as SIGNED, and hence all chars > 0x80 are negative. + const int result_bitmask = _mm_movemask_epi8(_mm_or_si128(_mm_or_si128(_mm_or_si128( + _mm_cmplt_epi8(haystack, zero), + _mm_and_si128(_mm_cmpgt_epi8(haystack, number_begin), _mm_cmplt_epi8(haystack, number_end))), + _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_lower_begin), _mm_cmplt_epi8(haystack, alpha_lower_end))), + _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_upper_begin), _mm_cmplt_epi8(haystack, alpha_upper_end)))); #endif // NOTE: __builtin_ctz family explicitly state that result is UNDEFINED if argument is 0 if (result_bitmask == 0) @@ -649,12 +657,15 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size const auto start = getTrailingZeroBits(result_bitmask); if (*token_len == 0) *token_start = *pos + start; + else if (start != 0) + // token is not continued in this haystack + return true; const auto l = getTrailingZeroBits(~(result_bitmask >> start)); *token_len += l; *pos += start + l; - if (start + l == 16) + if (start + l == haystack_length) // check if there are leftovers in next `haystack` continue; From f17fd7969ca01550fe1932aaaacb36c6255074c4 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Thu, 2 Apr 2020 00:32:12 +0300 Subject: [PATCH 004/208] Minor: excluded superflous includes --- dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp index 6be6650369e..2cd20a70821 100644 --- a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -10,10 +10,6 @@ #include #include -#include -#include -#include - namespace { using namespace DB; From 3cacef6b4478860639728b7d5cd64d16ea394bcc Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Thu, 2 Apr 2020 13:53:13 +0300 Subject: [PATCH 005/208] Fixed final garbage token Also, added getTrailingZeroBitsUnsafe(), updated comments and cleaned up test cases --- dbms/src/Common/BitHelpers.h | 15 +++++--- .../MergeTree/MergeTreeIndexFullText.cpp | 34 ++++++++++++------- .../tests/gtest_SplitTokenExtractor.cpp | 24 +++++++++---- 3 files changed, 49 insertions(+), 24 deletions(-) diff --git a/dbms/src/Common/BitHelpers.h b/dbms/src/Common/BitHelpers.h index ba6a4c60a49..bc6d7413def 100644 --- a/dbms/src/Common/BitHelpers.h +++ b/dbms/src/Common/BitHelpers.h @@ -53,12 +53,10 @@ inline size_t getLeadingZeroBits(T x) } } +// Unsafe since __builtin_ctz()-family explicitly state that result is undefined on x == 0 template -inline size_t getTrailingZeroBits(T x) +inline size_t getTrailingZeroBitsUnsafe(T x) { - if (!x) - return sizeof(x) * 8; - if constexpr (sizeof(T) <= sizeof(unsigned int)) { return __builtin_ctz(x); @@ -73,6 +71,15 @@ inline size_t getTrailingZeroBits(T x) } } +template +inline size_t getTrailingZeroBits(T x) +{ + if (!x) + return sizeof(x) * 8; + + return getTrailingZeroBitsUnsafe(x); +} + /** Returns a mask that has '1' for `bits` LSB set: * maskLowBits(3) => 00000111 */ diff --git a/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp b/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp index 68d67a0c787..af979010dc0 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeIndexFullText.cpp @@ -614,7 +614,7 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size while (*pos < len) { #if defined(__SSE2__) - // NOTE: we assume that `data` string is padded from the right with 15 zero-bytes. + // NOTE: we assume that `data` string is padded from the right with 15 bytes. const __m128i haystack = _mm_loadu_si128(reinterpret_cast(data + *pos)); const size_t haystack_length = 16; @@ -632,40 +632,40 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size static const auto alpha_lower_end = _mm_set1_epi8('z' + 1); static const auto alpha_upper_begin = _mm_set1_epi8('A' - 1); static const auto alpha_upper_end = _mm_set1_epi8('Z' + 1); - static const auto zero = _mm_set1_epi8(0); + static const auto zero = _mm_set1_epi8(0); // every bit represents if `haystack` character `c` statisfies condition: // (c < 0) || (c > '0' - 1 && c < '9' + 1) || (c > 'a' - 1 && c < 'z' + 1) || (c > 'A' - 1 && c < 'Z' + 1) - // < 0 since _mm_cmplt_epi8 threats chars as SIGNED, and hence all chars > 0x80 are negative. + // < 0 since _mm_cmplt_epi8 threats chars as SIGNED, and so all chars > 0x80 are negative. const int result_bitmask = _mm_movemask_epi8(_mm_or_si128(_mm_or_si128(_mm_or_si128( _mm_cmplt_epi8(haystack, zero), _mm_and_si128(_mm_cmpgt_epi8(haystack, number_begin), _mm_cmplt_epi8(haystack, number_end))), _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_lower_begin), _mm_cmplt_epi8(haystack, alpha_lower_end))), _mm_and_si128(_mm_cmpgt_epi8(haystack, alpha_upper_begin), _mm_cmplt_epi8(haystack, alpha_upper_end)))); #endif - // NOTE: __builtin_ctz family explicitly state that result is UNDEFINED if argument is 0 if (result_bitmask == 0) { - // end of token started on previous haystack if (*token_len != 0) + // end of token started on previous haystack return true; *pos += haystack_length; continue; } - const auto start = getTrailingZeroBits(result_bitmask); + const auto token_start_pos_in_current_haystack = getTrailingZeroBitsUnsafe(result_bitmask); if (*token_len == 0) - *token_start = *pos + start; - else if (start != 0) - // token is not continued in this haystack + // new token + *token_start = *pos + token_start_pos_in_current_haystack; + else if (token_start_pos_in_current_haystack != 0) + // end of token starting in one of previous haystacks return true; - const auto l = getTrailingZeroBits(~(result_bitmask >> start)); - *token_len += l; + const auto token_bytes_in_current_haystack = getTrailingZeroBitsUnsafe(~(result_bitmask >> token_start_pos_in_current_haystack)); + *token_len += token_bytes_in_current_haystack; - *pos += start + l; - if (start + l == haystack_length) + *pos += token_start_pos_in_current_haystack + token_bytes_in_current_haystack; + if (token_start_pos_in_current_haystack + token_bytes_in_current_haystack == haystack_length) // check if there are leftovers in next `haystack` continue; @@ -686,6 +686,14 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size } #endif } + +#if defined(__SSE2__) + // Could happen only if string is not padded with zeroes, and we accidentally hopped over end of data. + if (*token_start > len) + return false; + *token_len = len - *token_start; +#endif + return *token_len > 0; } diff --git a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp index 2cd20a70821..b8686f962bc 100644 --- a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -55,13 +55,16 @@ TEST_P(SplitTokenExtractorTest, next) for (const auto & expected_token : param.tokens) { SCOPED_TRACE(++i); - EXPECT_TRUE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)); + ASSERT_TRUE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)); EXPECT_EQ(expected_token, param.source.substr(token_start, token_len)) << " token_start:" << token_start << " token_len: " << token_len; } + + ASSERT_FALSE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)); } -#define BINARY_STRING(str) std::string{str, sizeof(str)-1} +// Helper to allow strings with embedded '\0' chars. +#define BINARY_STRING(str) std::string{str, sizeof(str) - 1} INSTANTIATE_TEST_SUITE_P(ShortSingleToken, SplitTokenExtractorTest, @@ -89,13 +92,13 @@ INSTANTIATE_TEST_SUITE_P(UTF8, ::testing::ValuesIn(std::initializer_list{ { "Single token with mixed ASCII and UTF-8 chars", - BINARY_STRING("abc\u0442" "123\u0447XYZ\u043A"), + "abc\u0442" "123\u0447XYZ\u043A", {"abc\u0442" "123\u0447XYZ\u043A"} }, { "Multiple UTF-8 tokens", - BINARY_STRING("\u043F\u0440\u0438\u0432\u0435\u0442, u043C\u0438\u0440!"), - {"\u043F\u0440\u0438\u0432\u0435\u0442", "u043C\u0438\u0440"} + "\u043F\u0440\u0438\u0432\u0435\u0442, \u043C\u0438\u0440!", + {"\u043F\u0440\u0438\u0432\u0435\u0442", "\u043C\u0438\u0440"} }, }) ); @@ -105,7 +108,7 @@ INSTANTIATE_TEST_SUITE_P(MultipleTokens, ::testing::ValuesIn(std::initializer_list{ { "Multiple tokens separated by whitespace", - BINARY_STRING("\nabc 123\tXYZ\r"), + "\nabc 123\tXYZ\r", { "abc", "123", "XYZ" } @@ -130,7 +133,14 @@ INSTANTIATE_TEST_SUITE_P(MultipleTokens, "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), { - "0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz" + "0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", + "\x80\x81\x82\x83\x84\x85\x86\x87" + "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c" + "\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1" + "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6" + "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb" + "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" + "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" } } }) From 21532f6a6d46107622a5f68754505cb977086c21 Mon Sep 17 00:00:00 2001 From: Vxider Date: Sun, 5 Apr 2020 01:33:51 +0800 Subject: [PATCH 006/208] parallel insert for materialized view --- src/Storages/StorageMaterializedView.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Storages/StorageMaterializedView.h b/src/Storages/StorageMaterializedView.h index 6284f791f4f..357d3858d0d 100644 --- a/src/Storages/StorageMaterializedView.h +++ b/src/Storages/StorageMaterializedView.h @@ -31,6 +31,7 @@ public: bool supportsPrewhere() const override { return getTargetTable()->supportsPrewhere(); } bool supportsFinal() const override { return getTargetTable()->supportsFinal(); } bool supportsIndexForIn() const override { return getTargetTable()->supportsIndexForIn(); } + bool supportsParallelInsert() const override { return getTargetTable()->supportsParallelInsert(); } bool mayBenefitFromIndexForIn(const ASTPtr & left_in_operand, const Context & query_context) const override { return getTargetTable()->mayBenefitFromIndexForIn(left_in_operand, query_context); From 1d451082187fd21a52dfba4c79cd5c847554557f Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Mon, 6 Apr 2020 13:27:31 +0300 Subject: [PATCH 007/208] Fixed builds, implementation and tests * Builds shouldn't fail on platforms that do not support SSE2 and SSE4.2 and do not have corresponding headers. * Updated tests to include malicious padding * Fixed reporting tokens that cross or outside of data boundaries. --- .../MergeTree/MergeTreeIndexFullText.cpp | 27 +++++++++++-------- .../tests/gtest_SplitTokenExtractor.cpp | 8 +++++- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/dbms/Storages/MergeTree/MergeTreeIndexFullText.cpp b/dbms/Storages/MergeTree/MergeTreeIndexFullText.cpp index af979010dc0..93553e0619e 100644 --- a/dbms/Storages/MergeTree/MergeTreeIndexFullText.cpp +++ b/dbms/Storages/MergeTree/MergeTreeIndexFullText.cpp @@ -19,9 +19,14 @@ #include +#if defined(__SSE2__) #include + +#if defined(__SSE4_2__) #include -#include +#endif + +#endif namespace DB @@ -620,19 +625,19 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size #if defined(__SSE4_2__) // With the help of https://www.strchr.com/strcmp_and_strlen_using_sse_4.2 - static const auto alnum_chars_ranges = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, + const auto alnum_chars_ranges = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, '\xFF', '\x80', 'z', 'a', 'Z', 'A', '9', '0'); // Every bit represents if `haystack` character is in the ranges (1) or not(0) const int result_bitmask = _mm_cvtsi128_si32(_mm_cmpestrm(alnum_chars_ranges, 8, haystack, haystack_length, _SIDD_CMP_RANGES)); #else // NOTE: -1 and +1 required since SSE2 has no `>=` and `<=` instructions on packed 8-bit integers (epi8). - static const auto number_begin = _mm_set1_epi8('0' - 1); - static const auto number_end = _mm_set1_epi8('9' + 1); - static const auto alpha_lower_begin = _mm_set1_epi8('a' - 1); - static const auto alpha_lower_end = _mm_set1_epi8('z' + 1); - static const auto alpha_upper_begin = _mm_set1_epi8('A' - 1); - static const auto alpha_upper_end = _mm_set1_epi8('Z' + 1); - static const auto zero = _mm_set1_epi8(0); + const auto number_begin = _mm_set1_epi8('0' - 1); + const auto number_end = _mm_set1_epi8('9' + 1); + const auto alpha_lower_begin = _mm_set1_epi8('a' - 1); + const auto alpha_lower_end = _mm_set1_epi8('z' + 1); + const auto alpha_upper_begin = _mm_set1_epi8('A' - 1); + const auto alpha_upper_end = _mm_set1_epi8('Z' + 1); + const auto zero = _mm_set1_epi8(0); // every bit represents if `haystack` character `c` statisfies condition: // (c < 0) || (c > '0' - 1 && c < '9' + 1) || (c > 'a' - 1 && c < 'z' + 1) || (c > 'A' - 1 && c < 'Z' + 1) @@ -669,7 +674,7 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size // check if there are leftovers in next `haystack` continue; - return true; + break; #else if (isASCII(data[*pos]) && !isAlphaNumericASCII(data[*pos])) { @@ -691,7 +696,7 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size // Could happen only if string is not padded with zeroes, and we accidentally hopped over end of data. if (*token_start > len) return false; - *token_len = len - *token_start; + *token_len = std::min(len - *token_start, *token_len); #endif return *token_len > 0; diff --git a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp index b8686f962bc..e2229792020 100644 --- a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -17,7 +17,7 @@ using namespace DB; struct SplitTokenExtractorTestCase { - const char * description; + const std::string_view description; const std::string source; const std::vector tokens; }; @@ -35,6 +35,12 @@ public: const auto & param = GetParam(); const auto & source = param.source; data = std::make_unique>(source.data(), source.data() + source.size()); + + // add predefined padding that forms tokens to ensure no reads past end of buffer. + const char extra_padding[] = "this is the end \xd1\x8d\xd1\x82\xd0\xbe\xd0\xba\xd0\xbe \xd0\xbd\xd0\xb5\xd1\x86"; + data->insert(data->end(), std::begin(extra_padding), std::end(extra_padding)); + + data->resize(data->size() - sizeof(extra_padding)); } std::unique_ptr> data; From 79024d73a230473203ad0560f5908b59cdac8e95 Mon Sep 17 00:00:00 2001 From: Anton Popov Date: Thu, 2 Apr 2020 20:27:07 +0300 Subject: [PATCH 008/208] improve performance of index analysis with monotonic functions --- src/Interpreters/Set.cpp | 11 ++ src/Interpreters/Set.h | 2 + src/Storages/MergeTree/IMergeTreeDataPart.cpp | 4 +- src/Storages/MergeTree/KeyCondition.cpp | 121 +++++++----------- src/Storages/MergeTree/KeyCondition.h | 109 ++++++++-------- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 28 ++-- .../MergeTree/MergeTreeIndexMinMax.cpp | 4 +- tests/performance/set_index.xml | 9 +- 8 files changed, 144 insertions(+), 144 deletions(-) diff --git a/src/Interpreters/Set.cpp b/src/Interpreters/Set.cpp index 3c79ea5174d..2ad9f588cf6 100644 --- a/src/Interpreters/Set.cpp +++ b/src/Interpreters/Set.cpp @@ -588,6 +588,14 @@ BoolMask MergeTreeSetIndex::checkInRange(const std::vector & key_ranges, }; } +bool MergeTreeSetIndex::hasMonotonicFunctionsChain() const +{ + for (const auto & mapping : indexes_mapping) + if (!mapping.functions.empty()) + return true; + return false; +} + void ValueWithInfinity::update(const Field & x) { /// Keep at most one element in column. @@ -599,8 +607,11 @@ void ValueWithInfinity::update(const Field & x) const IColumn & ValueWithInfinity::getColumnIfFinite() const { +#ifndef NDEBUG if (type != NORMAL) throw Exception("Trying to get column of infinite type", ErrorCodes::LOGICAL_ERROR); +#endif + return *column; } diff --git a/src/Interpreters/Set.h b/src/Interpreters/Set.h index c9605d4e11e..3a16d9ed094 100644 --- a/src/Interpreters/Set.h +++ b/src/Interpreters/Set.h @@ -227,6 +227,8 @@ public: size_t size() const { return ordered_set.at(0)->size(); } + bool hasMonotonicFunctionsChain() const; + BoolMask checkInRange(const std::vector & key_ranges, const DataTypes & data_types); private: diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.cpp b/src/Storages/MergeTree/IMergeTreeDataPart.cpp index 3e0caa67518..5d799d257bc 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.cpp +++ b/src/Storages/MergeTree/IMergeTreeDataPart.cpp @@ -98,8 +98,8 @@ void IMergeTreeDataPart::MinMaxIndex::update(const Block & block, const Names & for (size_t i = 0; i < column_names.size(); ++i) { - Field min_value; - Field max_value; + FieldRef min_value; + FieldRef max_value; const ColumnWithTypeAndName & column = block.getByName(column_names[i]); column.column->getExtremes(min_value, max_value); diff --git a/src/Storages/MergeTree/KeyCondition.cpp b/src/Storages/MergeTree/KeyCondition.cpp index e994d254958..e755c4942a1 100644 --- a/src/Storages/MergeTree/KeyCondition.cpp +++ b/src/Storages/MergeTree/KeyCondition.cpp @@ -338,44 +338,6 @@ inline bool Range::equals(const Field & lhs, const Field & rhs) { return applyVi inline bool Range::less(const Field & lhs, const Field & rhs) { return applyVisitor(FieldVisitorAccurateLess(), lhs, rhs); } -FieldWithInfinity::FieldWithInfinity(const Field & field_) - : field(field_), - type(Type::NORMAL) -{ -} - -FieldWithInfinity::FieldWithInfinity(Field && field_) - : field(std::move(field_)), - type(Type::NORMAL) -{ -} - -FieldWithInfinity::FieldWithInfinity(const Type type_) - : type(type_) -{ -} - -FieldWithInfinity FieldWithInfinity::getMinusInfinity() -{ - return FieldWithInfinity(Type::MINUS_INFINITY); -} - -FieldWithInfinity FieldWithInfinity::getPlusInfinity() -{ - return FieldWithInfinity(Type::PLUS_INFINITY); -} - -bool FieldWithInfinity::operator<(const FieldWithInfinity & other) const -{ - return type < other.type || (type == other.type && type == Type::NORMAL && field < other.field); -} - -bool FieldWithInfinity::operator==(const FieldWithInfinity & other) const -{ - return type == other.type && (type != Type::NORMAL || field == other.field); -} - - /** Calculate expressions, that depend only on constants. * For index to work when something like "WHERE Date = toDate(now())" is written. */ @@ -480,24 +442,41 @@ bool KeyCondition::getConstant(const ASTPtr & expr, Block & block_with_constants } -static void applyFunction( +static Field applyFunctionForField( const FunctionBasePtr & func, - const DataTypePtr & arg_type, const Field & arg_value, - DataTypePtr & res_type, Field & res_value) + const DataTypePtr & arg_type, + const Field & arg_value) { - res_type = func->getReturnType(); - Block block { { arg_type->createColumnConst(1, arg_value), arg_type, "x" }, - { nullptr, res_type, "y" } + { nullptr, func->getReturnType(), "y" } }; func->execute(block, {0}, 1, 1); - - block.safeGetByPosition(1).column->get(0, res_value); + return (*block.safeGetByPosition(1).column)[0]; } +static FieldRef applyFunction(FunctionBasePtr & func, const DataTypePtr & current_type, const FieldRef & field) +{ + /// Fallback for fields without block reference. + if (field.isExplicit()) + return applyFunctionForField(func, current_type, field); + + String result_name = "_" + func->getName() + "_" + toString(field.column_idx); + size_t result_idx; + const auto & block = field.block; + if (!block->has(result_name)) + { + result_idx = block->columns(); + field.block->insert({nullptr, func->getReturnType(), result_name}); + func->execute(*block, {field.column_idx}, result_idx, block->rows()); + } + else + result_idx = block->getPositionByName(result_name); + + return {field.block, field.row_idx, result_idx}; +} void KeyCondition::traverseAST(const ASTPtr & node, const Context & context, Block & block_with_constants) { @@ -569,12 +548,8 @@ bool KeyCondition::canConstantBeWrappedByMonotonicFunctions( return false; // Apply the next transformation step - DataTypePtr new_type; - applyFunction(a.function_base, out_type, out_value, new_type, out_value); - if (!new_type) - return false; - - out_type.swap(new_type); + out_value = applyFunctionForField(a.function_base, out_type, out_value); + out_type = a.function_base->getReturnType(); expr_name = a.result_name; // Transformation results in a key expression, accept @@ -957,8 +932,8 @@ String KeyCondition::toString() const template static BoolMask forAnyHyperrectangle( size_t key_size, - const Field * key_left, - const Field * key_right, + const FieldRef * key_left, + const FieldRef * key_right, bool left_bounded, bool right_bounded, std::vector & hyperrectangle, @@ -1049,8 +1024,8 @@ static BoolMask forAnyHyperrectangle( BoolMask KeyCondition::checkInRange( size_t used_key_size, - const Field * left_key, - const Field * right_key, + const FieldRef * left_key, + const FieldRef * right_key, const DataTypes & data_types, bool right_bounded, BoolMask initial_mask) const @@ -1102,19 +1077,12 @@ std::optional KeyCondition::applyMonotonicFunctionsChainToRange( return {}; } - /// Apply the function. - DataTypePtr new_type; if (!key_range.left.isNull()) - applyFunction(func, current_type, key_range.left, new_type, key_range.left); + key_range.left = applyFunction(func, current_type, key_range.left); if (!key_range.right.isNull()) - applyFunction(func, current_type, key_range.right, new_type, key_range.right); + key_range.right = applyFunction(func, current_type, key_range.right); - if (!new_type) - { - return {}; - } - - current_type.swap(new_type); + current_type = func->getReturnType(); if (!monotonicity.is_positive) key_range.swapLeftAndRight(); @@ -1220,8 +1188,8 @@ BoolMask KeyCondition::checkInHyperrectangle( BoolMask KeyCondition::checkInRange( size_t used_key_size, - const Field * left_key, - const Field * right_key, + const FieldRef * left_key, + const FieldRef * right_key, const DataTypes & data_types, BoolMask initial_mask) const { @@ -1231,8 +1199,8 @@ BoolMask KeyCondition::checkInRange( bool KeyCondition::mayBeTrueInRange( size_t used_key_size, - const Field * left_key, - const Field * right_key, + const FieldRef * left_key, + const FieldRef * right_key, const DataTypes & data_types) const { return checkInRange(used_key_size, left_key, right_key, data_types, true, BoolMask::consider_only_can_be_true).can_be_true; @@ -1241,7 +1209,7 @@ bool KeyCondition::mayBeTrueInRange( BoolMask KeyCondition::checkAfter( size_t used_key_size, - const Field * left_key, + const FieldRef * left_key, const DataTypes & data_types, BoolMask initial_mask) const { @@ -1251,7 +1219,7 @@ BoolMask KeyCondition::checkAfter( bool KeyCondition::mayBeTrueAfter( size_t used_key_size, - const Field * left_key, + const FieldRef * left_key, const DataTypes & data_types) const { return checkInRange(used_key_size, left_key, nullptr, data_types, false, BoolMask::consider_only_can_be_true).can_be_true; @@ -1382,4 +1350,13 @@ size_t KeyCondition::getMaxKeyColumn() const return res; } +bool KeyCondition::hasMonotonicFunctionsChain() const +{ + for (const auto & element : rpn) + if (!element.monotonic_functions_chain.empty() + || (element.set_index && element.set_index->hasMonotonicFunctionsChain())) + return true; + return false; +} + } diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index 8667e0aea27..a7cdd1f1e0a 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -15,10 +15,6 @@ namespace DB { -namespace ErrorCodes -{ - extern const int BAD_TYPE_OF_FIELD; -} class IFunction; using FunctionBasePtr = std::shared_ptr; @@ -26,6 +22,35 @@ using FunctionBasePtr = std::shared_ptr; class ExpressionActions; using ExpressionActionsPtr = std::shared_ptr; +/** A field, that can be stored in two reperesenation: + * - A standalone field. + * - A field with reference to it's position in block. + * It's needed for execution functions on ranges during + * index analysis. If function was executed once for field, + * it's result would be cached for all block for which field's reference points to. + */ +struct FieldRef : public Field +{ + using SharedBlock = std::shared_ptr; + + FieldRef() = default; + + /// Create as explicit field without block. + template + FieldRef(const T & value) : Field(value) {} + + /// Create as reference to field in block. + FieldRef(const SharedBlock & block_, size_t row_idx_, size_t column_idx_) + : Field((*block_->getByPosition(column_idx_).column)[row_idx_]), + block(block_), row_idx(row_idx_), column_idx(column_idx_) {} + + bool isExplicit() const { return block == nullptr; } + + SharedBlock block; + size_t row_idx; + size_t column_idx; +}; + /** Range with open or closed ends; possibly unbounded. */ struct Range @@ -35,8 +60,8 @@ private: static bool less(const Field & lhs, const Field & rhs); public: - Field left; /// the left border, if any - Field right; /// the right border, if any + FieldRef left; /// the left border, if any + FieldRef right; /// the right border, if any bool left_bounded = false; /// bounded at the left bool right_bounded = false; /// bounded at the right bool left_included = false; /// includes the left border, if any @@ -46,11 +71,11 @@ public: Range() {} /// One point. - Range(const Field & point) + Range(const FieldRef & point) : left(point), right(point), left_bounded(true), right_bounded(true), left_included(true), right_included(true) {} /// A bounded two-sided range. - Range(const Field & left_, bool left_included_, const Field & right_, bool right_included_) + Range(const FieldRef & left_, bool left_included_, const FieldRef & right_, bool right_included_) : left(left_), right(right_), left_bounded(true), right_bounded(true), left_included(left_included_), right_included(right_included_) @@ -58,7 +83,7 @@ public: shrinkToIncludedIfPossible(); } - static Range createRightBounded(const Field & right_point, bool right_included) + static Range createRightBounded(const FieldRef & right_point, bool right_included) { Range r; r.right = right_point; @@ -68,7 +93,7 @@ public: return r; } - static Range createLeftBounded(const Field & left_point, bool left_included) + static Range createLeftBounded(const FieldRef & left_point, bool left_included) { Range r; r.left = left_point; @@ -84,7 +109,7 @@ public: */ void shrinkToIncludedIfPossible() { - if (left_bounded && !left_included) + if (left.isExplicit() && left_bounded && !left_included) { if (left.getType() == Field::Types::UInt64 && left.get() != std::numeric_limits::max()) { @@ -97,7 +122,7 @@ public: left_included = true; } } - if (right_bounded && !right_included) + if (right.isExplicit() && right_bounded && !right_included) { if (right.getType() == Field::Types::UInt64 && right.get() != std::numeric_limits::min()) { @@ -120,13 +145,13 @@ public: } /// x contained in the range - bool contains(const Field & x) const + bool contains(const FieldRef & x) const { return !leftThan(x) && !rightThan(x); } /// x is to the left - bool rightThan(const Field & x) const + bool rightThan(const FieldRef & x) const { return (left_bounded ? !(less(left, x) || (left_included && equals(x, left))) @@ -134,7 +159,7 @@ public: } /// x is to the right - bool leftThan(const Field & x) const + bool leftThan(const FieldRef & x) const { return (right_bounded ? !(less(x, right) || (right_included && equals(x, right))) @@ -195,42 +220,6 @@ public: String toString() const; }; - -/// Class that extends arbitrary objects with infinities, like +-inf for floats -class FieldWithInfinity -{ -public: - enum Type - { - MINUS_INFINITY = -1, - NORMAL = 0, - PLUS_INFINITY = 1 - }; - - explicit FieldWithInfinity(const Field & field_); - FieldWithInfinity(Field && field_); - - static FieldWithInfinity getMinusInfinity(); - static FieldWithInfinity getPlusInfinity(); - - bool operator<(const FieldWithInfinity & other) const; - bool operator==(const FieldWithInfinity & other) const; - - Field getFieldIfFinite() const - { - if (type != NORMAL) - throw Exception("Trying to get field of infinite type", ErrorCodes::BAD_TYPE_OF_FIELD); - return field; - } - -private: - Field field; - Type type; - - FieldWithInfinity(const Type type_); -}; - - /** Condition on the index. * * Consists of the conditions for the key belonging to all possible ranges or sets, @@ -261,8 +250,8 @@ public: /// one of the resulting mask components (see BoolMask::consider_only_can_be_XXX). BoolMask checkInRange( size_t used_key_size, - const Field * left_key, - const Field * right_key, + const FieldRef * left_key, + const FieldRef* right_key, const DataTypes & data_types, BoolMask initial_mask = BoolMask(false, false)) const; @@ -270,7 +259,7 @@ public: /// left_key must contain all the fields in the sort_descr in the appropriate order. BoolMask checkAfter( size_t used_key_size, - const Field * left_key, + const FieldRef * left_key, const DataTypes & data_types, BoolMask initial_mask = BoolMask(false, false)) const; @@ -278,15 +267,15 @@ public: /// This is more efficient than checkInRange(...).can_be_true. bool mayBeTrueInRange( size_t used_key_size, - const Field * left_key, - const Field * right_key, + const FieldRef * left_key, + const FieldRef * right_key, const DataTypes & data_types) const; /// Same as checkAfter, but calculate only may_be_true component of a result. /// This is more efficient than checkAfter(...).can_be_true. bool mayBeTrueAfter( size_t used_key_size, - const Field * left_key, + const FieldRef * left_key, const DataTypes & data_types) const; /// Checks that the index can not be used. @@ -295,6 +284,8 @@ public: /// Get the maximum number of the key element used in the condition. size_t getMaxKeyColumn() const; + bool hasMonotonicFunctionsChain() const; + /// Impose an additional condition: the value in the column `column` must be in the range `range`. /// Returns whether there is such a column in the key. bool addCondition(const String & column, const Range & range); @@ -374,8 +365,8 @@ public: private: BoolMask checkInRange( size_t used_key_size, - const Field * left_key, - const Field * right_key, + const FieldRef * left_key, + const FieldRef * right_key, const DataTypes & data_types, bool right_bounded, BoolMask initial_mask) const; diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 370286117ae..39de45e07e0 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -1201,11 +1201,23 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( * If fits, split it into smaller ones and put them on the stack. If not, discard it. * If the segment is already of one mark length, add it to response and discard it. */ - std::vector ranges_stack{ {0, marks_count} }; + std::vector ranges_stack = { {0, marks_count} }; + + auto index_block = std::make_shared(); + for (size_t i = 0; i < used_key_size; ++i) + index_block->insert({index[i], data.primary_key_data_types[i], data.primary_key_columns[i]}); + + std::function create_field_ref; + /// If there is no monotonic functions, there is no need to save block reference. + /// Passing explicit field to FieldRef allows to optimize ranges and shows better performance while reading the field. + if (key_condition.hasMonotonicFunctionsChain()) + create_field_ref = [&index_block](size_t row, size_t column) -> FieldRef { return {index_block, row, column}; }; + else + create_field_ref = [&index](size_t row, size_t column) -> FieldRef { return (*index[column])[row]; }; /// NOTE Creating temporary Field objects to pass to KeyCondition. - Row index_left(used_key_size); - Row index_right(used_key_size); + std::vector index_left(used_key_size); + std::vector index_right(used_key_size); while (!ranges_stack.empty()) { @@ -1216,7 +1228,7 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( if (range.end == marks_count && !has_final_mark) { for (size_t i = 0; i < used_key_size; ++i) - index[i]->get(range.begin, index_left[i]); + index_left[i] = create_field_ref(range.begin, i); may_be_true = key_condition.mayBeTrueAfter( used_key_size, index_left.data(), data.primary_key_data_types); @@ -1228,8 +1240,8 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( for (size_t i = 0; i < used_key_size; ++i) { - index[i]->get(range.begin, index_left[i]); - index[i]->get(range.end, index_right[i]); + index_left[i] = create_field_ref(range.begin, i); + index_right[i] = create_field_ref(range.end, i); } may_be_true = key_condition.mayBeTrueInRange( @@ -1254,9 +1266,9 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( size_t end; for (end = range.end; end > range.begin + step; end -= step) - ranges_stack.push_back(MarkRange(end - step, end)); + ranges_stack.emplace_back(end - step, end); - ranges_stack.push_back(MarkRange(range.begin, end)); + ranges_stack.emplace_back(range.begin, end); } } } diff --git a/src/Storages/MergeTree/MergeTreeIndexMinMax.cpp b/src/Storages/MergeTree/MergeTreeIndexMinMax.cpp index 122f038fee6..220fc70c549 100644 --- a/src/Storages/MergeTree/MergeTreeIndexMinMax.cpp +++ b/src/Storages/MergeTree/MergeTreeIndexMinMax.cpp @@ -100,8 +100,8 @@ void MergeTreeIndexAggregatorMinMax::update(const Block & block, size_t * pos, s size_t rows_read = std::min(limit, block.rows() - *pos); - Field field_min; - Field field_max; + FieldRef field_min; + FieldRef field_max; for (size_t i = 0; i < index.columns.size(); ++i) { const auto & column = block.getByName(index.columns[i]).column; diff --git a/tests/performance/set_index.xml b/tests/performance/set_index.xml index 090d8ac8c08..f158c481d93 100644 --- a/tests/performance/set_index.xml +++ b/tests/performance/set_index.xml @@ -14,7 +14,14 @@ - SELECT count() FROM test_in WHERE a IN (SELECT rand(1) FROM zeros(100000)) SETTINGS max_rows_to_read = 1, read_overflow_mode = 'break' + SELECT count() FROM test_in WHERE a IN (SELECT rand(1) FROM numbers(100000)) SETTINGS max_rows_to_read = 1, read_overflow_mode = 'break' + + SELECT count() FROM test_in WHERE toInt64(a) IN (SELECT toInt64(rand(1)) FROM numbers(100000)) settings max_rows_to_read=1, read_overflow_mode='break' + + + SELECT count() FROM test_in WHERE -toInt64(a) IN (SELECT toInt64(rand(1)) FROM numbers(100000)) settings max_rows_to_read=1, read_overflow_mode='break' + + SELECT count() FROM test_in WHERE -toInt64(a) NOT IN (SELECT toInt64(rand(1)) FROM numbers(100000)) settings max_rows_to_read=1, read_overflow_mode='break' SELECT count() FROM numbers(1000) WHERE toString(number) IN ('41577', '83972', '51697', '50014', '37553', '93459', '87438', '95971', '83186', '74326', '67871', '50406', '83678', '29655', '18580', '83905', '61518', '29059', '56700', '82787', '98672', '30884', '81822', '39850', '80852', '57627', '91346', '64522', '17781', '49467', '41099', '41929', '85618', '91389', '68564', '91769', '81219', '52218', '37220', '97097', '2129', '9886', '52049', '34847', '25364', '36429', '76897', '71868', '58121', '71199', '84819', '69991', '34046', '64507', '34892', '24228', '36986', '28588', '51159', '53444', '80531', '9941', '20256', '48103', '32565', '62890', '5379', '60302', '46434', '3205', '18821', '31030', '19794', '71557', '71703', '15024', '14004', '82164', '95659', '40227', '83358', '24395', '9610', '19814', '48491', '66412', '16012', '71586', '42143', '51103', '24463', '89949', '35694', '39193', '63904', '40489', '77144', '94014', '84836', '9980', '46554', '43905', '25588', '25205', '72624', '10249', '35888', '98478', '99030', '26834', '31', '81499', '14847', '82997', '92357', '92893', '17426', '56630', '22252', '68119', '62710', '8740', '82144', '79916', '23391', '30192', '99271', '96435', '44237', '98327', '69481', '16691', '13643', '84554', '38571', '70926', '99283', '79000', '20926', '86495', '4834', '1222', '39486', '57697', '58002', '40790', '15623', '3999', '31515', '12694', '26143', '35951', '54085', '97534', '35329', '73535', '88715', '29572', '75799', '45166', '32066', '48023', '69523', '93150', '8740', '96790', '15534', '63252', '5142', '67045', '93992', '16663', '292', '63924', '6588', '12190', '31506', '69590', '35394', '55168', '65223', '79183', '32600', '69676', '28316', '72111', '53531', '15073', '41127', '73451', '24725', '61647', '65315', '41143', '26493', '95608', '34407', '76098', '53105', '83691', '48755', '35696', '62587', '81826', '3963', '45766', '82751', '12430', '97685', '29919', '78155', '71636', '50215', '89734', '9892', '47151', '54855', '3428', '9712', '52592', '2403', '79602', '81243', '79859', '57361', '82000', '42107', '28860', '99591', '28296', '57337', '64969', '32332', '25535', '30924', '21313', '32554', '17342', '87311', '19825', '24898', '61323', '83209', '79322', '79009', '50746', '33396', '62033', '16548', '17427', '24073', '34640', '52368', '4724', '80408', '40', '33787', '16666', '19665', '86751', '27264', '2241', '88134', '53566', '10589', '79711', '92823', '58972', '91767', '60885', '51659', '7867', '96849', '30360', '20914', '9584', '1250', '22871', '23282', '99312', '4683', '33429', '68361', '82614', '81440', '47863', '69790', '11968', '75210', '66854', '37002', '61142', '71514', '1588', '42336', '11069', '26291', '2261', '71056', '13492', '9133', '91216', '72207', '71586', '86535', '83898', '24392', '45384', '48545', '61972', '503', '80180', '35834', '97025', '70411', '55039', '35430', '27631', '82533', '96831', '74077', '42533', '14451', '26943', '53783', '69489', '71969', '8432', '37230', '61348', '19472', '59115', '9886', '50951', '57109', '7141', '1902', '84130', '4323', '55889', '47784', '2220', '75988', '66988', '63721', '8131', '95601', '95207', '2311', '26541', '50991', '6717', '2969', '71857', '51034', '65958', '94716', '90275', '21012', '46859', '7984', '31131', '46457', '69578', '44540', '7294', '80117', '9925', '60155', '90608', '82684', '32193', '87071', '28006', '87604', '24501', '79087', '2848', '29237', '11221', '81319', '40966', '87641', '35325', '78705', '88636', '78717', '62831', '56390', '99271', '43821', '14453', '17923', '62695', '77322', '21038', '67677', '41271', '4376', '65426', '46091', '19887', '97251', '55583', '58763', '3826', '35037', '73533', '64267', '82319', '9836', '42622', '96829', '16363', '10455', '49290', '99992', '98229', '66356', '59087', '73998', '25986', '4279', '56790', '69540', '588', '36620', '60358', '45056', '89297', '42740', '8323', '19245', '82417', '41431', '699', '11554', '73910', '44491', '56019', '68901', '45816', '68126', '89379', '23885', '13263', '56395', '73130', '19089', '23771', '10335', '48547', '16903', '6453', '33560', '89668', '38159', '43177', '90655', '49712', '62', '66920', '34180', '12150', '48564', '39538', '85026', '87195', '14928', '8956', '71157', '53287', '39161', '67583', '83309', '92054', '86977', '56188', '15229', '88170', '60894', '58497', '89254', '40082', '86890', '60161', '97291', '45878', '23368', '14577', '92870', '37017', '97356', '99426', '76061', '89186', '99751', '85153', '61580', '39360', '90107', '25603', '26798', '76224', '6469', '7912', '69838', '16404', '67497', '28965', '80836', '80365', '91249', '48713', '17113', '33090', '40793', '70450', '66689', '83698', '17802', '43869', '13355', '18959', '79411', '87930', '9265', '37504', '44876', '97234', '94149', '35040', '22049', '49248', '6535', '36080', '28346', '94437', '78319', '17961', '89056', '56161', '35810', '41632', '45494', '53351', '89729', '99510', '51584', '59688', '6193', '70809', '51093', '92589', '90247', '34910', '78235', '17362', '49423', '63324', '525', '37638', '72325', '89356', '15298', '59116', '17848', '65429', '27029', '84781', '70247', '8825', '35082', '70451', '22522', '58125', '91879', '90531', '2478', '463', '37902', '54405', '87267', '72688', '22803', '33134', '35177', '84551', '44974', '88375', '76407', '27774', '33849', '19915', '82014', '80434', '26380', '48777', '53811', '14838', '26829', '56441', '99869', '49574', '85476', '19723', '16907', '4018', '37338', '78510', '47912', '13030', '65277', '95716', '67363', '21393', '89887', '78842', '81650', '903', '17436', '30704', '49223', '27198', '25500', '52214', '54258', '70082', '53950', '49312', '43615', '99473', '94348', '53661', '96213', '96346', '62010', '38268', '32861', '75660', '10392', '89491', '68335', '29817', '88706', '24184', '36298', '43440', '21626', '26535', '44560', '46363', '12534', '99070', '95606', '33714', '73070', '8303', '29853', '23014', '99982', '4530', '14955', '45803', '50', '90750', '30394', '81276', '95563', '47314', '58520', '91299', '88944', '54402', '67405', '29253', '47079', '71734', '99728', '17652', '13307', '35556', '18962', '26780', '17771', '53712', '60055', '37628', '35830', '90739', '61151', '41309', '27652', '3051', '53167', '98417', '19382', '36833', '75085', '65374', '87732', '30352', '31776', '32765', '97565', '92199', '49050', '29503', '51024', '18834', '8515', '24069', '96216', '10777', '90680', '18974', '68884', '85305', '36007', '56707', '4212', '47352', '34426', '13185', '92939', '95782', '70577', '58080', '98279', '3906', '5065', '56896', '16382', '31273', '17117', '98602', '12786', '24086', '63970', '72756', '35798', '82367', '7356', '53398', '68503', '2962', '16425', '67334', '68461', '65439', '15620', '70906', '29649', '46461', '74602', '38012', '71714', '16825', '89480', '53386', '88532', '35104', '28556', '82120', '23155', '23347', '24797', '60061', '54962', '99427', '82248', '82447', '39968', '63727', '27431', '81511', '91168', '71425', '80740', '84127', '40717', '15503', '15419', '46594', '61263', '19212', '53175', '70724', '74445', '23034', '71818', '40246', '18886', '53066', '4880', '83701', '86107', '87862', '44751', '392', '73440', '90291', '93395', '20894', '38463', '32664', '55158', '20090', '50004', '79070', '98471', '85478', '96615', '68149', '78334', '97752', '73207', '71678', '91238', '96757', '82598', '194', '35797', '45120', '60782', '28721', '17676', '78066', '60957', '11826', '51563', '50516', '16485', '47053', '31738', '48923', '23554', '96850', '42033', '73701', '78607', '45979', '54571', '12415', '31693', '15356', '36902', '9126', '3767', '3295', '90402', '24005', '95350', '67033', '49137', '72606', '51899', '17522', '31957', '44641', '53982', '23767', '68257', '15766', '19995', '2107', '48788', '11765', '91055', '46576', '54651', '50381', '62827', '73636', '46606', '98753', '37631', '70441', '87916', '66983', '33870', '31125', '12904', '57040', '4874', '58632', '42037', '18782', '5998', '18974', '57949', '81010', '90407', '99874', '20462', '89949', '10952', '71454', '95130', '46115', '3518', '13384', '69039', '79482', '22076', '59782', '32042', '40930', '60243', '29298', '6790', '46985', '44398', '85631', '14380', '66179', '2629', '32126', '49833', '14118', '58492', '31493', '81172', '96638', '8745', '89663', '76842', '78633', '41373', '83721', '42886', '11123', '32739', '11051', '1303', '92314', '83324', '85600', '44276', '69064', '56125', '84650', '31028', '12628', '14502', '64764', '39405', '44855', '79046', '51716', '46824', '83389', '1941', '1257', '9280', '73176', '84729', '2579', '63366', '22606', '35541', '51096', '13447', '18355', '68037', '28436', '94116', '81070', '78355', '67897', '5296', '32742', '77645', '91853', '18767', '67949', '40963', '5792', '17278', '25597', '41884', '80829', '7099', '18645', '60295', '12082', '81800', '78415', '18082', '38789', '16295', '72377', '74949', '55583', '66853', '15402', '72977', '15123', '99434', '34999', '21687', '76049', '42987', '83748', '88256', '66688', '21766', '20304', '29271', '10069', '19822', '11792', '42526', '74143', '17289', '30253', '6367', '20888', '12975', '94073', '98639', '30134', '26320', '65507', '69002', '53120', '4550', '38893', '18954', '38283', '54863', '17698', '99670', '10521', '92467', '60994', '18052', '48673', '35811', '87282', '62706', '16061', '53112', '22652', '37780', '55662', '26331', '49410', '79074', '10623', '69577', '79613', '9491', '31229', '43922', '84231', '58409', '36386', '46875', '74431', '76735', '38776', '23350', '7314', '9079', '51519', '98544', '70216', '63380', '90381', '1295', '46901', '58225', '55339', '89918', '75522', '35431', '89460', '49552', '89302', '23068', '28493', '3042', '25194', '59520', '9810', '95706', '81297', '89638', '54794', '94527', '45262', '97932', '78685', '6947', '22818', '48700', '9153', '12289', '22011', '58825', '93854', '65438', '4509', '33741', '28208', '69061', '48578', '40247', '77725', '31837', '39003', '69363', '78113', '76398', '97262', '67795', From 5ada959853275249ad7ef2aec5031a4b6651109b Mon Sep 17 00:00:00 2001 From: Anton Popov Date: Mon, 6 Apr 2020 13:36:56 +0300 Subject: [PATCH 009/208] improve performance of index analysis with monotonic functions --- src/Storages/MergeTree/KeyCondition.h | 8 ++--- .../MergeTree/MergeTreeDataSelectExecutor.cpp | 32 ++++++++++++------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index a7cdd1f1e0a..ffc0d46a2ec 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -31,22 +31,20 @@ using ExpressionActionsPtr = std::shared_ptr; */ struct FieldRef : public Field { - using SharedBlock = std::shared_ptr; - FieldRef() = default; /// Create as explicit field without block. template - FieldRef(const T & value) : Field(value) {} + FieldRef(T && value) : Field(std::forward(value)) {} /// Create as reference to field in block. - FieldRef(const SharedBlock & block_, size_t row_idx_, size_t column_idx_) + FieldRef(Block * block_, size_t row_idx_, size_t column_idx_) : Field((*block_->getByPosition(column_idx_).column)[row_idx_]), block(block_), row_idx(row_idx_), column_idx(column_idx_) {} bool isExplicit() const { return block == nullptr; } - SharedBlock block; + Block * block; size_t row_idx; size_t column_idx; }; diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 39de45e07e0..13e852765b7 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -1203,17 +1203,27 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( */ std::vector ranges_stack = { {0, marks_count} }; - auto index_block = std::make_shared(); - for (size_t i = 0; i < used_key_size; ++i) - index_block->insert({index[i], data.primary_key_data_types[i], data.primary_key_columns[i]}); - - std::function create_field_ref; + std::function create_field_ref; /// If there is no monotonic functions, there is no need to save block reference. - /// Passing explicit field to FieldRef allows to optimize ranges and shows better performance while reading the field. + /// Passing explicit field to FieldRef allows to optimize ranges and shows better performance. if (key_condition.hasMonotonicFunctionsChain()) - create_field_ref = [&index_block](size_t row, size_t column) -> FieldRef { return {index_block, row, column}; }; + { + auto index_block = std::make_shared(); + for (size_t i = 0; i < used_key_size; ++i) + index_block->insert({index[i], data.primary_key_data_types[i], data.primary_key_columns[i]}); + + create_field_ref = [index_block](size_t row, size_t column, FieldRef & field) + { + field = {index_block.get(), row, column}; + }; + } else - create_field_ref = [&index](size_t row, size_t column) -> FieldRef { return (*index[column])[row]; }; + { + create_field_ref = [&index](size_t row, size_t column, FieldRef & field) + { + index[column]->get(row, field); + }; + } /// NOTE Creating temporary Field objects to pass to KeyCondition. std::vector index_left(used_key_size); @@ -1228,7 +1238,7 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( if (range.end == marks_count && !has_final_mark) { for (size_t i = 0; i < used_key_size; ++i) - index_left[i] = create_field_ref(range.begin, i); + create_field_ref(range.begin, i, index_left[i]); may_be_true = key_condition.mayBeTrueAfter( used_key_size, index_left.data(), data.primary_key_data_types); @@ -1240,8 +1250,8 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( for (size_t i = 0; i < used_key_size; ++i) { - index_left[i] = create_field_ref(range.begin, i); - index_right[i] = create_field_ref(range.end, i); + create_field_ref(range.begin, i, index_left[i]); + create_field_ref(range.end, i, index_right[i]); } may_be_true = key_condition.mayBeTrueInRange( From 9c5cea3035a2f877426e32f05b8c0571c98f3fd6 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Mon, 6 Apr 2020 13:43:00 +0300 Subject: [PATCH 010/208] More tests and better token checks. --- .../tests/gtest_SplitTokenExtractor.cpp | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp index e2229792020..de78347ebbd 100644 --- a/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/dbms/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -62,16 +62,39 @@ TEST_P(SplitTokenExtractorTest, next) { SCOPED_TRACE(++i); ASSERT_TRUE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)); - EXPECT_EQ(expected_token, param.source.substr(token_start, token_len)) + + EXPECT_EQ(expected_token, std::string_view(data->data() + token_start, token_len)) << " token_start:" << token_start << " token_len: " << token_len; } - - ASSERT_FALSE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)); + ASSERT_FALSE(token_extractor.next(data->data(), data->size(), &pos, &token_start, &token_len)) + << "\n\t=> \"" << param.source.substr(token_start, token_len) << "\"" + << "\n\t" << token_start << ", " << token_len << ", " << pos << ", " << data->size(); } // Helper to allow strings with embedded '\0' chars. #define BINARY_STRING(str) std::string{str, sizeof(str) - 1} +INSTANTIATE_TEST_SUITE_P(NoTokens, + SplitTokenExtractorTest, + ::testing::ValuesIn(std::initializer_list{ + { + "Empty input sequence produces no tokens.", + "", + {} + }, + { + "Whitespace only", + " ", + {} + }, + { + "Whitespace only large string", + " \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r \t\v\n\r", + {} + } + }) +); + INSTANTIATE_TEST_SUITE_P(ShortSingleToken, SplitTokenExtractorTest, ::testing::ValuesIn(std::initializer_list{ From 2dc1eddfab04348c816ecc5ef3794f8376e491dc Mon Sep 17 00:00:00 2001 From: Anton Popov Date: Mon, 6 Apr 2020 16:35:11 +0300 Subject: [PATCH 011/208] fix FieldRef --- src/Storages/MergeTree/KeyCondition.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index ffc0d46a2ec..7c8b63eb800 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -44,9 +44,9 @@ struct FieldRef : public Field bool isExplicit() const { return block == nullptr; } - Block * block; - size_t row_idx; - size_t column_idx; + Block * block = nullptr; + size_t row_idx = 0; + size_t column_idx = 0; }; /** Range with open or closed ends; possibly unbounded. From 738e8a7ef8af5066eb99ac714708c72414d4ce69 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Mon, 6 Apr 2020 20:16:36 +0300 Subject: [PATCH 012/208] Minor test refactoring * using string literal for binary strings * sorted includes --- .../tests/gtest_SplitTokenExtractor.cpp | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/Storages/tests/gtest_SplitTokenExtractor.cpp b/src/Storages/tests/gtest_SplitTokenExtractor.cpp index de78347ebbd..9255e5ca817 100644 --- a/src/Storages/tests/gtest_SplitTokenExtractor.cpp +++ b/src/Storages/tests/gtest_SplitTokenExtractor.cpp @@ -5,14 +5,15 @@ #include -#include -#include -#include #include +#include +#include +#include namespace { using namespace DB; +using namespace std::literals::string_literals; } struct SplitTokenExtractorTestCase @@ -71,9 +72,6 @@ TEST_P(SplitTokenExtractorTest, next) << "\n\t" << token_start << ", " << token_len << ", " << pos << ", " << data->size(); } -// Helper to allow strings with embedded '\0' chars. -#define BINARY_STRING(str) std::string{str, sizeof(str) - 1} - INSTANTIATE_TEST_SUITE_P(NoTokens, SplitTokenExtractorTest, ::testing::ValuesIn(std::initializer_list{ @@ -98,11 +96,6 @@ INSTANTIATE_TEST_SUITE_P(NoTokens, INSTANTIATE_TEST_SUITE_P(ShortSingleToken, SplitTokenExtractorTest, ::testing::ValuesIn(std::initializer_list{ - { - "Empty input sequence produces no tokens.", - "", - {} - }, { "Short single token", "foo", @@ -144,7 +137,7 @@ INSTANTIATE_TEST_SUITE_P(MultipleTokens, }, { "Multiple tokens separated by non-printable chars", - BINARY_STRING("\0abc\1" "123\2XYZ\4"), + "\0abc\1" "123\2XYZ\4"s, { "abc", "123", "XYZ" } @@ -152,7 +145,7 @@ INSTANTIATE_TEST_SUITE_P(MultipleTokens, { "ASCII table is split into numeric, upper case and lower case letters", - BINARY_STRING("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16" + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16" "\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO" "PQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87" "\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c" @@ -160,7 +153,7 @@ INSTANTIATE_TEST_SUITE_P(MultipleTokens, "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6" "\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb" "\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0" - "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), + "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"s, { "0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", "\x80\x81\x82\x83\x84\x85\x86\x87" From 2951ed4f1dec9510a23118a78a9a677f3cb3e867 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 00:35:20 +0300 Subject: [PATCH 013/208] Corrected Common.RWLockDeadlock test --- src/Common/tests/gtest_rw_lock.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Common/tests/gtest_rw_lock.cpp b/src/Common/tests/gtest_rw_lock.cpp index dec4c732fd5..facd7a33c1c 100644 --- a/src/Common/tests/gtest_rw_lock.cpp +++ b/src/Common/tests/gtest_rw_lock.cpp @@ -150,9 +150,16 @@ TEST(Common, RWLockDeadlock) usleep(100000); usleep(100000); usleep(100000); + usleep(100000); try { auto holder2 = lock2->getLock(RWLockImpl::Read, "q1"); + if (!holder2) + { + throw Exception( + "Locking attempt timed out! Possible deadlock avoided. Client should retry.", + ErrorCodes::DEADLOCK_AVOIDED); + } } catch (const Exception & e) { @@ -174,9 +181,16 @@ TEST(Common, RWLockDeadlock) auto holder2 = lock2->getLock(RWLockImpl::Read, "q3"); usleep(100000); usleep(100000); + usleep(100000); try { auto holder1 = lock1->getLock(RWLockImpl::Read, "q3"); + if (!holder1) + { + throw Exception( + "Locking attempt timed out! Possible deadlock avoided. Client should retry.", + ErrorCodes::DEADLOCK_AVOIDED); + } } catch (const Exception & e) { From b98bc9afefb61645d30992b3f37dc489613363cd Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 02:44:45 +0300 Subject: [PATCH 014/208] Reworked RWLockImpl::getLock() + phase-fairness Timeout param added to getLock() method --- src/Common/RWLock.cpp | 295 ++++++++++++++++++++++-------------------- src/Common/RWLock.h | 45 ++++--- 2 files changed, 185 insertions(+), 155 deletions(-) diff --git a/src/Common/RWLock.cpp b/src/Common/RWLock.cpp index 5dfc1b55c63..a282c1c6a91 100644 --- a/src/Common/RWLock.cpp +++ b/src/Common/RWLock.cpp @@ -29,19 +29,17 @@ namespace DB namespace ErrorCodes { extern const int LOGICAL_ERROR; - extern const int DEADLOCK_AVOIDED; } -/** A single-use object that represents lock's ownership +/** A one-time-use-object that represents lock ownership * For the purpose of exception safety guarantees LockHolder is to be used in two steps: - * 1. Create an instance (allocating all the memory needed) + * 1. Create an instance (allocating all the needed memory) * 2. Associate the instance with the lock (attach to the lock and locking request group) */ class RWLockImpl::LockHolderImpl { bool bound{false}; - Type lock_type; String query_id; CurrentMetrics::Increment active_client_increment; RWLock parent; @@ -53,24 +51,30 @@ public: /// Implicit memory allocation for query_id is done here LockHolderImpl(const String & query_id_, Type type) - : lock_type{type}, query_id{query_id_}, - active_client_increment{ + : query_id{query_id_} + , active_client_increment{ type == Type::Read ? CurrentMetrics::RWLockActiveReaders : CurrentMetrics::RWLockActiveWriters} { } - ~LockHolderImpl(); + ~LockHolderImpl() + { + if (bound && parent != nullptr) + parent->unlock(it_group, query_id); + else + active_client_increment.destroy(); + } private: /// A separate method which binds the lock holder to the owned lock /// N.B. It is very important that this method produces no allocations bool bindWith(RWLock && parent_, GroupsContainer::iterator it_group_) noexcept { - if (bound) + if (bound || parent_ == nullptr) return false; it_group = it_group_; parent = std::move(parent_); - ++it_group->refererrs; + ++it_group->requests; bound = true; return true; } @@ -79,56 +83,27 @@ private: }; -namespace -{ - /// Global information about all read locks that query has. It is needed to avoid some type of deadlocks. - - class QueryLockInfo - { - private: - mutable std::mutex mutex; - std::map queries; - - public: - void add(const String & query_id) - { - std::lock_guard lock(mutex); - - const auto res = queries.emplace(query_id, 1); // may throw - if (!res.second) - ++res.first->second; - } - - void remove(const String & query_id) noexcept - { - std::lock_guard lock(mutex); - - const auto query_it = queries.find(query_id); - if (query_it != queries.cend() && --query_it->second == 0) - queries.erase(query_it); - } - - void check(const String & query_id) const - { - std::lock_guard lock(mutex); - - if (queries.find(query_id) != queries.cend()) - throw Exception("Possible deadlock avoided. Client should retry.", ErrorCodes::DEADLOCK_AVOIDED); - } - }; - - QueryLockInfo all_read_locks; -} - - -/** To guarantee that we do not get any piece of our data corrupted: +/** General algorithm: + * Step 1. Try the FastPath (for both Reads/Writes) + * Step 2. Find ourselves request group: attach to existing or create a new one + * Step 3. Wait/timed wait for ownership signal + * Step 3a. Check if we must handle timeout and exit + * Step 4. Persist lock ownership + * + * To guarantee that we do not get any piece of our data corrupted: * 1. Perform all actions that include allocations before changing lock's internal state * 2. Roll back any changes that make the state inconsistent * * Note: "SM" in the commentaries below stands for STATE MODIFICATION */ -RWLockImpl::LockHolder RWLockImpl::getLock(RWLockImpl::Type type, const String & query_id) +RWLockImpl::LockHolder +RWLockImpl::getLock(RWLockImpl::Type type, const String & query_id, const std::chrono::milliseconds & lock_timeout_ms) { + const auto lock_deadline_tp = + (lock_timeout_ms == std::chrono::milliseconds(0)) + ? std::chrono::time_point::max() + : std::chrono::steady_clock::now() + lock_timeout_ms; + const bool request_has_query_id = query_id != NO_QUERY; Stopwatch watch(CLOCK_MONOTONIC_COARSE); @@ -145,100 +120,111 @@ RWLockImpl::LockHolder RWLockImpl::getLock(RWLockImpl::Type type, const String & /// This object is placed above unique_lock, because it may lock in destructor. auto lock_holder = std::make_shared(query_id, type); - std::unique_lock lock(mutex); + std::unique_lock state_lock(internal_state_mtx); /// The FastPath: /// Check if the same query_id already holds the required lock in which case we can proceed without waiting if (request_has_query_id) { - const auto it_query = owner_queries.find(query_id); - if (it_query != owner_queries.end()) + const auto owner_query_it = owner_queries.find(query_id); + if (owner_query_it != owner_queries.end()) { - const auto current_owner_group = queue.begin(); + if (wrlock_owner != writers_queue.end()) + throw Exception( + "RWLockImpl::getLock(): RWLock is already locked in exclusive mode", + ErrorCodes::LOGICAL_ERROR); - /// XXX: it means we can't upgrade lock from read to write! + /// Lock upgrading is not supported if (type == Write) throw Exception( "RWLockImpl::getLock(): Cannot acquire exclusive lock while RWLock is already locked", ErrorCodes::LOGICAL_ERROR); - if (current_owner_group->type == Write) - throw Exception( - "RWLockImpl::getLock(): RWLock is already locked in exclusive mode", - ErrorCodes::LOGICAL_ERROR); - /// N.B. Type is Read here, query_id is not empty and it_query is a valid iterator - all_read_locks.add(query_id); /// SM1: may throw on insertion (nothing to roll back) - ++it_query->second; /// SM2: nothrow - lock_holder->bindWith(shared_from_this(), current_owner_group); /// SM3: nothrow + ++owner_query_it->second; /// SM1: nothrow + lock_holder->bindWith(shared_from_this(), rdlock_owner); /// SM2: nothrow finalize_metrics(); return lock_holder; } } - /** If the query already has any active read lock and tries to acquire another read lock - * but it is not in front of the queue and has to wait, deadlock is possible: - * - * Example (four queries, two RWLocks - 'a' and 'b'): - * - * --> time --> - * - * q1: ra rb - * q2: wa - * q3: rb ra - * q4: wb - * - * We will throw an exception instead. - */ - - if (type == Type::Write || queue.empty() || queue.back().type == Type::Write) + if (type == Type::Write) { - if (type == Type::Read && request_has_query_id && !queue.empty()) - all_read_locks.check(query_id); - - /// Create a new group of locking requests - queue.emplace_back(type); /// SM1: may throw (nothing to roll back) + writers_queue.emplace_back(type); /// SM1: may throw (nothing to roll back) } - else if (request_has_query_id && queue.size() > 1) - all_read_locks.check(query_id); + else if (readers_queue.empty() || + (rdlock_owner == readers_queue.begin() && !writers_queue.empty())) + { + readers_queue.emplace_back(type); /// SM1: may throw (nothing to roll back) + } + GroupsContainer::iterator it_group = + (type == Type::Write) ? std::prev(writers_queue.end()) : std::prev(readers_queue.end()); - GroupsContainer::iterator it_group = std::prev(queue.end()); + if (rdlock_owner == readers_queue.end() && wrlock_owner == writers_queue.end()) + { + if (type == Type::Read) + { + rdlock_owner = it_group; /// SM2: nothrow + } + else + { + wrlock_owner = it_group; /// SM2: nothrow + } + } + else + { + /// Wait until our group becomes the lock owner + const auto predicate = [&] () { return it_group == (type == Read ? rdlock_owner : wrlock_owner); }; - /// We need to reference the associated group before waiting to guarantee - /// that this group does not get deleted prematurely - ++it_group->refererrs; + if (lock_deadline_tp == std::chrono::time_point::max()) + { + ++it_group->requests; + it_group->cv.wait(state_lock, predicate); + --it_group->requests; + } + else + { + ++it_group->requests; + const auto wait_result = it_group->cv.wait_until(state_lock, lock_deadline_tp, predicate); + --it_group->requests; - /// Wait a notification until we will be the only in the group. - it_group->cv.wait(lock, [&] () { return it_group == queue.begin(); }); + /// Step 3a. Check if we must handle timeout and exit + if (!wait_result) /// Wait timed out! + { + if (it_group->requests == 0) + { + /// Roll back SM1 + if (type == Read) + { + readers_queue.erase(it_group); /// Rollback(SM1): nothrow + } + else + { + writers_queue.erase(it_group); /// Rollback(SM1): nothrow + } + } - --it_group->refererrs; + return nullptr; + } + } + } if (request_has_query_id) { try { - if (type == Type::Read) - all_read_locks.add(query_id); /// SM2: may throw on insertion - /// and is safe to roll back unconditionally const auto emplace_res = - owner_queries.emplace(query_id, 1); /// SM3: may throw on insertion + owner_queries.emplace(query_id, 1); /// SM2: may throw on insertion if (!emplace_res.second) - ++emplace_res.first->second; /// SM4: nothrow + ++emplace_res.first->second; /// SM3: nothrow } catch (...) { /// Methods std::list<>::emplace_back() and std::unordered_map<>::emplace() provide strong exception safety - /// We only need to roll back the changes to these objects: all_read_locks and the locking queue - if (type == Type::Read) - all_read_locks.remove(query_id); /// Rollback(SM2): nothrow - - if (it_group->refererrs == 0) - { - const auto next = queue.erase(it_group); /// Rollback(SM1): nothrow - if (next != queue.end()) - next->cv.notify_all(); - } + /// We only need to roll back the changes to these objects: owner_queries and the readers/writers queue + if (it_group->requests == 0) + erase_group(it_group); /// Rollback(SM1): nothrow throw; } @@ -251,10 +237,9 @@ RWLockImpl::LockHolder RWLockImpl::getLock(RWLockImpl::Type type, const String & } -/** The sequence points of acquiring lock's ownership by an instance of LockHolderImpl: - * 1. all_read_locks is updated - * 2. owner_queries is updated - * 3. request group is updated by LockHolderImpl which in turn becomes "bound" +/** The sequence points of acquiring lock ownership by an instance of LockHolderImpl: + * 1. owner_queries is updated + * 2. request group is updated by LockHolderImpl which in turn becomes "bound" * * If by the time when destructor of LockHolderImpl is called the instance has been "bound", * it is guaranteed that all three steps have been executed successfully and the resulting state is consistent. @@ -262,38 +247,74 @@ RWLockImpl::LockHolder RWLockImpl::getLock(RWLockImpl::Type type, const String & * * We do not employ try-catch: if something bad happens, there is nothing we can do =( */ -RWLockImpl::LockHolderImpl::~LockHolderImpl() +void RWLockImpl::unlock(GroupsContainer::iterator owner_group, const String & query_id) noexcept { - if (!bound || parent == nullptr) + std::lock_guard state_lock(internal_state_mtx); + + /// All of theses are Undefined behavior and nothing we can do! + if (rdlock_owner == readers_queue.end() && wrlock_owner == writers_queue.end()) return; - - std::lock_guard lock(parent->mutex); - - /// The associated group must exist (and be the beginning of the queue?) - if (parent->queue.empty() || it_group != parent->queue.begin()) + if (rdlock_owner != readers_queue.end() && owner_group != rdlock_owner) + return; + if (wrlock_owner != writers_queue.end() && owner_group != wrlock_owner) return; /// If query_id is not empty it must be listed in parent->owner_queries - if (query_id != RWLockImpl::NO_QUERY) + if (query_id != NO_QUERY) { - const auto owner_it = parent->owner_queries.find(query_id); - if (owner_it != parent->owner_queries.end()) + const auto owner_query_it = owner_queries.find(query_id); + if (owner_query_it != owner_queries.end()) { - if (--owner_it->second == 0) /// SM: nothrow - parent->owner_queries.erase(owner_it); /// SM: nothrow - - if (lock_type == RWLockImpl::Read) - all_read_locks.remove(query_id); /// SM: nothrow + if (--owner_query_it->second == 0) /// SM: nothrow + owner_queries.erase(owner_query_it); /// SM: nothrow } } - /// If we are the last remaining referrer, remove the group and notify the next group - if (--it_group->refererrs == 0) /// SM: nothrow - { - const auto next = parent->queue.erase(it_group); /// SM: nothrow - if (next != parent->queue.end()) - next->cv.notify_all(); - } + /// If we are the last remaining referrer, remove this QNode and notify the next one + if (--owner_group->requests == 0) /// SM: nothrow + erase_group(owner_group); } + +void RWLockImpl::erase_group(GroupsContainer::iterator group_it) noexcept +{ + rdlock_owner = readers_queue.end(); + wrlock_owner = writers_queue.end(); + + if (group_it->type == Read) + { + readers_queue.erase(group_it); + /// Prepare next phase + if (!writers_queue.empty()) + { + wrlock_owner = writers_queue.begin(); + } + else + { + rdlock_owner = readers_queue.begin(); + } + } + else + { + writers_queue.erase(group_it); + /// Prepare next phase + if (!readers_queue.empty()) + { + rdlock_owner = readers_queue.begin(); + } + else + { + wrlock_owner = writers_queue.begin(); + } + } + + if (rdlock_owner != readers_queue.end()) + { + rdlock_owner->cv.notify_all(); + } + else if (wrlock_owner != writers_queue.end()) + { + wrlock_owner->cv.notify_one(); + } +} } diff --git a/src/Common/RWLock.h b/src/Common/RWLock.h index a7084720d6c..81b8551060a 100644 --- a/src/Common/RWLock.h +++ b/src/Common/RWLock.h @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -19,7 +20,8 @@ using RWLock = std::shared_ptr; /// Implements shared lock with FIFO service -/// Can be acquired recursively (several calls for the same query) in Read mode +/// (Phase Fair RWLock as suggested in https://www.cs.unc.edu/~anderson/papers/rtsj10-for-web.pdf) +/// Can be acquired recursively (for the same query) in Read mode /// /// NOTE: it is important to allow acquiring the same lock in Read mode without waiting if it is already /// acquired by another thread of the same query. Otherwise the following deadlock is possible: @@ -42,37 +44,44 @@ public: friend class LockHolderImpl; using LockHolder = std::shared_ptr; - /// Waits in the queue and returns appropriate lock - /// Empty query_id means the lock is acquired out of the query context (e.g. in a background thread). - LockHolder getLock(Type type, const String & query_id); + /// Empty query_id means the lock is acquired from outside of query context (e.g. in a background thread). + LockHolder getLock(Type type, const String & query_id, + const std::chrono::milliseconds & lock_timeout_ms = std::chrono::milliseconds(0)); /// Use as query_id to acquire a lock outside the query context. inline static const String NO_QUERY = String(); + inline static const auto default_locking_timeout = std::chrono::milliseconds(120000); private: - RWLockImpl() = default; - - struct Group; - using GroupsContainer = std::list; - using OwnerQueryIds = std::unordered_map; - - /// Group of locking requests that should be granted concurrently - /// i.e. a group can contain several readers, but only one writer + /// Group of locking requests that should be granted simultaneously + /// i.e. one or several readers or a single writer struct Group { const Type type; - size_t refererrs; + size_t requests; std::condition_variable cv; /// all locking requests of the group wait on this condvar - explicit Group(Type type_) : type{type_}, refererrs{0} {} + explicit Group(Type type_) : type{type_}, requests{0} {} }; - GroupsContainer queue; + using GroupsContainer = std::list; + using OwnerQueryIds = std::unordered_map; + +private: + mutable std::mutex internal_state_mtx; + + GroupsContainer readers_queue; + GroupsContainer writers_queue; + GroupsContainer::iterator rdlock_owner{readers_queue.end()}; /// equals to readers_queue.begin() in read phase + /// or readers_queue.end() otherwise + GroupsContainer::iterator wrlock_owner{writers_queue.end()}; /// equals to writers_queue.begin() in write phase + /// or writers_queue.end() otherwise OwnerQueryIds owner_queries; - mutable std::mutex mutex; +private: + RWLockImpl() = default; + void unlock(GroupsContainer::iterator group_it, const String & query_id) noexcept; + void erase_group(GroupsContainer::iterator group_it) noexcept; }; - - } From 09ce548376e8631cc19f5be00caea3c048f27b94 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 02:45:51 +0300 Subject: [PATCH 015/208] All locks in IStorage have timeouts now --- src/Storages/IStorage.cpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/Storages/IStorage.cpp b/src/Storages/IStorage.cpp index 4d916ca1b46..ee751be6f5a 100644 --- a/src/Storages/IStorage.cpp +++ b/src/Storages/IStorage.cpp @@ -28,6 +28,7 @@ namespace ErrorCodes extern const int TYPE_MISMATCH; extern const int TABLE_IS_DROPPED; extern const int NOT_IMPLEMENTED; + extern const int DEADLOCK_AVOIDED; } IStorage::IStorage(StorageID storage_id_, ColumnsDescription virtuals_) : storage_id(std::move(storage_id_)), virtuals(std::move(virtuals_)) @@ -314,12 +315,22 @@ bool IStorage::isVirtualColumn(const String & column_name) const return getColumns().get(column_name).is_virtual; } +RWLockImpl::LockHolder tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type, const String & query_id) +{ + auto lock_holder = rwlock->getLock(type, query_id, RWLockImpl::default_locking_timeout); + if (!lock_holder) + throw Exception( + "Locking attempt timed out! Possible deadlock avoided. Client should retry.", + ErrorCodes::DEADLOCK_AVOIDED); + return std::move(lock_holder); +} + TableStructureReadLockHolder IStorage::lockStructureForShare(bool will_add_new_data, const String & query_id) { TableStructureReadLockHolder result; if (will_add_new_data) - result.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Read, query_id); - result.structure_lock = structure_lock->getLock(RWLockImpl::Read, query_id); + result.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Read, query_id); + result.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Read, query_id); if (is_dropped) throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED); @@ -329,7 +340,7 @@ TableStructureReadLockHolder IStorage::lockStructureForShare(bool will_add_new_d TableStructureWriteLockHolder IStorage::lockAlterIntention(const String & query_id) { TableStructureWriteLockHolder result; - result.alter_intention_lock = alter_intention_lock->getLock(RWLockImpl::Write, query_id); + result.alter_intention_lock = tryLockTimed(alter_intention_lock, RWLockImpl::Write, query_id); if (is_dropped) throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED); @@ -342,20 +353,20 @@ void IStorage::lockStructureExclusively(TableStructureWriteLockHolder & lock_hol throw Exception("Alter intention lock for table " + getStorageID().getNameForLogs() + " was not taken. This is a bug.", ErrorCodes::LOGICAL_ERROR); if (!lock_holder.new_data_structure_lock) - lock_holder.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Write, query_id); - lock_holder.structure_lock = structure_lock->getLock(RWLockImpl::Write, query_id); + lock_holder.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Write, query_id); + lock_holder.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Write, query_id); } TableStructureWriteLockHolder IStorage::lockExclusively(const String & query_id) { TableStructureWriteLockHolder result; - result.alter_intention_lock = alter_intention_lock->getLock(RWLockImpl::Write, query_id); + result.alter_intention_lock = tryLockTimed(alter_intention_lock, RWLockImpl::Write, query_id); if (is_dropped) throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED); - result.new_data_structure_lock = new_data_structure_lock->getLock(RWLockImpl::Write, query_id); - result.structure_lock = structure_lock->getLock(RWLockImpl::Write, query_id); + result.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Write, query_id); + result.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Write, query_id); return result; } From 081187dd1fec6a231b5e8334ff24321226865d79 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 03:06:48 +0300 Subject: [PATCH 016/208] Unit test for RWLock is set to use timeout for avoiding deadlocks --- src/Common/tests/gtest_rw_lock.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Common/tests/gtest_rw_lock.cpp b/src/Common/tests/gtest_rw_lock.cpp index facd7a33c1c..73987a25508 100644 --- a/src/Common/tests/gtest_rw_lock.cpp +++ b/src/Common/tests/gtest_rw_lock.cpp @@ -153,7 +153,7 @@ TEST(Common, RWLockDeadlock) usleep(100000); try { - auto holder2 = lock2->getLock(RWLockImpl::Read, "q1"); + auto holder2 = lock2->getLock(RWLockImpl::Read, "q1", std::chrono::milliseconds(100)); if (!holder2) { throw Exception( @@ -184,7 +184,7 @@ TEST(Common, RWLockDeadlock) usleep(100000); try { - auto holder1 = lock1->getLock(RWLockImpl::Read, "q3"); + auto holder1 = lock1->getLock(RWLockImpl::Read, "q3", std::chrono::milliseconds(100)); if (!holder1) { throw Exception( From 2e76e4d1ed0e25282ea224794f1262be07b63709 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 10:15:59 +0300 Subject: [PATCH 017/208] Made clang happy - fixed build --- src/Storages/IStorage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/IStorage.cpp b/src/Storages/IStorage.cpp index ee751be6f5a..345ac6d5aac 100644 --- a/src/Storages/IStorage.cpp +++ b/src/Storages/IStorage.cpp @@ -322,7 +322,7 @@ RWLockImpl::LockHolder tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type throw Exception( "Locking attempt timed out! Possible deadlock avoided. Client should retry.", ErrorCodes::DEADLOCK_AVOIDED); - return std::move(lock_holder); + return lock_holder; } TableStructureReadLockHolder IStorage::lockStructureForShare(bool will_add_new_data, const String & query_id) From 78f97a7a59fdf0053e2d2e9f235f7f8e5556f414 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 12:23:08 +0300 Subject: [PATCH 018/208] Build fixes --- src/Common/RWLock.cpp | 14 +++++++------- src/Common/RWLock.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Common/RWLock.cpp b/src/Common/RWLock.cpp index a282c1c6a91..d6b8cbd244f 100644 --- a/src/Common/RWLock.cpp +++ b/src/Common/RWLock.cpp @@ -224,7 +224,7 @@ RWLockImpl::getLock(RWLockImpl::Type type, const String & query_id, const std::c /// Methods std::list<>::emplace_back() and std::unordered_map<>::emplace() provide strong exception safety /// We only need to roll back the changes to these objects: owner_queries and the readers/writers queue if (it_group->requests == 0) - erase_group(it_group); /// Rollback(SM1): nothrow + eraseGroup(it_group); /// Rollback(SM1): nothrow throw; } @@ -247,16 +247,16 @@ RWLockImpl::getLock(RWLockImpl::Type type, const String & query_id, const std::c * * We do not employ try-catch: if something bad happens, there is nothing we can do =( */ -void RWLockImpl::unlock(GroupsContainer::iterator owner_group, const String & query_id) noexcept +void RWLockImpl::unlock(GroupsContainer::iterator group_it, const String & query_id) noexcept { std::lock_guard state_lock(internal_state_mtx); /// All of theses are Undefined behavior and nothing we can do! if (rdlock_owner == readers_queue.end() && wrlock_owner == writers_queue.end()) return; - if (rdlock_owner != readers_queue.end() && owner_group != rdlock_owner) + if (rdlock_owner != readers_queue.end() && group_it != rdlock_owner) return; - if (wrlock_owner != writers_queue.end() && owner_group != wrlock_owner) + if (wrlock_owner != writers_queue.end() && group_it != wrlock_owner) return; /// If query_id is not empty it must be listed in parent->owner_queries @@ -271,12 +271,12 @@ void RWLockImpl::unlock(GroupsContainer::iterator owner_group, const String & qu } /// If we are the last remaining referrer, remove this QNode and notify the next one - if (--owner_group->requests == 0) /// SM: nothrow - erase_group(owner_group); + if (--group_it->requests == 0) /// SM: nothrow + eraseGroup(group_it); } -void RWLockImpl::erase_group(GroupsContainer::iterator group_it) noexcept +void RWLockImpl::eraseGroup(GroupsContainer::iterator group_it) noexcept { rdlock_owner = readers_queue.end(); wrlock_owner = writers_queue.end(); diff --git a/src/Common/RWLock.h b/src/Common/RWLock.h index 81b8551060a..edc22cffaa0 100644 --- a/src/Common/RWLock.h +++ b/src/Common/RWLock.h @@ -82,6 +82,6 @@ private: private: RWLockImpl() = default; void unlock(GroupsContainer::iterator group_it, const String & query_id) noexcept; - void erase_group(GroupsContainer::iterator group_it) noexcept; + void eraseGroup(GroupsContainer::iterator group_it) noexcept; }; } From 53b5dade5ed488f8be0f0b8e7a624be3e5bb206c Mon Sep 17 00:00:00 2001 From: "philip.han" Date: Mon, 6 Apr 2020 22:30:16 +0900 Subject: [PATCH 019/208] Implement transform_null_in --- src/Core/Settings.h | 1 + src/Functions/in.cpp | 52 ++++++++--- src/Interpreters/ActionsVisitor.cpp | 16 ++-- src/Interpreters/ExpressionAnalyzer.cpp | 2 +- src/Interpreters/NullableUtils.cpp | 9 +- src/Interpreters/NullableUtils.h | 2 +- src/Interpreters/Set.cpp | 19 ++-- src/Interpreters/Set.h | 10 +- src/Interpreters/SyntaxAnalyzer.cpp | 42 +++++++-- src/Interpreters/misc.h | 4 +- src/Storages/StorageSet.cpp | 6 +- .../01231_operator_null_in.reference | 54 +++++++++++ .../0_stateless/01231_operator_null_in.sql | 93 +++++++++++++++++++ 13 files changed, 267 insertions(+), 43 deletions(-) create mode 100644 tests/queries/0_stateless/01231_operator_null_in.reference create mode 100644 tests/queries/0_stateless/01231_operator_null_in.sql diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 753231603b2..29bfa82d89b 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -406,6 +406,7 @@ struct Settings : public SettingsCollection M(SettingBool, validate_polygons, true, "Throw exception if polygon is invalid in function pointInPolygon (e.g. self-tangent, self-intersecting). If the setting is false, the function will accept invalid polygons but may silently return wrong result.", 0) \ M(SettingUInt64, max_parser_depth, 1000, "Maximum parser depth.", 0) \ M(SettingSeconds, temporary_live_view_timeout, DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC, "Timeout after which temporary live view is deleted.", 0) \ + M(SettingBool, transform_null_in, false, "Enable null verification of the 'IN' operator.", 0) \ \ /** Obsolete settings that do nothing but left for compatibility reasons. Remove each one after half a year of obsolescence. */ \ \ diff --git a/src/Functions/in.cpp b/src/Functions/in.cpp index 0b25ca201bb..a89535c675a 100644 --- a/src/Functions/in.cpp +++ b/src/Functions/in.cpp @@ -21,38 +21,62 @@ namespace ErrorCodes * notIn(x, set) - and NOT IN. */ -template +template struct FunctionInName; template <> -struct FunctionInName +struct FunctionInName { static constexpr auto name = "in"; }; template <> -struct FunctionInName +struct FunctionInName { static constexpr auto name = "globalIn"; }; template <> -struct FunctionInName +struct FunctionInName { static constexpr auto name = "notIn"; }; template <> -struct FunctionInName +struct FunctionInName { static constexpr auto name = "globalNotIn"; }; -template +template <> +struct FunctionInName +{ + static constexpr auto name = "nullIn"; +}; + +template <> +struct FunctionInName +{ + static constexpr auto name = "globalNullIn"; +}; + +template <> +struct FunctionInName +{ + static constexpr auto name = "notNullIn"; +}; + +template <> +struct FunctionInName +{ + static constexpr auto name = "globalNotNullIn"; +}; + +template class FunctionIn : public IFunction { public: - static constexpr auto name = FunctionInName::name; + static constexpr auto name = FunctionInName::name; static FunctionPtr create(const Context &) { return std::make_shared(); @@ -75,6 +99,8 @@ public: bool useDefaultImplementationForConstants() const override { return true; } + bool useDefaultImplementationForNulls() const override { return null_is_skipped; } + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t /*input_rows_count*/) override { /// NOTE: after updating this code, check that FunctionIgnoreExceptNull returns the same type of column. @@ -123,10 +149,14 @@ public: void registerFunctionsIn(FunctionFactory & factory) { - factory.registerFunction>(); - factory.registerFunction>(); - factory.registerFunction>(); - factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); + factory.registerFunction>(); } } diff --git a/src/Interpreters/ActionsVisitor.cpp b/src/Interpreters/ActionsVisitor.cpp index 4e008a81973..f7d64d54f27 100644 --- a/src/Interpreters/ActionsVisitor.cpp +++ b/src/Interpreters/ActionsVisitor.cpp @@ -64,7 +64,7 @@ static NamesAndTypesList::iterator findColumn(const String & name, NamesAndTypes } template -static Block createBlockFromCollection(const Collection & collection, const DataTypes & types) +static Block createBlockFromCollection(const Collection & collection, const DataTypes & types, const Context & context) { size_t columns_num = types.size(); MutableColumns columns(columns_num); @@ -77,7 +77,7 @@ static Block createBlockFromCollection(const Collection & collection, const Data if (columns_num == 1) { auto field = convertFieldToType(value, *types[0]); - if (!field.isNull()) + if (!field.isNull() || context.getSettingsRef().transform_null_in) columns[0]->insert(std::move(field)); } else @@ -100,7 +100,7 @@ static Block createBlockFromCollection(const Collection & collection, const Data for (; i < tuple_size; ++i) { tuple_values[i] = convertFieldToType(tuple[i], *types[i]); - if (tuple_values[i].isNull()) + if (tuple_values[i].isNull() && !context.getSettingsRef().transform_null_in) break; } @@ -170,23 +170,23 @@ SetPtr makeExplicitSet( if (left_type_depth == right_type_depth) { Array array{right_arg_value}; - block = createBlockFromCollection(array, set_element_types); + block = createBlockFromCollection(array, set_element_types, context); } /// 1 in (1, 2); (1, 2) in ((1, 2), (3, 4)); etc. else if (left_type_depth + 1 == right_type_depth) { auto type_index = right_arg_type->getTypeId(); if (type_index == TypeIndex::Tuple) - block = createBlockFromCollection(DB::get(right_arg_value), set_element_types); + block = createBlockFromCollection(DB::get(right_arg_value), set_element_types, context); else if (type_index == TypeIndex::Array) - block = createBlockFromCollection(DB::get(right_arg_value), set_element_types); + block = createBlockFromCollection(DB::get(right_arg_value), set_element_types, context); else throw_unsupported_type(right_arg_type); } else throw_unsupported_type(right_arg_type); - SetPtr set = std::make_shared(size_limits, create_ordered_set); + SetPtr set = std::make_shared(size_limits, create_ordered_set, context); set->setHeader(block); set->insertFromBlock(block); @@ -654,7 +654,7 @@ SetPtr ActionsMatcher::makeSet(const ASTFunction & node, Data & data, bool no_su return subquery_for_set.set; } - SetPtr set = std::make_shared(data.set_size_limit, false); + SetPtr set = std::make_shared(data.set_size_limit, false, data.context); /** The following happens for GLOBAL INs: * - in the addExternalStorage function, the IN (SELECT ...) subquery is replaced with IN _data1, diff --git a/src/Interpreters/ExpressionAnalyzer.cpp b/src/Interpreters/ExpressionAnalyzer.cpp index d1be66df217..d0b44b91af7 100644 --- a/src/Interpreters/ExpressionAnalyzer.cpp +++ b/src/Interpreters/ExpressionAnalyzer.cpp @@ -291,7 +291,7 @@ void SelectQueryExpressionAnalyzer::tryMakeSetForIndexFromSubquery(const ASTPtr auto interpreter_subquery = interpretSubquery(subquery_or_table_name, context, {}, query_options); BlockIO res = interpreter_subquery->execute(); - SetPtr set = std::make_shared(settings.size_limits_for_set, true); + SetPtr set = std::make_shared(settings.size_limits_for_set, true, context); set->setHeader(res.in->getHeader()); res.in->readPrefix(); diff --git a/src/Interpreters/NullableUtils.cpp b/src/Interpreters/NullableUtils.cpp index fe2801f5d11..5c0202d1de3 100644 --- a/src/Interpreters/NullableUtils.cpp +++ b/src/Interpreters/NullableUtils.cpp @@ -5,7 +5,7 @@ namespace DB { -ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map) +ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map, bool exact_null) { ColumnPtr null_map_holder; @@ -38,7 +38,12 @@ ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullM PaddedPODArray & mutable_null_map = assert_cast(*mutable_null_map_holder).getData(); const PaddedPODArray & other_null_map = column_nullable->getNullMapData(); for (size_t i = 0, size = mutable_null_map.size(); i < size; ++i) - mutable_null_map[i] |= other_null_map[i]; + { + if (exact_null) + mutable_null_map[i] &= other_null_map[i]; + else + mutable_null_map[i] |= other_null_map[i]; + } null_map_holder = std::move(mutable_null_map_holder); } diff --git a/src/Interpreters/NullableUtils.h b/src/Interpreters/NullableUtils.h index ee3193919cd..054835f8bef 100644 --- a/src/Interpreters/NullableUtils.h +++ b/src/Interpreters/NullableUtils.h @@ -8,6 +8,6 @@ namespace DB * In 'null_map' return a map of positions where at least one column was NULL. * @returns ownership column of null_map. */ -ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map); +ColumnPtr extractNestedColumnsAndNullMap(ColumnRawPtrs & key_columns, ConstNullMapPtr & null_map, bool exact_null = false); } diff --git a/src/Interpreters/Set.cpp b/src/Interpreters/Set.cpp index 3c79ea5174d..e63eff37047 100644 --- a/src/Interpreters/Set.cpp +++ b/src/Interpreters/Set.cpp @@ -87,6 +87,8 @@ void NO_INLINE Set::insertFromBlockImplCase( { if ((*null_map)[i]) { + has_null = true; + if constexpr (build_filter) { (*out_filter)[i] = false; @@ -138,7 +140,7 @@ void Set::setHeader(const Block & header) /// We will insert to the Set only keys, where all components are not NULL. ConstNullMapPtr null_map{}; - ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map); + ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, context.getSettingsRef().transform_null_in); if (fill_set_elements) { @@ -228,7 +230,7 @@ static Field extractValueFromNode(const ASTPtr & node, const IDataType & type, c throw Exception("Incorrect element of set. Must be literal or constant expression.", ErrorCodes::INCORRECT_ELEMENT_OF_SET); } -void Set::createFromAST(const DataTypes & types, ASTPtr node, const Context & context) +void Set::createFromAST(const DataTypes & types, ASTPtr node) { /// Will form a block with values from the set. @@ -249,7 +251,7 @@ void Set::createFromAST(const DataTypes & types, ASTPtr node, const Context & co { Field value = extractValueFromNode(elem, *types[0], context); - if (!value.isNull()) + if (!value.isNull() || context.getSettingsRef().transform_null_in) columns[0]->insert(value); } else if (const auto * func = elem->as()) @@ -284,7 +286,7 @@ void Set::createFromAST(const DataTypes & types, ASTPtr node, const Context & co : extractValueFromNode(func->arguments->children[i], *types[i], context); /// If at least one of the elements of the tuple has an impossible (outside the range of the type) value, then the entire tuple too. - if (value.isNull()) + if (value.isNull() && !context.getSettings().transform_null_in) break; tuple_values[i] = value; @@ -348,7 +350,7 @@ ColumnPtr Set::execute(const Block & block, bool negative) const /// We will check existence in Set only for keys, where all components are not NULL. ConstNullMapPtr null_map{}; - ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map); + ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, context.getSettingsRef().transform_null_in); executeOrdinary(key_columns, vec_res, negative, null_map); @@ -390,7 +392,12 @@ void NO_INLINE Set::executeImplCase( for (size_t i = 0; i < rows; ++i) { if (has_null_map && (*null_map)[i]) - vec_res[i] = negative; + { + if (has_null) + vec_res[i] = !negative; + else + vec_res[i] = negative; + } else { auto find_result = state.findKey(method.data, i, pool); diff --git a/src/Interpreters/Set.h b/src/Interpreters/Set.h index c9605d4e11e..da20ffc41b6 100644 --- a/src/Interpreters/Set.h +++ b/src/Interpreters/Set.h @@ -30,9 +30,9 @@ public: /// (that is useful only for checking that some value is in the set and may not store the original values), /// store all set elements in explicit form. /// This is needed for subsequent use for index. - Set(const SizeLimits & limits_, bool fill_set_elements_) + Set(const SizeLimits & limits_, bool fill_set_elements_, const Context & context_) : log(&Logger::get("Set")), - limits(limits_), fill_set_elements(fill_set_elements_) + limits(limits_), fill_set_elements(fill_set_elements_), context(context_) { } @@ -45,7 +45,7 @@ public: * 'types' - types of what are on the left hand side of IN. * 'node' - list of values: 1, 2, 3 or list of tuples: (1, 2), (3, 4), (5, 6). */ - void createFromAST(const DataTypes & types, ASTPtr node, const Context & context); + void createFromAST(const DataTypes & types, ASTPtr node); /** Create a Set from stream. * Call setHeader, then call insertFromBlock for each block. @@ -113,6 +113,10 @@ private: /// Do we need to additionally store all elements of the set in explicit form for subsequent use for index. bool fill_set_elements; + const Context & context; + + bool has_null = false; + /// Check if set contains all the data. bool is_created = false; diff --git a/src/Interpreters/SyntaxAnalyzer.cpp b/src/Interpreters/SyntaxAnalyzer.cpp index f93d11fa1da..a1560e26367 100644 --- a/src/Interpreters/SyntaxAnalyzer.cpp +++ b/src/Interpreters/SyntaxAnalyzer.cpp @@ -60,25 +60,40 @@ namespace using LogAST = DebugASTLog; /// set to true to enable logs -/// Select implementation of countDistinct based on settings. +/// Select implementation of a function based on settings. /// Important that it is done as query rewrite. It means rewritten query /// will be sent to remote servers during distributed query execution, /// and on all remote servers, function implementation will be same. +template struct CustomizeFunctionsData { using TypeToVisit = ASTFunction; - const String & count_distinct; + const String & customized_func_name; void visit(ASTFunction & func, ASTPtr &) { - if (Poco::toLower(func.name) == "countdistinct") - func.name = count_distinct; + if (Poco::toLower(func.name) == func_name) + { + func.name = customized_func_name; + } } }; -using CustomizeFunctionsMatcher = OneTypeMatcher; -using CustomizeFunctionsVisitor = InDepthNodeVisitor; +char countdistinct[] = "countdistinct"; +using CustomizeFunctionsVisitor = InDepthNodeVisitor>, true>; + +char in[] = "in"; +using CustomizeInVisitor = InDepthNodeVisitor>, true>; + +char notIn[] = "notin"; +using CustomizeNotInVisitor = InDepthNodeVisitor>, true>; + +char globalIn[] = "globalin"; +using CustomizeGlobalInVisitor = InDepthNodeVisitor>, true>; + +char globalNotIn[] = "globalnotin"; +using CustomizeGlobalNotInVisitor = InDepthNodeVisitor>, true>; /// Translate qualified names such as db.table.column, table.column, table_alias.column to names' normal form. @@ -889,6 +904,21 @@ void SyntaxAnalyzer::normalize(ASTPtr & query, Aliases & aliases, const Settings CustomizeFunctionsVisitor::Data data{settings.count_distinct_implementation}; CustomizeFunctionsVisitor(data).visit(query); + if (settings.transform_null_in) + { + CustomizeInVisitor::Data data_null_in{"nullIn"}; + CustomizeInVisitor(data_null_in).visit(query); + + CustomizeNotInVisitor::Data data_not_null_in{"notNullIn"}; + CustomizeNotInVisitor(data_not_null_in).visit(query); + + CustomizeGlobalInVisitor::Data data_global_null_in{"globalNullIn"}; + CustomizeGlobalInVisitor(data_global_null_in).visit(query); + + CustomizeGlobalNotInVisitor::Data data_global_not_null_in{"globalNotNullIn"}; + CustomizeGlobalNotInVisitor(data_global_not_null_in).visit(query); + } + /// Creates a dictionary `aliases`: alias -> ASTPtr QueryAliasesVisitor(aliases).visit(query); diff --git a/src/Interpreters/misc.h b/src/Interpreters/misc.h index e2f34375dc0..0fd0e12a4bb 100644 --- a/src/Interpreters/misc.h +++ b/src/Interpreters/misc.h @@ -5,12 +5,12 @@ namespace DB inline bool functionIsInOperator(const std::string & name) { - return name == "in" || name == "notIn"; + return name == "in" || name == "notIn" || name == "nullIn" || name == "notNullIn"; } inline bool functionIsInOrGlobalInOperator(const std::string & name) { - return functionIsInOperator(name) || name == "globalIn" || name == "globalNotIn"; + return functionIsInOperator(name) || name == "globalIn" || name == "globalNotIn" || name == "globalNullIn" || name == "globalNotNullIn"; } inline bool functionIsLikeOperator(const std::string & name) diff --git a/src/Storages/StorageSet.cpp b/src/Storages/StorageSet.cpp index 72ae46787c8..45e1f81b487 100644 --- a/src/Storages/StorageSet.cpp +++ b/src/Storages/StorageSet.cpp @@ -112,7 +112,7 @@ StorageSet::StorageSet( const ConstraintsDescription & constraints_, const Context & context_) : StorageSetOrJoinBase{relative_path_, table_id_, columns_, constraints_, context_}, - set(std::make_shared(SizeLimits(), false)) + set(std::make_shared(SizeLimits(), false, context_)) { Block header = getSampleBlock(); header = header.sortColumns(); @@ -127,7 +127,7 @@ void StorageSet::finishInsert() { set->finishInsert(); } size_t StorageSet::getSize() const { return set->getTotalRowCount(); } -void StorageSet::truncate(const ASTPtr &, const Context &, TableStructureWriteLockHolder &) +void StorageSet::truncate(const ASTPtr &, const Context & context, TableStructureWriteLockHolder &) { Poco::File(path).remove(true); Poco::File(path).createDirectories(); @@ -137,7 +137,7 @@ void StorageSet::truncate(const ASTPtr &, const Context &, TableStructureWriteLo header = header.sortColumns(); increment = 0; - set = std::make_shared(SizeLimits(), false); + set = std::make_shared(SizeLimits(), false, context); set->setHeader(header); } diff --git a/tests/queries/0_stateless/01231_operator_null_in.reference b/tests/queries/0_stateless/01231_operator_null_in.reference new file mode 100644 index 00000000000..7432b657191 --- /dev/null +++ b/tests/queries/0_stateless/01231_operator_null_in.reference @@ -0,0 +1,54 @@ +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 diff --git a/tests/queries/0_stateless/01231_operator_null_in.sql b/tests/queries/0_stateless/01231_operator_null_in.sql new file mode 100644 index 00000000000..12361373001 --- /dev/null +++ b/tests/queries/0_stateless/01231_operator_null_in.sql @@ -0,0 +1,93 @@ +DROP TABLE IF EXISTS null_in; +CREATE TABLE null_in (dt DateTime, idx int, i Nullable(int), s Nullable(String)) ENGINE = MergeTree() PARTITION BY dt ORDER BY idx; + +INSERT INTO null_in VALUES (1, 1, 1, '1') (2, 2, NULL, NULL) (3, 3, 3, '3') (4, 4, NULL, NULL) (5, 5, 5, '5'); + +SELECT count() == 2 FROM null_in WHERE i in (1, 3, NULL); +SELECT count() == 2 FROM null_in WHERE i in range(4); +SELECT count() == 2 FROM null_in WHERE s in ('1', '3', NULL); +SELECT count() == 2 FROM null_in WHERE i global in (1, 3, NULL); +SELECT count() == 2 FROM null_in WHERE i global in range(4); +SELECT count() == 2 FROM null_in WHERE s global in ('1', '3', NULL); + +SELECT count() == 1 FROM null_in WHERE i not in (1, 3, NULL); +SELECT count() == 1 FROM null_in WHERE i not in range(4); +SELECT count() == 1 FROM null_in WHERE s not in ('1', '3', NULL); +SELECT count() == 1 FROM null_in WHERE i global not in (1, 3, NULL); +SELECT count() == 1 FROM null_in WHERE i global not in range(4); +SELECT count() == 1 FROM null_in WHERE s global not in ('1', '3', NULL); + +SET transform_null_in = 1; + +SELECT count() == 4 FROM null_in WHERE i in (1, 3, NULL); +SELECT count() == 2 FROM null_in WHERE i in range(4); +SELECT count() == 4 FROM null_in WHERE s in ('1', '3', NULL); +SELECT count() == 4 FROM null_in WHERE i global in (1, 3, NULL); +SELECT count() == 2 FROM null_in WHERE i global in range(4); +SELECT count() == 4 FROM null_in WHERE s global in ('1', '3', NULL); + +SELECT count() == 1 FROM null_in WHERE i not in (1, 3, NULL); +SELECT count() == 3 FROM null_in WHERE i not in range(4); +SELECT count() == 1 FROM null_in WHERE s not in ('1', '3', NULL); +SELECT count() == 1 FROM null_in WHERE i global not in (1, 3, NULL); +SELECT count() == 3 FROM null_in WHERE i global not in range(4); +SELECT count() == 1 FROM null_in WHERE s global not in ('1', '3', NULL); + +SELECT count() == 3 FROM null_in WHERE i not in (1, 3); +SELECT count() == 3 FROM null_in WHERE i not in range(4); +SELECT count() == 3 FROM null_in WHERE s not in ('1', '3'); +SELECT count() == 3 FROM null_in WHERE i global not in (1, 3); +SELECT count() == 3 FROM null_in WHERE i global not in range(4); +SELECT count() == 3 FROM null_in WHERE s global not in ('1', '3'); + +DROP TABLE IF EXISTS null_in; + +DROP TABLE IF EXISTS null_in_subquery; +CREATE TABLE null_in_subquery (dt DateTime, idx int, i Nullable(UInt64)) ENGINE = MergeTree() PARTITION BY dt ORDER BY idx; +INSERT INTO null_in_subquery SELECT number % 3, number, number FROM system.numbers LIMIT 99999; + +SELECT count() == 33333 FROM null_in_subquery WHERE i in (SELECT i FROM null_in_subquery WHERE dt = 0); +SELECT count() == 66666 FROM null_in_subquery WHERE i not in (SELECT i FROM null_in_subquery WHERE dt = 1); +SELECT count() == 33333 FROM null_in_subquery WHERE i global in (SELECT i FROM null_in_subquery WHERE dt = 2); +SELECT count() == 66666 FROM null_in_subquery WHERE i global not in (SELECT i FROM null_in_subquery WHERE dt = 0); + +-- For index column +SELECT count() == 33333 FROM null_in_subquery WHERE idx in (SELECT idx FROM null_in_subquery WHERE dt = 0); +SELECT count() == 66666 FROM null_in_subquery WHERE idx not in (SELECT idx FROM null_in_subquery WHERE dt = 1); +SELECT count() == 33333 FROM null_in_subquery WHERE idx global in (SELECT idx FROM null_in_subquery WHERE dt = 2); +SELECT count() == 66666 FROM null_in_subquery WHERE idx global not in (SELECT idx FROM null_in_subquery WHERE dt = 0); + +INSERT INTO null_in_subquery VALUES (0, 123456780, NULL); +INSERT INTO null_in_subquery VALUES (1, 123456781, NULL); + +SELECT count() == 33335 FROM null_in_subquery WHERE i in (SELECT i FROM null_in_subquery WHERE dt = 0); +SELECT count() == 66666 FROM null_in_subquery WHERE i not in (SELECT i FROM null_in_subquery WHERE dt = 1); +SELECT count() == 33333 FROM null_in_subquery WHERE i in (SELECT i FROM null_in_subquery WHERE dt = 2); +SELECT count() == 66668 FROM null_in_subquery WHERE i not in (SELECT i FROM null_in_subquery WHERE dt = 2); +SELECT count() == 33335 FROM null_in_subquery WHERE i global in (SELECT i FROM null_in_subquery WHERE dt = 0); +SELECT count() == 66666 FROM null_in_subquery WHERE i global not in (SELECT i FROM null_in_subquery WHERE dt = 1); +SELECT count() == 33333 FROM null_in_subquery WHERE i global in (SELECT i FROM null_in_subquery WHERE dt = 2); +SELECT count() == 66668 FROM null_in_subquery WHERE i global not in (SELECT i FROM null_in_subquery WHERE dt = 2); + +DROP TABLE IF EXISTS null_in_subquery; + + +DROP TABLE IF EXISTS null_in_tuple; +CREATE TABLE null_in_tuple (dt DateTime, idx int, t Tuple(Nullable(UInt64), Nullable(String))) ENGINE = MergeTree() PARTITION BY dt ORDER BY idx; +INSERT INTO null_in_tuple VALUES (1, 1, (1, '1')) (2, 2, (2, NULL)) (3, 3, (NULL, '3')) (4, 4, (NULL, NULL)) + +SET transform_null_in = 0; + +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1')] FROM null_in_tuple WHERE t in ((1, '1'), (NULL, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3'), (NULL, NULL)] FROM null_in_tuple WHERE t not in ((1, '1'), (NULL, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1')] FROM null_in_tuple WHERE t global in ((1, '1'), (NULL, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3'), (NULL, NULL)] FROM null_in_tuple WHERE t global not in ((1, '1'), (NULL, NULL)); + +SET transform_null_in = 1; + +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1'), (NULL, NULL)] FROM null_in_tuple WHERE t in ((1, '1'), (NULL, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3')] FROM null_in_tuple WHERE t not in ((1, '1'), (NULL, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1'), (NULL, NULL)] FROM null_in_tuple WHERE t global in ((1, '1'), (NULL, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3')] FROM null_in_tuple WHERE t global not in ((1, '1'), (NULL, NULL)); + +DROP TABLE IF EXISTS null_in_subquery; From 621d26bcf7fb1d04c47144a2c9f4767a0c0b4f38 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Tue, 7 Apr 2020 14:34:35 +0300 Subject: [PATCH 020/208] Better timeout diagnostics message --- src/Common/RWLock.h | 2 +- src/Storages/IStorage.cpp | 11 ++++++++--- src/Storages/IStorage.h | 3 +++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Common/RWLock.h b/src/Common/RWLock.h index edc22cffaa0..43366192cf8 100644 --- a/src/Common/RWLock.h +++ b/src/Common/RWLock.h @@ -50,7 +50,7 @@ public: /// Use as query_id to acquire a lock outside the query context. inline static const String NO_QUERY = String(); - inline static const auto default_locking_timeout = std::chrono::milliseconds(120000); + inline static const auto default_locking_timeout_ms = std::chrono::milliseconds(120000); private: /// Group of locking requests that should be granted simultaneously diff --git a/src/Storages/IStorage.cpp b/src/Storages/IStorage.cpp index 345ac6d5aac..ab3a750db16 100644 --- a/src/Storages/IStorage.cpp +++ b/src/Storages/IStorage.cpp @@ -315,13 +315,18 @@ bool IStorage::isVirtualColumn(const String & column_name) const return getColumns().get(column_name).is_virtual; } -RWLockImpl::LockHolder tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type, const String & query_id) +RWLockImpl::LockHolder IStorage::tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type, const String & query_id) { - auto lock_holder = rwlock->getLock(type, query_id, RWLockImpl::default_locking_timeout); + auto lock_holder = rwlock->getLock(type, query_id, RWLockImpl::default_locking_timeout_ms); if (!lock_holder) + { + const String type_str = type == RWLockImpl::Type::Read ? "READ" : "WRITE"; throw Exception( - "Locking attempt timed out! Possible deadlock avoided. Client should retry.", + type_str + " locking attempt on \"" + getStorageID().getFullTableName() + + "\" has timed out! (" + toString(RWLockImpl::default_locking_timeout_ms.count()) + "ms) " + "Possible deadlock avoided. Client should retry.", ErrorCodes::DEADLOCK_AVOIDED); + } return lock_holder; } diff --git a/src/Storages/IStorage.h b/src/Storages/IStorage.h index d3cede6e5c8..581fc8a67e7 100644 --- a/src/Storages/IStorage.h +++ b/src/Storages/IStorage.h @@ -195,6 +195,9 @@ private: IndicesDescription indices; ConstraintsDescription constraints; +private: + RWLockImpl::LockHolder tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type, const String & query_id); + public: /// Acquire this lock if you need the table structure to remain constant during the execution of /// the query. If will_add_new_data is true, this means that the query will add new data to the table From a6194364ea6f0ec3613f83188adf8ba889e40ae4 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 8 Apr 2020 05:54:08 +0300 Subject: [PATCH 021/208] Update MergeTreeDataSelectExecutor.cpp --- src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp index 13e852765b7..816af8db3e9 100644 --- a/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp +++ b/src/Storages/MergeTree/MergeTreeDataSelectExecutor.cpp @@ -1204,7 +1204,7 @@ MarkRanges MergeTreeDataSelectExecutor::markRangesFromPKRange( std::vector ranges_stack = { {0, marks_count} }; std::function create_field_ref; - /// If there is no monotonic functions, there is no need to save block reference. + /// If there are no monotonic functions, there is no need to save block reference. /// Passing explicit field to FieldRef allows to optimize ranges and shows better performance. if (key_condition.hasMonotonicFunctionsChain()) { From 94a621060d8af8607e3604e7c65c7e0b718c8182 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 8 Apr 2020 05:55:03 +0300 Subject: [PATCH 022/208] Update KeyCondition.h --- src/Storages/MergeTree/KeyCondition.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index 7c8b63eb800..4863ffa6f34 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -22,7 +22,7 @@ using FunctionBasePtr = std::shared_ptr; class ExpressionActions; using ExpressionActionsPtr = std::shared_ptr; -/** A field, that can be stored in two reperesenation: +/** A field, that can be stored in two reperesenations: * - A standalone field. * - A field with reference to it's position in block. * It's needed for execution functions on ranges during From 723a1f41e2516f5d17d03b7240accc3a8f07e4a5 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 8 Apr 2020 05:55:22 +0300 Subject: [PATCH 023/208] Update KeyCondition.h --- src/Storages/MergeTree/KeyCondition.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index 4863ffa6f34..db0f9e68c60 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -24,7 +24,7 @@ using ExpressionActionsPtr = std::shared_ptr; /** A field, that can be stored in two reperesenations: * - A standalone field. - * - A field with reference to it's position in block. + * - A field with reference to its position in block. * It's needed for execution functions on ranges during * index analysis. If function was executed once for field, * it's result would be cached for all block for which field's reference points to. From a42d875a68ae50358095a63355c323a35b199a48 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 8 Apr 2020 05:55:39 +0300 Subject: [PATCH 024/208] Update KeyCondition.h --- src/Storages/MergeTree/KeyCondition.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index db0f9e68c60..4c67ef258bf 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -27,7 +27,7 @@ using ExpressionActionsPtr = std::shared_ptr; * - A field with reference to its position in block. * It's needed for execution functions on ranges during * index analysis. If function was executed once for field, - * it's result would be cached for all block for which field's reference points to. + * its result would be cached for all block for which field's reference points to. */ struct FieldRef : public Field { From a46a61c970d40845fa49115eaa8c7f53d93651bf Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 8 Apr 2020 05:56:25 +0300 Subject: [PATCH 025/208] Update KeyCondition.h --- src/Storages/MergeTree/KeyCondition.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Storages/MergeTree/KeyCondition.h b/src/Storages/MergeTree/KeyCondition.h index 4c67ef258bf..3a3768f0e4c 100644 --- a/src/Storages/MergeTree/KeyCondition.h +++ b/src/Storages/MergeTree/KeyCondition.h @@ -24,10 +24,10 @@ using ExpressionActionsPtr = std::shared_ptr; /** A field, that can be stored in two reperesenations: * - A standalone field. - * - A field with reference to its position in block. - * It's needed for execution functions on ranges during + * - A field with reference to its position in a block. + * It's needed for execution of functions on ranges during * index analysis. If function was executed once for field, - * its result would be cached for all block for which field's reference points to. + * its result would be cached for whole block for which field's reference points to. */ struct FieldRef : public Field { From 0b5cc8058094c4189ccc63c32c909c4096fadb42 Mon Sep 17 00:00:00 2001 From: Amos Bird Date: Tue, 7 Apr 2020 22:52:32 +0800 Subject: [PATCH 026/208] joinGetOrNull --- src/Functions/FunctionJoinGet.cpp | 33 +++++++++++++------ src/Functions/FunctionJoinGet.h | 9 +++-- src/Interpreters/HashJoin.cpp | 33 ++++++++++++------- src/Interpreters/HashJoin.h | 6 ++-- .../01240_join_get_or_null.reference | 1 + .../0_stateless/01240_join_get_or_null.sql | 7 ++++ 6 files changed, 62 insertions(+), 27 deletions(-) create mode 100644 tests/queries/0_stateless/01240_join_get_or_null.reference create mode 100644 tests/queries/0_stateless/01240_join_get_or_null.sql diff --git a/src/Functions/FunctionJoinGet.cpp b/src/Functions/FunctionJoinGet.cpp index 1745343cc33..3e18d657ac0 100644 --- a/src/Functions/FunctionJoinGet.cpp +++ b/src/Functions/FunctionJoinGet.cpp @@ -60,7 +60,8 @@ static auto getJoin(const ColumnsWithTypeAndName & arguments, const Context & co return std::make_pair(storage_join, attr_name); } -FunctionBaseImplPtr JoinGetOverloadResolver::build(const ColumnsWithTypeAndName & arguments, const DataTypePtr &) const +template +FunctionBaseImplPtr JoinGetOverloadResolver::build(const ColumnsWithTypeAndName & arguments, const DataTypePtr &) const { auto [storage_join, attr_name] = getJoin(arguments, context); auto join = storage_join->getJoin(); @@ -70,40 +71,52 @@ FunctionBaseImplPtr JoinGetOverloadResolver::build(const ColumnsWithTypeAndName for (size_t i = 0; i < arguments.size(); ++i) data_types[i] = arguments[i].type; - auto return_type = join->joinGetReturnType(attr_name); - return std::make_unique(table_lock, storage_join, join, attr_name, data_types, return_type); + auto return_type = join->joinGetReturnType(attr_name, or_null); + return std::make_unique>(table_lock, storage_join, join, attr_name, data_types, return_type); } -DataTypePtr JoinGetOverloadResolver::getReturnType(const ColumnsWithTypeAndName & arguments) const +template +DataTypePtr JoinGetOverloadResolver::getReturnType(const ColumnsWithTypeAndName & arguments) const { auto [storage_join, attr_name] = getJoin(arguments, context); auto join = storage_join->getJoin(); - return join->joinGetReturnType(attr_name); + return join->joinGetReturnType(attr_name, or_null); } -void ExecutableFunctionJoinGet::execute(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) +template +void ExecutableFunctionJoinGet::execute(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) { auto ctn = block.getByPosition(arguments[2]); if (isColumnConst(*ctn.column)) ctn.column = ctn.column->cloneResized(1); ctn.name = ""; // make sure the key name never collide with the join columns Block key_block = {ctn}; - join->joinGet(key_block, attr_name); + join->joinGet(key_block, attr_name, or_null); auto & result_ctn = key_block.getByPosition(1); if (isColumnConst(*ctn.column)) result_ctn.column = ColumnConst::create(result_ctn.column, input_rows_count); block.getByPosition(result) = result_ctn; } -ExecutableFunctionImplPtr FunctionJoinGet::prepare(const Block &, const ColumnNumbers &, size_t) const +template +ExecutableFunctionImplPtr FunctionJoinGet::prepare(const Block &, const ColumnNumbers &, size_t) const { - return std::make_unique(join, attr_name); + return std::make_unique>(join, attr_name); } void registerFunctionJoinGet(FunctionFactory & factory) { - factory.registerFunction(); + // joinGet + factory.registerFunction>(); + // joinGetOrNull + factory.registerFunction>(); } +template class ExecutableFunctionJoinGet; +template class ExecutableFunctionJoinGet; +template class FunctionJoinGet; +template class FunctionJoinGet; +template class JoinGetOverloadResolver; +template class JoinGetOverloadResolver; } diff --git a/src/Functions/FunctionJoinGet.h b/src/Functions/FunctionJoinGet.h index 42ff2b16217..f233ccd8a4f 100644 --- a/src/Functions/FunctionJoinGet.h +++ b/src/Functions/FunctionJoinGet.h @@ -9,13 +9,14 @@ class Context; class HashJoin; using HashJoinPtr = std::shared_ptr; +template class ExecutableFunctionJoinGet final : public IExecutableFunctionImpl { public: ExecutableFunctionJoinGet(HashJoinPtr join_, String attr_name_) : join(std::move(join_)), attr_name(std::move(attr_name_)) {} - static constexpr auto name = "joinGet"; + static constexpr auto name = or_null ? "joinGetOrNull" : "joinGet"; bool useDefaultImplementationForNulls() const override { return false; } bool useDefaultImplementationForConstants() const override { return true; } @@ -30,10 +31,11 @@ private: const String attr_name; }; +template class FunctionJoinGet final : public IFunctionBaseImpl { public: - static constexpr auto name = "joinGet"; + static constexpr auto name = or_null ? "joinGetOrNull" : "joinGet"; FunctionJoinGet(TableStructureReadLockHolder table_lock_, StoragePtr storage_join_, HashJoinPtr join_, String attr_name_, @@ -63,10 +65,11 @@ private: DataTypePtr return_type; }; +template class JoinGetOverloadResolver final : public IFunctionOverloadResolverImpl { public: - static constexpr auto name = "joinGet"; + static constexpr auto name = or_null ? "joinGetOrNull" : "joinGet"; static FunctionOverloadResolverImplPtr create(const Context & context) { return std::make_unique(context); } explicit JoinGetOverloadResolver(const Context & context_) : context(context_) {} diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index a3432ebebba..d8c0d239c96 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -681,12 +681,10 @@ public: type_name.reserve(num_columns_to_add); right_indexes.reserve(num_columns_to_add); - for (size_t i = 0; i < num_columns_to_add; ++i) + for (auto & src_column : block_with_columns_to_add) { - const ColumnWithTypeAndName & src_column = sample_block_with_columns_to_add.safeGetByPosition(i); - - /// Don't insert column if it's in left block or not explicitly required. - if (!block.has(src_column.name) && block_with_columns_to_add.has(src_column.name)) + /// Don't insert column if it's in left block + if (!block.has(src_column.name)) addColumn(src_column); } @@ -1158,28 +1156,36 @@ static void checkTypeOfKey(const Block & block_left, const Block & block_right) } -DataTypePtr HashJoin::joinGetReturnType(const String & column_name) const +DataTypePtr HashJoin::joinGetReturnType(const String & column_name, bool or_null) const { std::shared_lock lock(data->rwlock); if (!sample_block_with_columns_to_add.has(column_name)) throw Exception("StorageJoin doesn't contain column " + column_name, ErrorCodes::LOGICAL_ERROR); - return sample_block_with_columns_to_add.getByName(column_name).type; + auto ctn = sample_block_with_columns_to_add.getByName(column_name); + if (or_null) + { + if (!ctn.type->canBeInsideNullable()) + throw Exception("Type " + ctn.type->getName() + "cannot be inside Nullable", ErrorCodes::LOGICAL_ERROR); + else + ctn.type = makeNullable(ctn.type); + } + return ctn.type; } template -void HashJoin::joinGetImpl(Block & block, const String & column_name, const Maps & maps_) const +void HashJoin::joinGetImpl(Block & block, const Block & block_with_columns_to_add, const Maps & maps_) const { joinBlockImpl( - block, {block.getByPosition(0).name}, {sample_block_with_columns_to_add.getByName(column_name)}, maps_); + block, {block.getByPosition(0).name}, block_with_columns_to_add, maps_); } // TODO: support composite key // TODO: return multiple columns as named tuple // TODO: return array of values when strictness == ASTTableJoin::Strictness::All -void HashJoin::joinGet(Block & block, const String & column_name) const +void HashJoin::joinGet(Block & block, const String & column_name, bool or_null) const { std::shared_lock lock(data->rwlock); @@ -1188,10 +1194,15 @@ void HashJoin::joinGet(Block & block, const String & column_name) const checkTypeOfKey(block, right_table_keys); + auto ctn = sample_block_with_columns_to_add.getByName(column_name); + if (or_null) + ctn.type = makeNullable(ctn.type); + ctn.column = ctn.type->createColumn(); + if ((strictness == ASTTableJoin::Strictness::Any || strictness == ASTTableJoin::Strictness::RightAny) && kind == ASTTableJoin::Kind::Left) { - joinGetImpl(block, column_name, std::get(data->maps)); + joinGetImpl(block, {ctn}, std::get(data->maps)); } else throw Exception("joinGet only supports StorageJoin of type Left Any", ErrorCodes::LOGICAL_ERROR); diff --git a/src/Interpreters/HashJoin.h b/src/Interpreters/HashJoin.h index 24ad2b871c9..b769cfc61c5 100644 --- a/src/Interpreters/HashJoin.h +++ b/src/Interpreters/HashJoin.h @@ -161,10 +161,10 @@ public: void joinBlock(Block & block, ExtraBlockPtr & not_processed) override; /// Infer the return type for joinGet function - DataTypePtr joinGetReturnType(const String & column_name) const; + DataTypePtr joinGetReturnType(const String & column_name, bool or_null) const; /// Used by joinGet function that turns StorageJoin into a dictionary - void joinGet(Block & block, const String & column_name) const; + void joinGet(Block & block, const String & column_name, bool or_null) const; /** Keep "totals" (separate part of dataset, see WITH TOTALS) to use later. */ @@ -382,7 +382,7 @@ private: void joinBlockImplCross(Block & block, ExtraBlockPtr & not_processed) const; template - void joinGetImpl(Block & block, const String & column_name, const Maps & maps) const; + void joinGetImpl(Block & block, const Block & block_with_columns_to_add, const Maps & maps_) const; static Type chooseMethod(const ColumnRawPtrs & key_columns, Sizes & key_sizes); }; diff --git a/tests/queries/0_stateless/01240_join_get_or_null.reference b/tests/queries/0_stateless/01240_join_get_or_null.reference new file mode 100644 index 00000000000..dec7d2fabd2 --- /dev/null +++ b/tests/queries/0_stateless/01240_join_get_or_null.reference @@ -0,0 +1 @@ +\N diff --git a/tests/queries/0_stateless/01240_join_get_or_null.sql b/tests/queries/0_stateless/01240_join_get_or_null.sql new file mode 100644 index 00000000000..d1b9a07540a --- /dev/null +++ b/tests/queries/0_stateless/01240_join_get_or_null.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS join_test; + +CREATE TABLE join_test (id UInt16, num UInt16) engine = Join(ANY, LEFT, id); + +SELECT joinGetOrNull('join_test', 'num', 500); + +DROP TABLE join_test; From c8c4dc8104a0b9c0e59457885b0dfc6c5a09994f Mon Sep 17 00:00:00 2001 From: Anton Popov Date: Wed, 8 Apr 2020 19:20:52 +0300 Subject: [PATCH 027/208] fix 'ALTER MODIFY COLUMN' with compact parts --- src/Storages/MergeTree/IMergeTreeReader.cpp | 24 ++++++++++--- src/Storages/MergeTree/IMergeTreeReader.h | 11 ++++-- .../MergeTree/MergeTreeReaderCompact.cpp | 20 ++--------- .../MergeTree/MergeTreeReaderWide.cpp | 36 ++----------------- 4 files changed, 34 insertions(+), 57 deletions(-) diff --git a/src/Storages/MergeTree/IMergeTreeReader.cpp b/src/Storages/MergeTree/IMergeTreeReader.cpp index 4978aeaaa58..8243983d837 100644 --- a/src/Storages/MergeTree/IMergeTreeReader.cpp +++ b/src/Storages/MergeTree/IMergeTreeReader.cpp @@ -32,6 +32,8 @@ IMergeTreeReader::IMergeTreeReader(const MergeTreeData::DataPartPtr & data_part_ , all_mark_ranges(all_mark_ranges_) , alter_conversions(storage.getAlterConversionsForPart(data_part)) { + for (const NameAndTypePair & column_from_part : data_part->getColumns()) + columns_from_part[column_from_part.name] = column_from_part.type; } IMergeTreeReader::~IMergeTreeReader() = default; @@ -183,6 +185,23 @@ void IMergeTreeReader::evaluateMissingDefaults(Block additional_columns, Columns } } +NameAndTypePair IMergeTreeReader::getColumnFromPart(const NameAndTypePair & required_column) const +{ + auto it = columns_from_part.find(required_column.name); + if (it != columns_from_part.end()) + return {it->first, it->second}; + + if (alter_conversions.isColumnRenamed(required_column.name)) + { + String old_name = alter_conversions.getColumnOldName(required_column.name); + it = columns_from_part.find(old_name); + if (it != columns_from_part.end()) + return {it->first, it->second}; + } + + return required_column; +} + void IMergeTreeReader::performRequiredConversions(Columns & res_columns) { try @@ -209,10 +228,7 @@ void IMergeTreeReader::performRequiredConversions(Columns & res_columns) if (res_columns[pos] == nullptr) continue; - if (columns_from_part.count(name_and_type->name)) - copy_block.insert({res_columns[pos], columns_from_part[name_and_type->name], name_and_type->name}); - else - copy_block.insert({res_columns[pos], name_and_type->type, name_and_type->name}); + copy_block.insert({res_columns[pos], getColumnFromPart(*name_and_type).type, name_and_type->name}); } DB::performRequiredConversions(copy_block, columns, storage.global_context); diff --git a/src/Storages/MergeTree/IMergeTreeReader.h b/src/Storages/MergeTree/IMergeTreeReader.h index 622e11dae8b..02d8f67f9d0 100644 --- a/src/Storages/MergeTree/IMergeTreeReader.h +++ b/src/Storages/MergeTree/IMergeTreeReader.h @@ -4,7 +4,6 @@ #include #include - namespace DB { @@ -59,6 +58,9 @@ public: MergeTreeData::DataPartPtr data_part; protected: + /// Returns actual column type in part, which can differ from table metadata. + NameAndTypePair getColumnFromPart(const NameAndTypePair & required_column) const; + /// avg_value_size_hints are used to reduce the number of reallocations when creating columns of variable size. ValueSizeMap avg_value_size_hints; /// Stores states for IDataType::deserializeBinaryBulk @@ -67,8 +69,6 @@ protected: /// Columns that are read. NamesAndTypesList columns; - std::unordered_map columns_from_part; - UncompressedCache * uncompressed_cache; MarkCache * mark_cache; @@ -78,8 +78,13 @@ protected: MarkRanges all_mark_ranges; friend class MergeTreeRangeReader::DelayedStream; + +private: /// Alter conversions, which must be applied on fly if required MergeTreeData::AlterConversions alter_conversions; + + /// Actual data type of columns in part + std::unordered_map columns_from_part; }; } diff --git a/src/Storages/MergeTree/MergeTreeReaderCompact.cpp b/src/Storages/MergeTree/MergeTreeReaderCompact.cpp index e4f7275f4a5..a895149e12e 100644 --- a/src/Storages/MergeTree/MergeTreeReaderCompact.cpp +++ b/src/Storages/MergeTree/MergeTreeReaderCompact.cpp @@ -78,15 +78,9 @@ MergeTreeReaderCompact::MergeTreeReaderCompact( auto name_and_type = columns.begin(); for (size_t i = 0; i < columns_num; ++i, ++name_and_type) { - const auto & [name, type] = *name_and_type; + const auto & [name, type] = getColumnFromPart(*name_and_type); auto position = data_part->getColumnPosition(name); - if (!position && alter_conversions.isColumnRenamed(name)) - { - String old_name = alter_conversions.getColumnOldName(name); - position = data_part->getColumnPosition(old_name); - } - if (!position && typeid_cast(type.get())) { /// If array of Nested column is missing in part, @@ -118,7 +112,7 @@ size_t MergeTreeReaderCompact::readRows(size_t from_mark, bool continue_reading, bool append = res_columns[i] != nullptr; if (!append) - res_columns[i] = column_it->type->createColumn(); + res_columns[i] = getColumnFromPart(*column_it).type->createColumn(); mutable_columns[i] = res_columns[i]->assumeMutable(); } @@ -132,15 +126,7 @@ size_t MergeTreeReaderCompact::readRows(size_t from_mark, bool continue_reading, if (!res_columns[pos]) continue; - auto [name, type] = *name_and_type; - - if (alter_conversions.isColumnRenamed(name)) - { - String old_name = alter_conversions.getColumnOldName(name); - if (!data_part->getColumnPosition(name) && data_part->getColumnPosition(old_name)) - name = old_name; - } - + auto [name, type] = getColumnFromPart(*name_and_type); auto & column = mutable_columns[pos]; try diff --git a/src/Storages/MergeTree/MergeTreeReaderWide.cpp b/src/Storages/MergeTree/MergeTreeReaderWide.cpp index ad676b4db03..1a03acb5758 100644 --- a/src/Storages/MergeTree/MergeTreeReaderWide.cpp +++ b/src/Storages/MergeTree/MergeTreeReaderWide.cpp @@ -41,28 +41,10 @@ MergeTreeReaderWide::MergeTreeReaderWide( { try { - for (const NameAndTypePair & column_from_part : data_part->getColumns()) - columns_from_part[column_from_part.name] = column_from_part.type; - for (const NameAndTypePair & column : columns) { - if (columns_from_part.count(column.name)) - { - addStreams(column.name, *columns_from_part[column.name], profile_callback_, clock_type_); - } - else - { - if (alter_conversions.isColumnRenamed(column.name)) - { - String old_name = alter_conversions.getColumnOldName(column.name); - if (columns_from_part.count(old_name)) - addStreams(old_name, *columns_from_part[old_name], profile_callback_, clock_type_); - } - else - { - addStreams(column.name, *column.type, profile_callback_, clock_type_); - } - } + auto column_from_part = getColumnFromPart(column); + addStreams(column_from_part.name, *column_from_part.type, profile_callback_, clock_type_); } } catch (...) @@ -93,19 +75,7 @@ size_t MergeTreeReaderWide::readRows(size_t from_mark, bool continue_reading, si auto name_and_type = columns.begin(); for (size_t pos = 0; pos < num_columns; ++pos, ++name_and_type) { - String name = name_and_type->name; - if (alter_conversions.isColumnRenamed(name)) - { - String original_name = alter_conversions.getColumnOldName(name); - if (!columns_from_part.count(name) && columns_from_part.count(original_name)) - name = original_name; - } - - DataTypePtr type; - if (columns_from_part.count(name)) - type = columns_from_part[name]; - else - type = name_and_type->type; + auto [name, type] = getColumnFromPart(*name_and_type); /// The column is already present in the block so we will append the values to the end. bool append = res_columns[pos] != nullptr; From ae2a05d4143fa23586f684f129e58178b5b91160 Mon Sep 17 00:00:00 2001 From: Anton Popov Date: Wed, 8 Apr 2020 19:33:57 +0300 Subject: [PATCH 028/208] add test with 'ALTER MODIFY' and compact parts --- .../01114_alter_modify_compact_parts.reference | 1 + .../0_stateless/01114_alter_modify_compact_parts.sql | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/queries/0_stateless/01114_alter_modify_compact_parts.reference create mode 100644 tests/queries/0_stateless/01114_alter_modify_compact_parts.sql diff --git a/tests/queries/0_stateless/01114_alter_modify_compact_parts.reference b/tests/queries/0_stateless/01114_alter_modify_compact_parts.reference new file mode 100644 index 00000000000..4ec38dfb475 --- /dev/null +++ b/tests/queries/0_stateless/01114_alter_modify_compact_parts.reference @@ -0,0 +1 @@ +999000 diff --git a/tests/queries/0_stateless/01114_alter_modify_compact_parts.sql b/tests/queries/0_stateless/01114_alter_modify_compact_parts.sql new file mode 100644 index 00000000000..a5aa12548e7 --- /dev/null +++ b/tests/queries/0_stateless/01114_alter_modify_compact_parts.sql @@ -0,0 +1,12 @@ +DROP TABLE IF EXISTS mt_compact; + +CREATE TABLE mt_compact (d Date, id UInt32, s String) + ENGINE = MergeTree ORDER BY id PARTITION BY d + SETTINGS min_bytes_for_wide_part = 10000000, index_granularity = 128; + +INSERT INTO mt_compact SELECT toDate('2020-01-05'), number, toString(number) FROM numbers(1000); +INSERT INTO mt_compact SELECT toDate('2020-01-06'), number, toString(number) FROM numbers(1000); +ALTER TABLE mt_compact MODIFY COLUMN s UInt64; +SELECT sum(s) from mt_compact; + +DROP TABLE IF EXISTS mt_compact; From 458c7f516deb834bcb6775cdec732b404e793ce0 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 8 Apr 2020 15:40:04 +0300 Subject: [PATCH 029/208] Fix extremes for Processors. --- .../ClusterProxy/SelectStreamFactory.cpp | 23 ++- src/Interpreters/InterpreterSelectQuery.cpp | 4 +- .../TreeExecutorBlockInputStream.cpp | 35 +++- .../Executors/TreeExecutorBlockInputStream.h | 5 +- .../Formats/Impl/PrettyBlockOutputFormat.cpp | 4 +- src/Processors/NullSink.h | 11 ++ src/Processors/Pipe.cpp | 19 +- src/Processors/Pipe.h | 6 +- src/Processors/QueryPipeline.cpp | 162 ++++++++++++------ src/Processors/QueryPipeline.h | 2 +- .../Sources/SourceFromInputStream.cpp | 53 ++++-- .../Sources/SourceFromInputStream.h | 10 +- 12 files changed, 243 insertions(+), 91 deletions(-) diff --git a/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp b/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp index 39bbb1eb667..45e2fc9dc4b 100644 --- a/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp +++ b/src/Interpreters/ClusterProxy/SelectStreamFactory.cpp @@ -82,7 +82,16 @@ Pipe createLocalStream(const ASTPtr & query_ast, const Block & header, const Con /// This flag means that pipeline must be tree-shaped, /// so we can't enable processors for InterpreterSelectQuery here. auto stream = interpreter.execute().in; - Pipe pipe(std::make_shared(std::move(stream))); + auto source = std::make_shared(std::move(stream)); + + bool add_totals_and_extremes_port = processed_stage == QueryProcessingStage::Complete; + if (add_totals_and_extremes_port) + { + source->addTotalsPort(); + source->addExtremesPort(); + } + + Pipe pipe(std::move(source)); pipe.addSimpleTransform(std::make_shared( pipe.getHeader(), header, ConvertingTransform::MatchColumnsMode::Name, context)); @@ -130,7 +139,7 @@ void SelectStreamFactory::createForShard( Pipes & res) { bool force_add_agg_info = processed_stage == QueryProcessingStage::WithMergeableState; - bool add_totals_port = processed_stage == QueryProcessingStage::Complete; + bool add_totals_and_extremes_port = processed_stage == QueryProcessingStage::Complete; auto modified_query_ast = query_ast->clone(); if (has_virtual_shard_num_column) @@ -153,8 +162,11 @@ void SelectStreamFactory::createForShard( auto source = std::make_shared(std::move(stream), force_add_agg_info); - if (add_totals_port) + if (add_totals_and_extremes_port) + { source->addTotalsPort(); + source->addExtremesPort(); + } res.emplace_back(std::move(source)); }; @@ -303,8 +315,11 @@ void SelectStreamFactory::createForShard( auto lazy_stream = std::make_shared("LazyShardWithLocalReplica", header, lazily_create_stream); auto source = std::make_shared(std::move(lazy_stream), force_add_agg_info); - if (add_totals_port) + if (add_totals_and_extremes_port) + { source->addTotalsPort(); + source->addExtremesPort(); + } res.emplace_back(std::move(source)); } diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index c58b0eab71b..63007f070db 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -87,7 +87,6 @@ #include #include #include -#include #include #include #include @@ -2541,8 +2540,7 @@ void InterpreterSelectQuery::executeExtremes(QueryPipeline & pipeline) if (!context->getSettingsRef().extremes) return; - auto transform = std::make_shared(pipeline.getHeader()); - pipeline.addExtremesTransform(std::move(transform)); + pipeline.addExtremesTransform(); } diff --git a/src/Processors/Executors/TreeExecutorBlockInputStream.cpp b/src/Processors/Executors/TreeExecutorBlockInputStream.cpp index ee5b254ccf9..84fd97f4781 100644 --- a/src/Processors/Executors/TreeExecutorBlockInputStream.cpp +++ b/src/Processors/Executors/TreeExecutorBlockInputStream.cpp @@ -30,7 +30,10 @@ static void checkProcessorHasSingleOutput(IProcessor * processor) /// Check tree invariants (described in TreeExecutor.h). /// Collect sources with progress. -static void validateTree(const Processors & processors, IProcessor * root, IProcessor * totals_root, std::vector & sources) +static void validateTree( + const Processors & processors, + IProcessor * root, IProcessor * totals_root, IProcessor * extremes_root, + std::vector & sources) { std::unordered_map index; @@ -49,6 +52,8 @@ static void validateTree(const Processors & processors, IProcessor * root, IProc stack.push(root); if (totals_root) stack.push(totals_root); + if (extremes_root) + stack.push(extremes_root); while (!stack.empty()) { @@ -104,11 +109,15 @@ void TreeExecutorBlockInputStream::init() root = &output_port.getProcessor(); IProcessor * totals_root = nullptr; + IProcessor * extremes_root = nullptr; if (totals_port) totals_root = &totals_port->getProcessor(); - validateTree(processors, root, totals_root, sources_with_progress); + if (extremes_port) + extremes_root = &extremes_port->getProcessor(); + + validateTree(processors, root, totals_root, extremes_root, sources_with_progress); input_port = std::make_unique(getHeader(), root); connect(output_port, *input_port); @@ -121,15 +130,24 @@ void TreeExecutorBlockInputStream::init() input_totals_port->setNeeded(); } + if (extremes_port) + { + input_extremes_port = std::make_unique(extremes_port->getHeader(), root); + connect(*extremes_port, *input_extremes_port); + input_extremes_port->setNeeded(); + } + initRowsBeforeLimit(); } -void TreeExecutorBlockInputStream::execute(bool on_totals) +void TreeExecutorBlockInputStream::execute(bool on_totals, bool on_extremes) { std::stack stack; if (on_totals) stack.push(&totals_port->getProcessor()); + else if (on_extremes) + stack.push(&extremes_port->getProcessor()); else stack.push(root); @@ -283,11 +301,18 @@ Block TreeExecutorBlockInputStream::readImpl() { if (totals_port && !input_totals_port->isFinished()) { - execute(true); + execute(true, false); if (input_totals_port->hasData()) totals = getHeader().cloneWithColumns(input_totals_port->pull().detachColumns()); } + if (extremes_port && !input_extremes_port->isFinished()) + { + execute(false, true); + if (input_extremes_port->hasData()) + extremes = getHeader().cloneWithColumns(input_extremes_port->pull().detachColumns()); + } + if (rows_before_limit_at_least && rows_before_limit_at_least->hasAppliedLimit()) info.setRowsBeforeLimit(rows_before_limit_at_least->get()); @@ -311,7 +336,7 @@ Block TreeExecutorBlockInputStream::readImpl() return block; } - execute(false); + execute(false, false); } } diff --git a/src/Processors/Executors/TreeExecutorBlockInputStream.h b/src/Processors/Executors/TreeExecutorBlockInputStream.h index 24cab387eb8..dfe8e66ed09 100644 --- a/src/Processors/Executors/TreeExecutorBlockInputStream.h +++ b/src/Processors/Executors/TreeExecutorBlockInputStream.h @@ -31,6 +31,7 @@ public: interpreter_context.emplace_back(context); totals_port = pipe.getTotalsPort(); + extremes_port = pipe.getExtremesPort(); processors = std::move(pipe).detachProcessors(); init(); } @@ -52,10 +53,12 @@ protected: private: OutputPort & output_port; OutputPort * totals_port = nullptr; + OutputPort * extremes_port = nullptr; Processors processors; IProcessor * root = nullptr; std::unique_ptr input_port; std::unique_ptr input_totals_port; + std::unique_ptr input_extremes_port; RowsBeforeLimitCounterPtr rows_before_limit_at_least; /// Remember sources that support progress. @@ -65,7 +68,7 @@ private: void init(); /// Execute tree step-by-step until root returns next chunk or execution is finished. - void execute(bool on_totals); + void execute(bool on_totals, bool on_extremes); void initRowsBeforeLimit(); diff --git a/src/Processors/Formats/Impl/PrettyBlockOutputFormat.cpp b/src/Processors/Formats/Impl/PrettyBlockOutputFormat.cpp index a816cdd5318..ae86a01a52a 100644 --- a/src/Processors/Formats/Impl/PrettyBlockOutputFormat.cpp +++ b/src/Processors/Formats/Impl/PrettyBlockOutputFormat.cpp @@ -225,7 +225,7 @@ void PrettyBlockOutputFormat::consumeTotals(Chunk chunk) { total_rows = 0; writeSuffixIfNot(); - writeCString("\nExtremes:\n", out); + writeCString("\nTotals:\n", out); write(chunk, PortKind::Totals); } @@ -233,7 +233,7 @@ void PrettyBlockOutputFormat::consumeExtremes(Chunk chunk) { total_rows = 0; writeSuffixIfNot(); - writeCString("\nTotals:\n", out); + writeCString("\nExtremes:\n", out); write(chunk, PortKind::Extremes); } diff --git a/src/Processors/NullSink.h b/src/Processors/NullSink.h index e4968daee29..b3c3bc1ac60 100644 --- a/src/Processors/NullSink.h +++ b/src/Processors/NullSink.h @@ -1,5 +1,6 @@ #pragma once #include +#include namespace DB { @@ -19,4 +20,14 @@ public: InputPort & getPort() { return inputs.front(); } }; +class EmptySink : public ISink +{ +public: + explicit EmptySink(Block header) : ISink(std::move(header)) {} + String getName() const override { return "EmptySink"; } + +protected: + void consume(Chunk) override {} +}; + } diff --git a/src/Processors/Pipe.cpp b/src/Processors/Pipe.cpp index 4461d714264..d9b21dbc854 100644 --- a/src/Processors/Pipe.cpp +++ b/src/Processors/Pipe.cpp @@ -1,5 +1,6 @@ #include #include +#include namespace DB { @@ -48,7 +49,7 @@ static void checkSource(const IProcessor & source) throw Exception("Source for pipe should have single output, but it doesn't have any", ErrorCodes::LOGICAL_ERROR); - if (source.getOutputs().size() > 2) + if (source.getOutputs().size() > 1) throw Exception("Source for pipe should have single or two outputs, but " + source.getName() + " has " + toString(source.getOutputs().size()) + " outputs.", ErrorCodes::LOGICAL_ERROR); } @@ -56,18 +57,22 @@ static void checkSource(const IProcessor & source) Pipe::Pipe(ProcessorPtr source) { - checkSource(*source); - output_port = &source->getOutputs().front(); + if (auto * source_from_input_stream = typeid_cast(source.get())) + { + totals = source_from_input_stream->getTotalsPort(); + extremes = source_from_input_stream->getExtremesPort(); + } + else if (source->getOutputs().size() != 1) + checkSource(*source); - if (source->getOutputs().size() > 1) - totals = &source->getOutputs().back(); + output_port = &source->getOutputs().front(); processors.emplace_back(std::move(source)); max_parallel_streams = 1; } -Pipe::Pipe(Processors processors_, OutputPort * output_port_, OutputPort * totals_) - : processors(std::move(processors_)), output_port(output_port_), totals(totals_) +Pipe::Pipe(Processors processors_, OutputPort * output_port_, OutputPort * totals_, OutputPort * extremes_) + : processors(std::move(processors_)), output_port(output_port_), totals(totals_), extremes(extremes_) { } diff --git a/src/Processors/Pipe.h b/src/Processors/Pipe.h index 60715d986af..42bbd4e06d0 100644 --- a/src/Processors/Pipe.h +++ b/src/Processors/Pipe.h @@ -47,8 +47,11 @@ public: void enableQuota(); + /// Totals and extremes port. void setTotalsPort(OutputPort * totals_) { totals = totals_; } + void setExtremesPort(OutputPort * extremes_) { extremes = extremes_; } OutputPort * getTotalsPort() const { return totals; } + OutputPort * getExtremesPort() const { return extremes; } size_t maxParallelStreams() const { return max_parallel_streams; } @@ -67,6 +70,7 @@ private: Processors processors; OutputPort * output_port = nullptr; OutputPort * totals = nullptr; + OutputPort * extremes = nullptr; /// It is the max number of processors which can be executed in parallel for each step. See QueryPipeline::Streams. size_t max_parallel_streams = 0; @@ -84,7 +88,7 @@ private: /// and therefore we can skip those checks. /// Note that Pipe represents a tree if it was created using public interface. But this constructor can't assert it. /// So, it's possible that TreeExecutorBlockInputStream could be unable to convert such Pipe to IBlockInputStream. - explicit Pipe(Processors processors_, OutputPort * output_port, OutputPort * totals); + explicit Pipe(Processors processors_, OutputPort * output_port, OutputPort * totals, OutputPort * extremes); friend class QueryPipeline; }; diff --git a/src/Processors/QueryPipeline.cpp b/src/Processors/QueryPipeline.cpp index ee6938a48a6..d20086e726f 100644 --- a/src/Processors/QueryPipeline.cpp +++ b/src/Processors/QueryPipeline.cpp @@ -60,6 +60,58 @@ void QueryPipeline::init(Pipe pipe) init(std::move(pipes)); } +static OutputPort * uniteExtremes(const std::vector & ports, const Block & header, Processors & processors) +{ + /// Here we calculate extremes for extremes in case we unite several pipelines. + /// Example: select number from numbers(2) union all select number from numbers(3) + + /// ->> Resize -> Extremes --(output port)----> Null + /// --(extremes port)--> ... + + auto resize = std::make_shared(header, ports.size(), 1); + auto extremes = std::make_shared(header); + auto sink = std::make_shared(header); + + auto * extremes_port = &extremes->getExtremesPort(); + + auto in = resize->getInputs().begin(); + for (auto & port : ports) + connect(*port, *(in++)); + + connect(resize->getOutputs().front(), extremes->getInputPort()); + connect(extremes->getOutputPort(), sink->getPort()); + + processors.emplace_back(std::move(resize)); + processors.emplace_back(std::move(extremes)); + processors.emplace_back(std::move(sink)); + + return extremes_port; +} + +static OutputPort * uniteTotals(const std::vector & ports, const Block & header, Processors & processors) +{ + /// Calculate totals fro several streams. + /// Take totals from first sources which has any, skip others. + + /// ->> Concat -> Limit + + auto concat = std::make_shared(header, ports.size()); + auto limit = std::make_shared(header, 1, 0); + + auto * totals_port = &limit->getOutputPort(); + + auto in = concat->getInputs().begin(); + for (auto & port : ports) + connect(*port, *(in++)); + + connect(concat->getOutputs().front(), limit->getInputPort()); + + processors.emplace_back(std::move(concat)); + processors.emplace_back(std::move(limit)); + + return totals_port; +} + void QueryPipeline::init(Pipes pipes) { if (initialized()) @@ -82,6 +134,7 @@ void QueryPipeline::init(Pipes pipes) } std::vector totals; + std::vector extremes; for (auto & pipe : pipes) { @@ -98,6 +151,12 @@ void QueryPipeline::init(Pipes pipes) totals.emplace_back(totals_port); } + if (auto * extremes_port_ = pipe.getExtremesPort()) + { + assertBlocksHaveEqualStructure(current_header, extremes_port_->getHeader(), "QueryPipeline"); + extremes.emplace_back(extremes_port_); + } + streams.addStream(&pipe.getPort(), pipe.maxParallelStreams()); auto cur_processors = std::move(pipe).detachProcessors(); processors.insert(processors.end(), cur_processors.begin(), cur_processors.end()); @@ -108,15 +167,15 @@ void QueryPipeline::init(Pipes pipes) if (totals.size() == 1) totals_having_port = totals.back(); else - { - auto resize = std::make_shared(current_header, totals.size(), 1); - auto in = resize->getInputs().begin(); - for (auto & total : totals) - connect(*total, *(in++)); + totals_having_port = uniteTotals(totals, current_header, processors); + } - totals_having_port = &resize->getOutputs().front(); - processors.emplace_back(std::move(resize)); - } + if (!extremes.empty()) + { + if (extremes.size() == 1) + extremes_port = extremes.back(); + else + extremes_port = uniteExtremes(extremes, current_header, processors); } } @@ -356,29 +415,31 @@ void QueryPipeline::dropTotalsIfHas() } } -void QueryPipeline::addExtremesTransform(ProcessorPtr transform) +void QueryPipeline::addExtremesTransform() { checkInitialized(); - if (!typeid_cast(transform.get())) - throw Exception("ExtremesTransform expected for QueryPipeline::addExtremesTransform.", - ErrorCodes::LOGICAL_ERROR); - if (extremes_port) throw Exception("Extremes transform was already added to pipeline.", ErrorCodes::LOGICAL_ERROR); - if (getNumStreams() != 1) - throw Exception("Cant't add Extremes transform because pipeline is expected to have single stream, " - "but it has " + toString(getNumStreams()) + " streams.", ErrorCodes::LOGICAL_ERROR); + std::vector extremes; + extremes.reserve(streams.size()); - connect(*streams.front(), transform->getInputs().front()); + for (auto & stream : streams) + { + auto transform = std::make_shared(current_header); + connect(*stream, transform->getInputPort()); - auto & outputs = transform->getOutputs(); + stream = &transform->getOutputPort(); + extremes.push_back(&transform->getExtremesPort()); - streams.assign({ &outputs.front() }); - extremes_port = &outputs.back(); - current_header = outputs.front().getHeader(); - processors.emplace_back(std::move(transform)); + processors.emplace_back(std::move(transform)); + } + + if (extremes.size() == 1) + extremes_port = extremes.front(); + else + extremes_port = uniteExtremes(extremes, current_header, processors); } void QueryPipeline::addCreatingSetsTransform(ProcessorPtr transform) @@ -455,6 +516,13 @@ void QueryPipeline::unitePipelines( }); std::vector extremes; + std::vector totals; + + if (extremes_port) + extremes.push_back(extremes_port); + + if (totals_having_port) + totals.push_back(totals_having_port); for (auto & pipeline : pipelines) { @@ -479,17 +547,12 @@ void QueryPipeline::unitePipelines( /// Take totals only from first port. if (pipeline.totals_having_port) { - if (!totals_having_port) - { - auto converting = std::make_shared( - pipeline.current_header, common_header, ConvertingTransform::MatchColumnsMode::Position, context); + auto converting = std::make_shared( + pipeline.current_header, common_header, ConvertingTransform::MatchColumnsMode::Position, context); - connect(*pipeline.totals_having_port, converting->getInputPort()); - totals_having_port = &converting->getOutputPort(); - processors.push_back(std::move(converting)); - } - else - pipeline.dropTotalsIfHas(); + connect(*pipeline.totals_having_port, converting->getInputPort()); + totals.push_back(&converting->getOutputPort()); + processors.push_back(std::move(converting)); } processors.insert(processors.end(), pipeline.processors.begin(), pipeline.processors.end()); @@ -504,28 +567,18 @@ void QueryPipeline::unitePipelines( if (!extremes.empty()) { - size_t num_inputs = extremes.size() + (extremes_port ? 1u : 0u); - - if (num_inputs == 1) - extremes_port = extremes.front(); + if (extremes.size() == 1) + extremes_port = extremes.back(); else - { - /// Add extra processor for extremes. - auto resize = std::make_shared(current_header, num_inputs, 1); - auto input = resize->getInputs().begin(); + extremes_port = uniteExtremes(extremes, current_header, processors); + } - if (extremes_port) - connect(*extremes_port, *(input++)); - - for (auto & output : extremes) - connect(*output, *(input++)); - - auto transform = std::make_shared(current_header); - extremes_port = &transform->getOutputPort(); - - connect(resize->getOutputs().front(), transform->getInputPort()); - processors.emplace_back(std::move(transform)); - } + if (!totals.empty()) + { + if (totals.size() == 1) + totals_having_port = totals.back(); + else + totals_having_port = uniteTotals(totals, current_header, processors); } } @@ -644,7 +697,7 @@ void QueryPipeline::initRowsBeforeLimit() Pipe QueryPipeline::getPipe() && { resize(1); - Pipe pipe(std::move(processors), streams.at(0), totals_having_port); + Pipe pipe(std::move(processors), streams.at(0), totals_having_port, extremes_port); pipe.max_parallel_streams = streams.maxParallelStreams(); for (auto & lock : table_locks) @@ -659,6 +712,9 @@ Pipe QueryPipeline::getPipe() && if (totals_having_port) pipe.setTotalsPort(totals_having_port); + if (extremes_port) + pipe.setExtremesPort(extremes_port); + return pipe; } diff --git a/src/Processors/QueryPipeline.h b/src/Processors/QueryPipeline.h index 9ce12e75b91..e8ba80cf65b 100644 --- a/src/Processors/QueryPipeline.h +++ b/src/Processors/QueryPipeline.h @@ -99,7 +99,7 @@ public: void addSimpleTransform(const ProcessorGetterWithStreamKind & getter); void addPipe(Processors pipe); void addTotalsHavingTransform(ProcessorPtr transform); - void addExtremesTransform(ProcessorPtr transform); + void addExtremesTransform(); void addCreatingSetsTransform(ProcessorPtr transform); void setOutput(ProcessorPtr output); diff --git a/src/Processors/Sources/SourceFromInputStream.cpp b/src/Processors/Sources/SourceFromInputStream.cpp index 6f2a7eeb28a..e7ca28f72b9 100644 --- a/src/Processors/Sources/SourceFromInputStream.cpp +++ b/src/Processors/Sources/SourceFromInputStream.cpp @@ -28,11 +28,20 @@ void SourceFromInputStream::init() void SourceFromInputStream::addTotalsPort() { - if (has_totals_port) + if (totals_port) throw Exception("Totals port was already added for SourceFromInputStream.", ErrorCodes::LOGICAL_ERROR); outputs.emplace_back(outputs.front().getHeader(), this); - has_totals_port = true; + totals_port = &outputs.back(); +} + +void SourceFromInputStream::addExtremesPort() +{ + if (extremes_port) + throw Exception("Extremes port was already added for SourceFromInputStream.", ErrorCodes::LOGICAL_ERROR); + + outputs.emplace_back(outputs.front().getHeader(), this); + extremes_port = &outputs.back(); } IProcessor::Status SourceFromInputStream::prepare() @@ -47,23 +56,32 @@ IProcessor::Status SourceFromInputStream::prepare() if (!is_stream_finished && !isCancelled()) return Status::Ready; - if (has_totals_port) + if (totals_port && !totals_port->isFinished()) { - auto & totals_out = outputs.back(); - - if (totals_out.isFinished()) - return Status::Finished; - if (has_totals) { - if (!totals_out.canPush()) + if (!totals_port->canPush()) return Status::PortFull; - totals_out.push(std::move(totals)); + totals_port->push(std::move(totals)); has_totals = false; } - totals_out.finish(); + totals_port->finish(); + } + + if (extremes_port && !extremes_port->isFinished()) + { + if (has_extremes) + { + if (!extremes_port->canPush()) + return Status::PortFull; + + extremes_port->push(std::move(extremes)); + has_extremes = false; + } + + extremes_port->finish(); } } @@ -138,13 +156,22 @@ Chunk SourceFromInputStream::generate() if (auto totals_block = stream->getTotals()) { - if (totals_block.rows() == 1) /// Sometimes we can get empty totals. Skip it. + if (totals_block.rows() > 0) /// Sometimes we can get empty totals. Skip it. { - totals.setColumns(totals_block.getColumns(), 1); + totals.setColumns(totals_block.getColumns(), totals_block.rows()); has_totals = true; } } + if (auto extremes_block = stream->getExtremes()) + { + if (extremes_block.rows() > 0) /// Sometimes we can get empty extremes. Skip it. + { + extremes.setColumns(extremes_block.getColumns(), extremes_block.rows()); + has_extremes = true; + } + } + is_stream_finished = true; return {}; } diff --git a/src/Processors/Sources/SourceFromInputStream.h b/src/Processors/Sources/SourceFromInputStream.h index 0fc92164059..b547e6a6d1f 100644 --- a/src/Processors/Sources/SourceFromInputStream.h +++ b/src/Processors/Sources/SourceFromInputStream.h @@ -23,6 +23,10 @@ public: BlockInputStreamPtr & getStream() { return stream; } void addTotalsPort(); + void addExtremesPort(); + + OutputPort * getTotalsPort() const { return totals_port; } + OutputPort * getExtremesPort() const { return extremes_port; } void setRowsBeforeLimitCounter(RowsBeforeLimitCounterPtr counter) { rows_before_limit.swap(counter); } @@ -44,9 +48,13 @@ private: RowsBeforeLimitCounterPtr rows_before_limit; Chunk totals; - bool has_totals_port = false; + OutputPort * totals_port = nullptr; bool has_totals = false; + Chunk extremes; + OutputPort * extremes_port = nullptr; + bool has_extremes = false; + bool is_generating_finished = false; bool is_stream_finished = false; bool is_stream_started = false; From b9f73a9f772935f27c5de2134daeb56677eb6913 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Wed, 8 Apr 2020 21:48:46 +0300 Subject: [PATCH 030/208] Added test. --- .../0_stateless/01232_extremes.reference | 110 ++++++++++++++++++ tests/queries/0_stateless/01232_extremes.sql | 51 ++++++++ 2 files changed, 161 insertions(+) create mode 100644 tests/queries/0_stateless/01232_extremes.reference create mode 100644 tests/queries/0_stateless/01232_extremes.sql diff --git a/tests/queries/0_stateless/01232_extremes.reference b/tests/queries/0_stateless/01232_extremes.reference new file mode 100644 index 00000000000..d5b66dcbd4b --- /dev/null +++ b/tests/queries/0_stateless/01232_extremes.reference @@ -0,0 +1,110 @@ +0 +1 + +0 +1 +- + +- +- +0 +1 +0 +1 + +0 +1 +- + +- +- +0 +1 +0 +1 + +0 +1 +- + +- +- +0 +1 +0 +1 + +0 +1 +- + +- +- +0 +1 + +0 +1 +------ + +------ +------ +0 +0 +0 +1 +1 +2 + +0 +2 +- + +- +- +0 +0 +0 +1 +1 +2 + +0 +2 +- + +- +- +0 +0 +0 +1 +1 +2 + +0 +2 +------ + +------ +------ +0 +0 +1 +1 +2 + +0 +2 +- + +- +- +0 +0 +1 +1 +2 + +0 +2 diff --git a/tests/queries/0_stateless/01232_extremes.sql b/tests/queries/0_stateless/01232_extremes.sql new file mode 100644 index 00000000000..80bf628d669 --- /dev/null +++ b/tests/queries/0_stateless/01232_extremes.sql @@ -0,0 +1,51 @@ +set send_logs_level = 'error'; +set extremes = 1; +-- set experimental_use_processors=0; + +select * from remote('127.0.0.1', numbers(2)); +select '-'; +select * from remote('127.0.0.{1,1}', numbers(2)); +select '-'; +select * from remote('127.0.0.{1,2}', numbers(2)); +select '-'; +select * from remote('127.0.0.{2,2}', numbers(2)); +select '-'; +select * from remote('127.0.0.2', numbers(2)); +select '------'; + +select * from (select * from numbers(2) union all select * from numbers(3) union all select * from numbers(1)) order by number; +select '-'; +select * from (select * from numbers(1) union all select * from numbers(2) union all select * from numbers(3)) order by number; +select '-'; +select * from (select * from numbers(3) union all select * from numbers(1) union all select * from numbers(2)) order by number; +select '------'; + +create database if not exists shard_0; +create database if not exists shard_1; + +drop table if exists shard_0.num_01232; +drop table if exists shard_0.num2_01232; +drop table if exists shard_1.num_01232; +drop table if exists shard_1.num2_01232; + +create table shard_0.num_01232 (number UInt64) engine = MergeTree order by number; +create table shard_1.num_01232 (number UInt64) engine = MergeTree order by number; +insert into shard_0.num_01232 select number from numbers(2); +insert into shard_1.num_01232 select number from numbers(3); +create table distr (number UInt64) engine = Distributed(test_cluster_two_shards_different_databases, '', num_01232); + +create table shard_0.num2_01232 (number UInt64) engine = MergeTree order by number; +create table shard_1.num2_01232 (number UInt64) engine = MergeTree order by number; +insert into shard_0.num2_01232 select number from numbers(3); +insert into shard_1.num2_01232 select number from numbers(2); +create table distr2 (number UInt64) engine = Distributed(test_cluster_two_shards_different_databases, '', num2_01232); + +select * from distr order by number; +select '-'; +select * from distr2 order by number; + +drop table if exists shard_0.num_01232; +drop table if exists shard_0.num2_01232; +drop table if exists shard_1.num_01232; +drop table if exists shard_1.num2_01232; + From b666f60af87e2bbc86990cacbcbc23c760cce3f7 Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev Date: Mon, 6 Apr 2020 22:27:57 +0300 Subject: [PATCH 031/208] Optional secured communication between ClickHouse and Zookeeper --- programs/server/config.xml | 2 +- src/Common/ZooKeeper/CMakeLists.txt | 4 ++ src/Common/ZooKeeper/ZooKeeper.cpp | 29 ++++++---- src/Common/ZooKeeper/ZooKeeper.h | 4 ++ src/Common/ZooKeeper/ZooKeeperImpl.cpp | 53 ++++++++++++++----- src/Common/ZooKeeper/ZooKeeperImpl.h | 13 +++-- .../tests/zkutil_test_commands_new_lib.cpp | 25 ++++++--- src/Common/ZooKeeper/tests/zookeeper_impl.cpp | 2 +- .../configs/config.xml | 2 +- tests/server-test.xml | 2 +- 10 files changed, 97 insertions(+), 39 deletions(-) diff --git a/programs/server/config.xml b/programs/server/config.xml index f55ab02d903..fb2f9be6e24 100644 --- a/programs/server/config.xml +++ b/programs/server/config.xml @@ -37,7 +37,7 @@ true - + true true sslv2,sslv3 diff --git a/src/Common/ZooKeeper/CMakeLists.txt b/src/Common/ZooKeeper/CMakeLists.txt index aa6efcd3ca1..4dbf999419e 100644 --- a/src/Common/ZooKeeper/CMakeLists.txt +++ b/src/Common/ZooKeeper/CMakeLists.txt @@ -7,6 +7,10 @@ add_library(clickhouse_common_zookeeper ${clickhouse_common_zookeeper_headers} $ target_link_libraries (clickhouse_common_zookeeper PUBLIC clickhouse_common_io common PRIVATE string_utils PUBLIC ${Poco_Util_LIBRARY}) target_include_directories(clickhouse_common_zookeeper PUBLIC ${DBMS_INCLUDE_DIR}) +if (USE_POCO_NETSSL) + target_link_libraries (clickhouse_common_zookeeper PRIVATE ${Poco_NetSSL_LIBRARY} ${Poco_Crypto_LIBRARY}) +endif() + if (ENABLE_TESTS) add_subdirectory (tests) endif () diff --git a/src/Common/ZooKeeper/ZooKeeper.cpp b/src/Common/ZooKeeper/ZooKeeper.cpp index 99c3f115021..f2442f3f5c5 100644 --- a/src/Common/ZooKeeper/ZooKeeper.cpp +++ b/src/Common/ZooKeeper/ZooKeeper.cpp @@ -59,30 +59,36 @@ void ZooKeeper::init(const std::string & implementation_, const std::string & ho if (implementation == "zookeeper") { if (hosts.empty()) - throw KeeperException("No addresses passed to ZooKeeper constructor.", Coordination::ZBADARGUMENTS); + throw KeeperException("No hosts passed to ZooKeeper constructor.", Coordination::ZBADARGUMENTS); - std::vector addresses_strings; - splitInto<','>(addresses_strings, hosts); - Coordination::ZooKeeper::Addresses addresses; - addresses.reserve(addresses_strings.size()); + std::vector hosts_strings; + splitInto<','>(hosts_strings, hosts); + Coordination::ZooKeeper::Nodes nodes; + nodes.reserve(hosts_strings.size()); - for (const auto & address_string : addresses_strings) + for (auto & host_string : hosts_strings) { try { - addresses.emplace_back(address_string); + bool secure = bool(startsWith(host_string, "secure://")); + + if (secure) { + host_string.erase(0, strlen("secure://")); + } + + nodes.emplace_back(Coordination::ZooKeeper::Node{Poco::Net::SocketAddress{host_string}, secure}); } catch (const Poco::Net::DNSException & e) { - LOG_ERROR(log, "Cannot use ZooKeeper address " << address_string << ", reason: " << e.displayText()); + LOG_ERROR(log, "Cannot use ZooKeeper host " << host_string << ", reason: " << e.displayText()); } } - if (addresses.empty()) - throw KeeperException("Cannot use any of provided ZooKeeper addresses", Coordination::ZBADARGUMENTS); + if (nodes.empty()) + throw KeeperException("Cannot use any of provided ZooKeeper nodes", Coordination::ZBADARGUMENTS); impl = std::make_unique( - addresses, + nodes, chroot, identity_.empty() ? "" : "digest", identity_, @@ -130,6 +136,7 @@ struct ZooKeeperArgs if (startsWith(key, "node")) { hosts_strings.push_back( + (config.getBool(config_name + "." + key + ".secure", false) ? "secure://" : "") + config.getString(config_name + "." + key + ".host") + ":" + config.getString(config_name + "." + key + ".port", "2181") ); diff --git a/src/Common/ZooKeeper/ZooKeeper.h b/src/Common/ZooKeeper/ZooKeeper.h index 2d4d449b1a6..db166314a07 100644 --- a/src/Common/ZooKeeper/ZooKeeper.h +++ b/src/Common/ZooKeeper/ZooKeeper.h @@ -63,10 +63,14 @@ public: example1 2181 + + 1 example2 2181 + + 1 30000 10000 diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.cpp b/src/Common/ZooKeeper/ZooKeeperImpl.cpp index b8700a93e35..2fba10b20e9 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.cpp +++ b/src/Common/ZooKeeper/ZooKeeperImpl.cpp @@ -11,6 +11,11 @@ #include #include +#include +#if USE_POCO_NETSSL +#include +#endif + #include @@ -44,6 +49,13 @@ namespace CurrentMetrics extern const Metric ZooKeeperWatch; } +namespace DB +{ + namespace ErrorCodes + { + extern const int SUPPORT_IS_DISABLED; + } +} /** ZooKeeper wire protocol. @@ -817,7 +829,7 @@ ZooKeeper::~ZooKeeper() ZooKeeper::ZooKeeper( - const Addresses & addresses, + const Nodes & nodes, const String & root_path_, const String & auth_scheme, const String & auth_data, @@ -851,7 +863,7 @@ ZooKeeper::ZooKeeper( default_acls.emplace_back(std::move(acl)); } - connect(addresses, connection_timeout); + connect(nodes, connection_timeout); if (!auth_scheme.empty()) sendAuth(auth_scheme, auth_data); @@ -864,11 +876,11 @@ ZooKeeper::ZooKeeper( void ZooKeeper::connect( - const Addresses & addresses, + const Nodes & nodes, Poco::Timespan connection_timeout) { - if (addresses.empty()) - throw Exception("No addresses passed to ZooKeeper constructor", ZBADARGUMENTS); + if (nodes.empty()) + throw Exception("No nodes passed to ZooKeeper constructor", ZBADARGUMENTS); static constexpr size_t num_tries = 3; bool connected = false; @@ -876,12 +888,25 @@ void ZooKeeper::connect( WriteBufferFromOwnString fail_reasons; for (size_t try_no = 0; try_no < num_tries; ++try_no) { - for (const auto & address : addresses) + for (const auto & node : nodes) { try { - socket = Poco::Net::StreamSocket(); /// Reset the state of previous attempt. - socket.connect(address, connection_timeout); + /// Reset the state of previous attempt. + if (node.secure) + { +#if USE_POCO_NETSSL + socket = Poco::Net::SecureStreamSocket(); +#else + throw Exception{"Communication with ZooKeeper over SSL is disabled because poco library was built without NetSSL support.", ErrorCodes::SUPPORT_IS_DISABLED}; +#endif + } + else + { + socket = Poco::Net::StreamSocket(); + } + + socket.connect(node.address, connection_timeout); socket.setReceiveTimeout(operation_timeout); socket.setSendTimeout(operation_timeout); @@ -915,7 +940,7 @@ void ZooKeeper::connect( } catch (...) { - fail_reasons << "\n" << getCurrentExceptionMessage(false) << ", " << address.toString(); + fail_reasons << "\n" << getCurrentExceptionMessage(false) << ", " << node.address.toString(); } } @@ -926,15 +951,19 @@ void ZooKeeper::connect( if (!connected) { WriteBufferFromOwnString message; - message << "All connection tries failed while connecting to ZooKeeper. Addresses: "; + message << "All connection tries failed while connecting to ZooKeeper. nodes: "; bool first = true; - for (const auto & address : addresses) + for (const auto & node : nodes) { if (first) first = false; else message << ", "; - message << address.toString(); + + if (node.secure) + message << "secure://"; + + message << node.address.toString(); } message << fail_reasons.str() << "\n"; diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.h b/src/Common/ZooKeeper/ZooKeeperImpl.h index 88e949dbd45..069df723d43 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.h +++ b/src/Common/ZooKeeper/ZooKeeperImpl.h @@ -93,17 +93,22 @@ struct ZooKeeperRequest; class ZooKeeper : public IKeeper { public: - using Addresses = std::vector; + struct Node { + Poco::Net::SocketAddress address; + bool secure; + }; + + using Nodes = std::vector; using XID = int32_t; using OpNum = int32_t; - /** Connection to addresses is performed in order. If you want, shuffle them manually. + /** Connection to nodes is performed in order. If you want, shuffle them manually. * Operation timeout couldn't be greater than session timeout. * Operation timeout applies independently for network read, network write, waiting for events and synchronization. */ ZooKeeper( - const Addresses & addresses, + const Nodes & nodes, const String & root_path, const String & auth_scheme, const String & auth_data, @@ -213,7 +218,7 @@ private: ThreadFromGlobalPool receive_thread; void connect( - const Addresses & addresses, + const Nodes & node, Poco::Timespan connection_timeout); void sendHandshake(); diff --git a/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp b/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp index aa348163adf..0bca8e0f561 100644 --- a/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp +++ b/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -23,15 +24,23 @@ try Poco::Logger::root().setChannel(channel); Poco::Logger::root().setLevel("trace"); - std::string addresses_arg = argv[1]; - std::vector addresses_strings; - splitInto<','>(addresses_strings, addresses_arg); - ZooKeeper::Addresses addresses; - addresses.reserve(addresses_strings.size()); - for (const auto & address_string : addresses_strings) - addresses.emplace_back(address_string); + std::string hosts_arg = argv[1]; + std::vector hosts_strings; + splitInto<','>(hosts_strings, hosts_arg); + ZooKeeper::Nodes nodes; + nodes.reserve(hosts_strings.size()); + for (auto & host_string : hosts_strings) { + bool secure = bool(startsWith(host_string, "secure://")); - ZooKeeper zk(addresses, {}, {}, {}, {5, 0}, {0, 50000}, {0, 50000}); + if (secure) { + host_string.erase(0, strlen("secure://")); + } + + nodes.emplace_back(ZooKeeper::Node{Poco::Net::SocketAddress{host_string},secure}); + } + + + ZooKeeper zk(nodes, {}, {}, {}, {5, 0}, {0, 50000}, {0, 50000}); Poco::Event event(true); diff --git a/src/Common/ZooKeeper/tests/zookeeper_impl.cpp b/src/Common/ZooKeeper/tests/zookeeper_impl.cpp index da609a7bc72..74ba63514f2 100644 --- a/src/Common/ZooKeeper/tests/zookeeper_impl.cpp +++ b/src/Common/ZooKeeper/tests/zookeeper_impl.cpp @@ -5,7 +5,7 @@ int main() try { - Coordination::ZooKeeper zookeeper({Poco::Net::SocketAddress{"localhost:2181"}}, "", "", "", {30, 0}, {0, 50000}, {0, 50000}); + Coordination::ZooKeeper zookeeper({Coordination::ZooKeeper::Node{Poco::Net::SocketAddress{"localhost:2181"}, false}}, "", "", "", {30, 0}, {0, 50000}, {0, 50000}); zookeeper.create("/test", "hello", false, false, {}, [](const Coordination::CreateResponse & response) { diff --git a/tests/integration/test_config_corresponding_root/configs/config.xml b/tests/integration/test_config_corresponding_root/configs/config.xml index 154ebf6c35e..4e130afa84d 100644 --- a/tests/integration/test_config_corresponding_root/configs/config.xml +++ b/tests/integration/test_config_corresponding_root/configs/config.xml @@ -37,7 +37,7 @@ true - + true true sslv2,sslv3 diff --git a/tests/server-test.xml b/tests/server-test.xml index c2356ec1ba0..7f792479065 100644 --- a/tests/server-test.xml +++ b/tests/server-test.xml @@ -31,7 +31,7 @@ true - + true true sslv2,sslv3 From e544edd72643a804fe9fe75e723f1eadc3a6bae9 Mon Sep 17 00:00:00 2001 From: BohuTANG Date: Thu, 9 Apr 2020 09:43:02 +0800 Subject: [PATCH 032/208] Fix random scramble using seperator character issue during MySQL handshakes --- src/Core/MySQLProtocol.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Core/MySQLProtocol.h b/src/Core/MySQLProtocol.h index 1fae57517c1..5adcf836c18 100644 --- a/src/Core/MySQLProtocol.h +++ b/src/Core/MySQLProtocol.h @@ -914,8 +914,16 @@ public: scramble.resize(SCRAMBLE_LENGTH + 1, 0); Poco::RandomInputStream generator; - for (size_t i = 0; i < SCRAMBLE_LENGTH; i++) + /** Generate a random string using ASCII characters but avoid seperator character, + * produce pseudo random numbers between with about 7 bit worth of entropty between 1-127. + * https://github.com/mysql/mysql-server/blob/8.0/mysys/crypt_genhash_impl.cc#L427 + */ + for (size_t i = 0; i < SCRAMBLE_LENGTH; i++){ generator >> scramble[i]; + scramble[i] &= 0x7f; + if (scramble[i] == '\0' || scramble[i] == '$') + scramble[i] = scramble[i] + 1; + } } String getName() override @@ -993,8 +1001,12 @@ public: scramble.resize(SCRAMBLE_LENGTH + 1, 0); Poco::RandomInputStream generator; - for (size_t i = 0; i < SCRAMBLE_LENGTH; i++) + for (size_t i = 0; i < SCRAMBLE_LENGTH; i++) { generator >> scramble[i]; + scramble[i] &= 0x7f; + if (scramble[i] == '\0' || scramble[i] == '$') + scramble[i] = scramble[i] + 1; + } } String getName() override From 17256e0f1e02111da6df9902d7c20be231cda8d9 Mon Sep 17 00:00:00 2001 From: BohuTANG Date: Thu, 9 Apr 2020 10:53:40 +0800 Subject: [PATCH 033/208] add java client integation tests --- tests/integration/test_mysql_protocol/test.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/integration/test_mysql_protocol/test.py b/tests/integration/test_mysql_protocol/test.py index b5ee3cecec9..f75a168d5db 100644 --- a/tests/integration/test_mysql_protocol/test.py +++ b/tests/integration/test_mysql_protocol/test.py @@ -278,15 +278,29 @@ def test_java_client(server_address, java_container): with open(os.path.join(SCRIPT_DIR, 'clients', 'java', '0.reference')) as fp: reference = fp.read() + # database not exists exception. code, (stdout, stderr) = java_container.exec_run('java JavaConnectorTest --host {host} --port {port} --user user_with_empty_password --database ' 'abc'.format(host=server_address, port=server_port), demux=True) assert code == 1 + # empty password passed. code, (stdout, stderr) = java_container.exec_run('java JavaConnectorTest --host {host} --port {port} --user user_with_empty_password --database ' 'default'.format(host=server_address, port=server_port), demux=True) assert code == 0 assert stdout == reference + # non-empty password passed. + code, (stdout, stderr) = java_container.exec_run('java JavaConnectorTest --host {host} --port {port} --user default --password 123 --database ' + 'default'.format(host=server_address, port=server_port), demux=True) + assert code == 0 + assert stdout == reference + + # double-sha1 password passed. + code, (stdout, stderr) = java_container.exec_run('java JavaConnectorTest --host {host} --port {port} --user user_with_double_sha1 --password abacaba --database ' + 'default'.format(host=server_address, port=server_port), demux=True) + assert code == 0 + assert stdout == reference + def test_types(server_address): client = pymysql.connections.Connection(host=server_address, user='default', password='123', database='default', port=server_port) From ccf5cb2a668499ad0fd9c275a4e63aeb02cd6d1c Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 9 Apr 2020 06:24:09 +0300 Subject: [PATCH 034/208] Update MySQLProtocol.h --- src/Core/MySQLProtocol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/MySQLProtocol.h b/src/Core/MySQLProtocol.h index 5adcf836c18..e73e1fddd3a 100644 --- a/src/Core/MySQLProtocol.h +++ b/src/Core/MySQLProtocol.h @@ -914,7 +914,7 @@ public: scramble.resize(SCRAMBLE_LENGTH + 1, 0); Poco::RandomInputStream generator; - /** Generate a random string using ASCII characters but avoid seperator character, + /** Generate a random string using ASCII characters but avoid separator character, * produce pseudo random numbers between with about 7 bit worth of entropty between 1-127. * https://github.com/mysql/mysql-server/blob/8.0/mysys/crypt_genhash_impl.cc#L427 */ From cb6c860d898c7e7b1c99b8f98921d51ff5146dd9 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Thu, 9 Apr 2020 06:25:20 +0300 Subject: [PATCH 035/208] Update MySQLProtocol.h --- src/Core/MySQLProtocol.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Core/MySQLProtocol.h b/src/Core/MySQLProtocol.h index e73e1fddd3a..5255c6f263e 100644 --- a/src/Core/MySQLProtocol.h +++ b/src/Core/MySQLProtocol.h @@ -918,7 +918,8 @@ public: * produce pseudo random numbers between with about 7 bit worth of entropty between 1-127. * https://github.com/mysql/mysql-server/blob/8.0/mysys/crypt_genhash_impl.cc#L427 */ - for (size_t i = 0; i < SCRAMBLE_LENGTH; i++){ + for (size_t i = 0; i < SCRAMBLE_LENGTH; ++i) + { generator >> scramble[i]; scramble[i] &= 0x7f; if (scramble[i] == '\0' || scramble[i] == '$') @@ -1001,7 +1002,8 @@ public: scramble.resize(SCRAMBLE_LENGTH + 1, 0); Poco::RandomInputStream generator; - for (size_t i = 0; i < SCRAMBLE_LENGTH; i++) { + for (size_t i = 0; i < SCRAMBLE_LENGTH; ++i) + { generator >> scramble[i]; scramble[i] &= 0x7f; if (scramble[i] == '\0' || scramble[i] == '$') From ae6267070eb6b63d510a78e2558b7a3402a592da Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 9 Apr 2020 09:28:13 +0300 Subject: [PATCH 036/208] Fix style. --- src/Processors/QueryPipeline.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Processors/QueryPipeline.cpp b/src/Processors/QueryPipeline.cpp index d20086e726f..a13547568d1 100644 --- a/src/Processors/QueryPipeline.cpp +++ b/src/Processors/QueryPipeline.cpp @@ -151,10 +151,10 @@ void QueryPipeline::init(Pipes pipes) totals.emplace_back(totals_port); } - if (auto * extremes_port_ = pipe.getExtremesPort()) + if (auto * port = pipe.getExtremesPort()) { - assertBlocksHaveEqualStructure(current_header, extremes_port_->getHeader(), "QueryPipeline"); - extremes.emplace_back(extremes_port_); + assertBlocksHaveEqualStructure(current_header, port->getHeader(), "QueryPipeline"); + extremes.emplace_back(port); } streams.addStream(&pipe.getPort(), pipe.maxParallelStreams()); From e28e5b24e967ac594240d9bd8e0584214b4fcda5 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 9 Apr 2020 09:29:38 +0300 Subject: [PATCH 037/208] Update test. --- tests/queries/0_stateless/01232_extremes.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/queries/0_stateless/01232_extremes.sql b/tests/queries/0_stateless/01232_extremes.sql index 80bf628d669..9379dc1cd38 100644 --- a/tests/queries/0_stateless/01232_extremes.sql +++ b/tests/queries/0_stateless/01232_extremes.sql @@ -27,6 +27,8 @@ drop table if exists shard_0.num_01232; drop table if exists shard_0.num2_01232; drop table if exists shard_1.num_01232; drop table if exists shard_1.num2_01232; +drop table if exists distr; +drop table if exists distr2; create table shard_0.num_01232 (number UInt64) engine = MergeTree order by number; create table shard_1.num_01232 (number UInt64) engine = MergeTree order by number; @@ -48,4 +50,6 @@ drop table if exists shard_0.num_01232; drop table if exists shard_0.num2_01232; drop table if exists shard_1.num_01232; drop table if exists shard_1.num2_01232; +drop table if exists distr; +drop table if exists distr2; From 3149f75430161b8feee13b6759ada45d63f151c9 Mon Sep 17 00:00:00 2001 From: "philip.han" Date: Thu, 9 Apr 2020 17:27:55 +0900 Subject: [PATCH 038/208] Replace a reference for Context with a copied bool value. --- src/Interpreters/ActionsVisitor.cpp | 4 ++-- src/Interpreters/ExpressionAnalyzer.cpp | 2 +- src/Interpreters/Set.cpp | 7 ++++--- src/Interpreters/Set.h | 8 ++++---- src/Storages/StorageSet.cpp | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Interpreters/ActionsVisitor.cpp b/src/Interpreters/ActionsVisitor.cpp index f7d64d54f27..38656c47765 100644 --- a/src/Interpreters/ActionsVisitor.cpp +++ b/src/Interpreters/ActionsVisitor.cpp @@ -186,7 +186,7 @@ SetPtr makeExplicitSet( else throw_unsupported_type(right_arg_type); - SetPtr set = std::make_shared(size_limits, create_ordered_set, context); + SetPtr set = std::make_shared(size_limits, create_ordered_set, context.getSettingsRef().transform_null_in); set->setHeader(block); set->insertFromBlock(block); @@ -654,7 +654,7 @@ SetPtr ActionsMatcher::makeSet(const ASTFunction & node, Data & data, bool no_su return subquery_for_set.set; } - SetPtr set = std::make_shared(data.set_size_limit, false, data.context); + SetPtr set = std::make_shared(data.set_size_limit, false, data.context.getSettingsRef().transform_null_in); /** The following happens for GLOBAL INs: * - in the addExternalStorage function, the IN (SELECT ...) subquery is replaced with IN _data1, diff --git a/src/Interpreters/ExpressionAnalyzer.cpp b/src/Interpreters/ExpressionAnalyzer.cpp index d0b44b91af7..ee3ba3c8b98 100644 --- a/src/Interpreters/ExpressionAnalyzer.cpp +++ b/src/Interpreters/ExpressionAnalyzer.cpp @@ -291,7 +291,7 @@ void SelectQueryExpressionAnalyzer::tryMakeSetForIndexFromSubquery(const ASTPtr auto interpreter_subquery = interpretSubquery(subquery_or_table_name, context, {}, query_options); BlockIO res = interpreter_subquery->execute(); - SetPtr set = std::make_shared(settings.size_limits_for_set, true, context); + SetPtr set = std::make_shared(settings.size_limits_for_set, true, context.getSettingsRef().transform_null_in); set->setHeader(res.in->getHeader()); res.in->readPrefix(); diff --git a/src/Interpreters/Set.cpp b/src/Interpreters/Set.cpp index e63eff37047..0504f9d9e6d 100644 --- a/src/Interpreters/Set.cpp +++ b/src/Interpreters/Set.cpp @@ -140,7 +140,7 @@ void Set::setHeader(const Block & header) /// We will insert to the Set only keys, where all components are not NULL. ConstNullMapPtr null_map{}; - ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, context.getSettingsRef().transform_null_in); + ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, transform_null_in); if (fill_set_elements) { @@ -230,7 +230,7 @@ static Field extractValueFromNode(const ASTPtr & node, const IDataType & type, c throw Exception("Incorrect element of set. Must be literal or constant expression.", ErrorCodes::INCORRECT_ELEMENT_OF_SET); } -void Set::createFromAST(const DataTypes & types, ASTPtr node) +void Set::createFromAST(const DataTypes & types, ASTPtr node, const Context & context) { /// Will form a block with values from the set. @@ -350,7 +350,8 @@ ColumnPtr Set::execute(const Block & block, bool negative) const /// We will check existence in Set only for keys, where all components are not NULL. ConstNullMapPtr null_map{}; - ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, context.getSettingsRef().transform_null_in); + + ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, transform_null_in); executeOrdinary(key_columns, vec_res, negative, null_map); diff --git a/src/Interpreters/Set.h b/src/Interpreters/Set.h index da20ffc41b6..90ff6c48dec 100644 --- a/src/Interpreters/Set.h +++ b/src/Interpreters/Set.h @@ -30,9 +30,9 @@ public: /// (that is useful only for checking that some value is in the set and may not store the original values), /// store all set elements in explicit form. /// This is needed for subsequent use for index. - Set(const SizeLimits & limits_, bool fill_set_elements_, const Context & context_) + Set(const SizeLimits & limits_, bool fill_set_elements_, bool transform_null_in_) : log(&Logger::get("Set")), - limits(limits_), fill_set_elements(fill_set_elements_), context(context_) + limits(limits_), fill_set_elements(fill_set_elements_), transform_null_in(transform_null_in_) { } @@ -45,7 +45,7 @@ public: * 'types' - types of what are on the left hand side of IN. * 'node' - list of values: 1, 2, 3 or list of tuples: (1, 2), (3, 4), (5, 6). */ - void createFromAST(const DataTypes & types, ASTPtr node); + void createFromAST(const DataTypes & types, ASTPtr node, const Context & context); /** Create a Set from stream. * Call setHeader, then call insertFromBlock for each block. @@ -113,7 +113,7 @@ private: /// Do we need to additionally store all elements of the set in explicit form for subsequent use for index. bool fill_set_elements; - const Context & context; + bool transform_null_in; bool has_null = false; diff --git a/src/Storages/StorageSet.cpp b/src/Storages/StorageSet.cpp index 45e1f81b487..7d2a7ee128f 100644 --- a/src/Storages/StorageSet.cpp +++ b/src/Storages/StorageSet.cpp @@ -112,7 +112,7 @@ StorageSet::StorageSet( const ConstraintsDescription & constraints_, const Context & context_) : StorageSetOrJoinBase{relative_path_, table_id_, columns_, constraints_, context_}, - set(std::make_shared(SizeLimits(), false, context_)) + set(std::make_shared(SizeLimits(), false, context_.getSettingsRef().transform_null_in)) { Block header = getSampleBlock(); header = header.sortColumns(); @@ -137,7 +137,7 @@ void StorageSet::truncate(const ASTPtr &, const Context & context, TableStructur header = header.sortColumns(); increment = 0; - set = std::make_shared(SizeLimits(), false, context); + set = std::make_shared(SizeLimits(), false, context.getSettingsRef().transform_null_in); set->setHeader(header); } From 9f5a40e7004f8aaa233fea7e64c38cd2d948450b Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Thu, 9 Apr 2020 13:35:51 +0300 Subject: [PATCH 039/208] Added comment. --- src/Processors/NullSink.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Processors/NullSink.h b/src/Processors/NullSink.h index b3c3bc1ac60..5d304a0d68e 100644 --- a/src/Processors/NullSink.h +++ b/src/Processors/NullSink.h @@ -5,6 +5,7 @@ namespace DB { +/// Sink which closes input port and reads nothing. class NullSink : public IProcessor { public: @@ -20,6 +21,7 @@ public: InputPort & getPort() { return inputs.front(); } }; +/// Sink which reads everything and do nothing with it. class EmptySink : public ISink { public: From 7cc0c99669bbec93fa7d57ed034199ba7db6c19c Mon Sep 17 00:00:00 2001 From: Mikhail Filimonov Date: Thu, 9 Apr 2020 15:16:56 +0200 Subject: [PATCH 040/208] clickhouse-docker-util --- utils/clickhouse-docker | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100755 utils/clickhouse-docker diff --git a/utils/clickhouse-docker b/utils/clickhouse-docker new file mode 100755 index 00000000000..6f2d1197c0a --- /dev/null +++ b/utils/clickhouse-docker @@ -0,0 +1,57 @@ +#!/bin/bash + +if [ $# -lt 1 ] +then +cat << HELP + +clickhouse-docker -- open clickhouse-client of desired version in docker container (automatically removed after you exit bash shell). + +EXAMPLE: + - start latest version: + clickhouse-docker latest + + - start version 20.1: + clickhouse-docker 20.1 + + - list avaliable versions: + clickhouse-docker list +HELP +exit +fi + +param="$1" + +if [ "${param}" = "list" ] +then + # https://stackoverflow.com/a/39454426/1555175 + wget -q https://registry.hub.docker.com/v1/repositories/yandex/clickhouse-server/tags -O - | sed -e 's/[][]//g' -e 's/"//g' -e 's/ //g' | tr '}' '\n' | awk -F: '{print $3}' +else + docker pull yandex/clickhouse-server:${param} + tmp_dir=$(mktemp -d -t ci-XXXXXXXXXX) # older version require /nonexistent folder to exist to run clickhouse client :D + chmod 777 ${tmp_dir} + set -e + containerid=`docker run -v${tmp_dir}:/nonexistent -d yandex/clickhouse-server:${param}` + set +e + while : + do + # that trick with init-file allows to start clickhouse client inside bash shell (nice if you need exit to bash, check smth, and get back to clickhouse-client) + docker exec -it ${containerid} bash -c 'bash --init-file <(echo "clickhouse client -m")' + + printf "\n\nYou exited the session. What next?\n" + echo " [Q]uit and remove container." + echo " [R]estart clickhouse and run clickhouse-client in shell again." + echo "You can also hit Ctrl+C to exit and keep container running." + + while : + do + read -p "Quit or restart [Q/R]?" choice + case "$choice" in + q|Q|exit ) break 2;; + r|R|restart ) echo "Restarting container ..."; docker restart ${containerid} > /dev/null; break 1;; + * ) echo "I don't understand. Please type Q or R" ;; + esac + done + done + docker rm -f ${containerid} > /dev/null + rm -rf ${tmp_dir} +fi From 20d935566fc83d82a9ad1d47b00ece69b7efd01d Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Thu, 9 Apr 2020 19:12:55 +0300 Subject: [PATCH 041/208] Enable access management in stateless tests #3. --- tests/users.d/access_management.xml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 tests/users.d/access_management.xml diff --git a/tests/users.d/access_management.xml b/tests/users.d/access_management.xml new file mode 100644 index 00000000000..7e799cb7b10 --- /dev/null +++ b/tests/users.d/access_management.xml @@ -0,0 +1,7 @@ + + + + 1 + + + From 26dd6140b21c99df5f51f81ac6fe1263ca08bcc6 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Thu, 9 Apr 2020 21:10:27 +0300 Subject: [PATCH 042/208] Added new config settings to control timeouts * "lock_acquire_timeout" controls for how long a query will continue to acquire each lock on its argument tables * "lock_acquire_timeout_for_background_operations" is a per-table setting for storages of *MergeTree family --- src/Core/Defines.h | 4 ++ src/Core/Settings.h | 1 + .../PushingToViewsBlockOutputStream.cpp | 7 +++- src/Databases/DatabaseMySQL.cpp | 4 +- src/Functions/FunctionJoinGet.cpp | 3 +- src/Interpreters/InterpreterAlterQuery.cpp | 7 +++- src/Interpreters/InterpreterCreateQuery.cpp | 3 +- src/Interpreters/InterpreterDescribeQuery.cpp | 3 +- src/Interpreters/InterpreterDropQuery.cpp | 12 +++--- src/Interpreters/InterpreterInsertQuery.cpp | 3 +- src/Interpreters/InterpreterRenameQuery.cpp | 3 +- src/Interpreters/InterpreterSelectQuery.cpp | 3 +- src/Interpreters/InterpreterSystemQuery.cpp | 2 +- src/Storages/IStorage.cpp | 33 +++++++-------- src/Storages/IStorage.h | 11 ++--- src/Storages/LiveView/StorageLiveView.cpp | 2 +- src/Storages/MergeTree/DataPartsExchange.cpp | 3 +- src/Storages/MergeTree/MergeTreeSettings.h | 1 + .../ReplicatedMergeTreeCleanupThread.cpp | 3 +- .../ReplicatedMergeTreePartCheckThread.cpp | 4 +- src/Storages/StorageBuffer.cpp | 5 ++- src/Storages/StorageDistributed.cpp | 2 +- src/Storages/StorageMaterializedView.cpp | 9 +++-- src/Storages/StorageMerge.cpp | 18 +++++---- src/Storages/StorageMerge.h | 5 ++- src/Storages/StorageMergeTree.cpp | 29 ++++++++------ src/Storages/StorageNull.cpp | 2 +- src/Storages/StorageReplicatedMergeTree.cpp | 40 ++++++++++++------- src/Storages/System/StorageSystemColumns.cpp | 15 +++---- .../System/StorageSystemPartsBase.cpp | 4 +- src/Storages/System/StorageSystemPartsBase.h | 2 + src/Storages/System/StorageSystemTables.cpp | 3 +- 32 files changed, 151 insertions(+), 95 deletions(-) diff --git a/src/Core/Defines.h b/src/Core/Defines.h index f2d4a517712..c797f527be9 100644 --- a/src/Core/Defines.h +++ b/src/Core/Defines.h @@ -91,3 +91,7 @@ # define ASAN_UNPOISON_MEMORY_REGION(a, b) # define ASAN_POISON_MEMORY_REGION(a, b) #endif + +/// Actually, there may be multiple acquisitions of different locks for a given table within one query. +/// Check with IStorage class for the list of possible locks +#define DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC 120 diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 753231603b2..ec03dfa1a4e 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -406,6 +406,7 @@ struct Settings : public SettingsCollection M(SettingBool, validate_polygons, true, "Throw exception if polygon is invalid in function pointInPolygon (e.g. self-tangent, self-intersecting). If the setting is false, the function will accept invalid polygons but may silently return wrong result.", 0) \ M(SettingUInt64, max_parser_depth, 1000, "Maximum parser depth.", 0) \ M(SettingSeconds, temporary_live_view_timeout, DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC, "Timeout after which temporary live view is deleted.", 0) \ + M(SettingSeconds, lock_acquire_timeout, DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC, "How long locking request should wait before failing", 0) \ \ /** Obsolete settings that do nothing but left for compatibility reasons. Remove each one after half a year of obsolescence. */ \ \ diff --git a/src/DataStreams/PushingToViewsBlockOutputStream.cpp b/src/DataStreams/PushingToViewsBlockOutputStream.cpp index 991d206777a..8e547767584 100644 --- a/src/DataStreams/PushingToViewsBlockOutputStream.cpp +++ b/src/DataStreams/PushingToViewsBlockOutputStream.cpp @@ -25,7 +25,8 @@ PushingToViewsBlockOutputStream::PushingToViewsBlockOutputStream( * Although now any insertion into the table is done via PushingToViewsBlockOutputStream, * but it's clear that here is not the best place for this functionality. */ - addTableLock(storage->lockStructureForShare(true, context.getInitialQueryId())); + addTableLock( + storage->lockStructureForShare(true, context.getInitialQueryId(), context.getSettingsRef().lock_acquire_timeout)); /// If the "root" table deduplactes blocks, there are no need to make deduplication for children /// Moreover, deduplication for AggregatingMergeTree children could produce false positives due to low size of inserting blocks @@ -54,7 +55,9 @@ PushingToViewsBlockOutputStream::PushingToViewsBlockOutputStream( if (auto * materialized_view = dynamic_cast(dependent_table.get())) { - addTableLock(materialized_view->lockStructureForShare(true, context.getInitialQueryId())); + addTableLock( + materialized_view->lockStructureForShare( + true, context.getInitialQueryId(), context.getSettingsRef().lock_acquire_timeout)); StoragePtr inner_table = materialized_view->getTargetTable(); auto inner_table_id = inner_table->getStorageID(); diff --git a/src/Databases/DatabaseMySQL.cpp b/src/Databases/DatabaseMySQL.cpp index 959121585ea..1cbbd4b06d9 100644 --- a/src/Databases/DatabaseMySQL.cpp +++ b/src/Databases/DatabaseMySQL.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ namespace ErrorCodes constexpr static const auto suffix = ".remove_flag"; static constexpr const std::chrono::seconds cleaner_sleep_time{30}; +static const SettingSeconds lock_acquire_timeout{10}; static String toQueryStringWithQuote(const std::vector & quote_list) { @@ -358,7 +360,7 @@ void DatabaseMySQL::cleanOutdatedTables() ++iterator; else { - const auto table_lock = (*iterator)->lockAlterIntention(RWLockImpl::NO_QUERY); + const auto table_lock = (*iterator)->lockAlterIntention(RWLockImpl::NO_QUERY, lock_acquire_timeout); (*iterator)->shutdown(); (*iterator)->is_dropped = true; diff --git a/src/Functions/FunctionJoinGet.cpp b/src/Functions/FunctionJoinGet.cpp index 0860deccb14..7940bad2cf4 100644 --- a/src/Functions/FunctionJoinGet.cpp +++ b/src/Functions/FunctionJoinGet.cpp @@ -65,7 +65,8 @@ FunctionBaseImplPtr JoinGetOverloadResolver::build(const ColumnsWithTypeAndName auto join = storage_join->getJoin(); DataTypes data_types(arguments.size()); - auto table_lock = storage_join->lockStructureForShare(false, context.getInitialQueryId()); + auto table_lock = storage_join->lockStructureForShare( + false, context.getInitialQueryId(), context.getSettingsRef().lock_acquire_timeout); for (size_t i = 0; i < arguments.size(); ++i) data_types[i] = arguments[i].type; diff --git a/src/Interpreters/InterpreterAlterQuery.cpp b/src/Interpreters/InterpreterAlterQuery.cpp index 315527765ef..7412b6b683b 100644 --- a/src/Interpreters/InterpreterAlterQuery.cpp +++ b/src/Interpreters/InterpreterAlterQuery.cpp @@ -82,7 +82,9 @@ BlockIO InterpreterAlterQuery::execute() if (!mutation_commands.empty()) { - auto table_lock_holder = table->lockStructureForShare(false /* because mutation is executed asyncronously */, context.getCurrentQueryId()); + auto table_lock_holder = table->lockStructureForShare( + false /* because mutation is executed asyncronously */, + context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); MutationsInterpreter(table, mutation_commands, context, false).validate(table_lock_holder); table->mutate(mutation_commands, context); } @@ -109,7 +111,8 @@ BlockIO InterpreterAlterQuery::execute() if (!alter_commands.empty()) { - auto table_lock_holder = table->lockAlterIntention(context.getCurrentQueryId()); + auto table_lock_holder = table->lockAlterIntention( + context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); StorageInMemoryMetadata metadata = table->getInMemoryMetadata(); alter_commands.validate(metadata, context); alter_commands.prepare(metadata); diff --git a/src/Interpreters/InterpreterCreateQuery.cpp b/src/Interpreters/InterpreterCreateQuery.cpp index f15796688e1..81b238a8973 100644 --- a/src/Interpreters/InterpreterCreateQuery.cpp +++ b/src/Interpreters/InterpreterCreateQuery.cpp @@ -403,7 +403,8 @@ InterpreterCreateQuery::TableProperties InterpreterCreateQuery::setProperties(AS StoragePtr as_storage = DatabaseCatalog::instance().getTable({as_database_name, create.as_table}); /// as_storage->getColumns() and setEngine(...) must be called under structure lock of other_table for CREATE ... AS other_table. - as_storage_lock = as_storage->lockStructureForShare(false, context.getCurrentQueryId()); + as_storage_lock = as_storage->lockStructureForShare( + false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); properties.columns = as_storage->getColumns(); /// Secondary indices make sense only for MergeTree family of storage engines. diff --git a/src/Interpreters/InterpreterDescribeQuery.cpp b/src/Interpreters/InterpreterDescribeQuery.cpp index 1353c01ebf6..f9c769a523e 100644 --- a/src/Interpreters/InterpreterDescribeQuery.cpp +++ b/src/Interpreters/InterpreterDescribeQuery.cpp @@ -89,7 +89,8 @@ BlockInputStreamPtr InterpreterDescribeQuery::executeImpl() table = DatabaseCatalog::instance().getTable(table_id); } - auto table_lock = table->lockStructureForShare(false, context.getInitialQueryId()); + auto table_lock = table->lockStructureForShare( + false, context.getInitialQueryId(), context.getSettingsRef().lock_acquire_timeout); columns = table->getColumns(); } diff --git a/src/Interpreters/InterpreterDropQuery.cpp b/src/Interpreters/InterpreterDropQuery.cpp index 42d9528abd5..70707c814ca 100644 --- a/src/Interpreters/InterpreterDropQuery.cpp +++ b/src/Interpreters/InterpreterDropQuery.cpp @@ -93,7 +93,7 @@ BlockIO InterpreterDropQuery::executeToTable( context.checkAccess(table->isView() ? AccessType::DROP_VIEW : AccessType::DROP_TABLE, table_id); table->shutdown(); /// If table was already dropped by anyone, an exception will be thrown - auto table_lock = table->lockExclusively(context.getCurrentQueryId()); + auto table_lock = table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); /// Drop table from memory, don't touch data and metadata database->detachTable(table_name); } @@ -103,7 +103,7 @@ BlockIO InterpreterDropQuery::executeToTable( table->checkTableCanBeDropped(); /// If table was already dropped by anyone, an exception will be thrown - auto table_lock = table->lockExclusively(context.getCurrentQueryId()); + auto table_lock = table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); /// Drop table data, don't touch metadata table->truncate(query_ptr, context, table_lock); } @@ -115,7 +115,7 @@ BlockIO InterpreterDropQuery::executeToTable( table->shutdown(); /// If table was already dropped by anyone, an exception will be thrown - auto table_lock = table->lockExclusively(context.getCurrentQueryId()); + auto table_lock = table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); const std::string metadata_file_without_extension = database->getMetadataPath() + escapeForFileName(table_id.table_name); const auto prev_metadata_name = metadata_file_without_extension + ".sql"; @@ -216,7 +216,8 @@ BlockIO InterpreterDropQuery::executeToTemporaryTable(const String & table_name, if (kind == ASTDropQuery::Kind::Truncate) { /// If table was already dropped by anyone, an exception will be thrown - auto table_lock = table->lockExclusively(context.getCurrentQueryId()); + auto table_lock = + table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); /// Drop table data, don't touch metadata table->truncate(query_ptr, context, table_lock); } @@ -225,7 +226,8 @@ BlockIO InterpreterDropQuery::executeToTemporaryTable(const String & table_name, context_handle.removeExternalTable(table_name); table->shutdown(); /// If table was already dropped by anyone, an exception will be thrown - auto table_lock = table->lockExclusively(context.getCurrentQueryId()); + auto table_lock = + table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); /// Delete table data table->drop(table_lock); table->is_dropped = true; diff --git a/src/Interpreters/InterpreterInsertQuery.cpp b/src/Interpreters/InterpreterInsertQuery.cpp index 39b99b10c0d..fc5d76ee216 100644 --- a/src/Interpreters/InterpreterInsertQuery.cpp +++ b/src/Interpreters/InterpreterInsertQuery.cpp @@ -109,7 +109,8 @@ BlockIO InterpreterInsertQuery::execute() BlockIO res; StoragePtr table = getTable(query); - auto table_lock = table->lockStructureForShare(true, context.getInitialQueryId()); + auto table_lock = table->lockStructureForShare( + true, context.getInitialQueryId(), context.getSettingsRef().lock_acquire_timeout); auto query_sample_block = getSampleBlock(query, table); if (!query.table_function) diff --git a/src/Interpreters/InterpreterRenameQuery.cpp b/src/Interpreters/InterpreterRenameQuery.cpp index 4f54f759510..9a4f4b1b197 100644 --- a/src/Interpreters/InterpreterRenameQuery.cpp +++ b/src/Interpreters/InterpreterRenameQuery.cpp @@ -79,7 +79,8 @@ BlockIO InterpreterRenameQuery::execute() { database_catalog.assertTableDoesntExist(StorageID(elem.to_database_name, elem.to_table_name)); auto from_table = database_catalog.getTable({elem.from_database_name, elem.from_table_name}); - auto from_table_lock = from_table->lockExclusively(context.getCurrentQueryId()); + auto from_table_lock = + from_table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); database_catalog.getDatabase(elem.from_database_name)->renameTable( context, diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index 80a7831475b..b355d5af6b1 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -255,7 +255,8 @@ InterpreterSelectQuery::InterpreterSelectQuery( if (storage) { - table_lock = storage->lockStructureForShare(false, context->getInitialQueryId()); + table_lock = storage->lockStructureForShare( + false, context->getInitialQueryId(), context->getSettingsRef().lock_acquire_timeout); table_id = storage->getStorageID(); } diff --git a/src/Interpreters/InterpreterSystemQuery.cpp b/src/Interpreters/InterpreterSystemQuery.cpp index 9a7d6ae7c5a..87d995372ef 100644 --- a/src/Interpreters/InterpreterSystemQuery.cpp +++ b/src/Interpreters/InterpreterSystemQuery.cpp @@ -326,7 +326,7 @@ StoragePtr InterpreterSystemQuery::tryRestartReplica(const StorageID & replica, table->shutdown(); { /// If table was already dropped by anyone, an exception will be thrown - auto table_lock = table->lockExclusively(context.getCurrentQueryId()); + auto table_lock = table->lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); create_ast = database->getCreateTableQuery(system_context, replica.table_name); database->detachTable(replica.table_name); diff --git a/src/Storages/IStorage.cpp b/src/Storages/IStorage.cpp index ab3a750db16..3bf8054485c 100644 --- a/src/Storages/IStorage.cpp +++ b/src/Storages/IStorage.cpp @@ -315,63 +315,64 @@ bool IStorage::isVirtualColumn(const String & column_name) const return getColumns().get(column_name).is_virtual; } -RWLockImpl::LockHolder IStorage::tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type, const String & query_id) +RWLockImpl::LockHolder IStorage::tryLockTimed( + const RWLock & rwlock, RWLockImpl::Type type, const String & query_id, const SettingSeconds & acquire_timeout) { - auto lock_holder = rwlock->getLock(type, query_id, RWLockImpl::default_locking_timeout_ms); + auto lock_holder = rwlock->getLock(type, query_id, std::chrono::milliseconds(acquire_timeout.totalMilliseconds())); if (!lock_holder) { const String type_str = type == RWLockImpl::Type::Read ? "READ" : "WRITE"; throw Exception( type_str + " locking attempt on \"" + getStorageID().getFullTableName() + - "\" has timed out! (" + toString(RWLockImpl::default_locking_timeout_ms.count()) + "ms) " + "\" has timed out! (" + toString(acquire_timeout.totalMilliseconds()) + "ms ). " "Possible deadlock avoided. Client should retry.", ErrorCodes::DEADLOCK_AVOIDED); } return lock_holder; } -TableStructureReadLockHolder IStorage::lockStructureForShare(bool will_add_new_data, const String & query_id) +TableStructureReadLockHolder IStorage::lockStructureForShare(bool will_add_new_data, const String & query_id, const SettingSeconds & acquire_timeout) { TableStructureReadLockHolder result; if (will_add_new_data) - result.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Read, query_id); - result.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Read, query_id); + result.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Read, query_id, acquire_timeout); + result.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Read, query_id, acquire_timeout); if (is_dropped) throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED); return result; } -TableStructureWriteLockHolder IStorage::lockAlterIntention(const String & query_id) +TableStructureWriteLockHolder IStorage::lockAlterIntention(const String & query_id, const SettingSeconds & acquire_timeout) { TableStructureWriteLockHolder result; - result.alter_intention_lock = tryLockTimed(alter_intention_lock, RWLockImpl::Write, query_id); + result.alter_intention_lock = tryLockTimed(alter_intention_lock, RWLockImpl::Write, query_id, acquire_timeout); if (is_dropped) throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED); return result; } -void IStorage::lockStructureExclusively(TableStructureWriteLockHolder & lock_holder, const String & query_id) +void IStorage::lockStructureExclusively(TableStructureWriteLockHolder & lock_holder, const String & query_id, const SettingSeconds & acquire_timeout) { if (!lock_holder.alter_intention_lock) throw Exception("Alter intention lock for table " + getStorageID().getNameForLogs() + " was not taken. This is a bug.", ErrorCodes::LOGICAL_ERROR); if (!lock_holder.new_data_structure_lock) - lock_holder.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Write, query_id); - lock_holder.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Write, query_id); + lock_holder.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Write, query_id, acquire_timeout); + lock_holder.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Write, query_id, acquire_timeout); } -TableStructureWriteLockHolder IStorage::lockExclusively(const String & query_id) +TableStructureWriteLockHolder IStorage::lockExclusively(const String & query_id, const SettingSeconds & acquire_timeout) { TableStructureWriteLockHolder result; - result.alter_intention_lock = tryLockTimed(alter_intention_lock, RWLockImpl::Write, query_id); + result.alter_intention_lock = tryLockTimed(alter_intention_lock, RWLockImpl::Write, query_id, acquire_timeout); if (is_dropped) throw Exception("Table is dropped", ErrorCodes::TABLE_IS_DROPPED); - result.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Write, query_id); - result.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Write, query_id); + result.new_data_structure_lock = tryLockTimed(new_data_structure_lock, RWLockImpl::Write, query_id, acquire_timeout); + result.structure_lock = tryLockTimed(structure_lock, RWLockImpl::Write, query_id, acquire_timeout); return result; } @@ -386,7 +387,7 @@ void IStorage::alter( const Context & context, TableStructureWriteLockHolder & table_lock_holder) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto table_id = getStorageID(); StorageInMemoryMetadata metadata = getInMemoryMetadata(); params.apply(metadata); diff --git a/src/Storages/IStorage.h b/src/Storages/IStorage.h index 581fc8a67e7..dd4e8506f9f 100644 --- a/src/Storages/IStorage.h +++ b/src/Storages/IStorage.h @@ -196,24 +196,25 @@ private: ConstraintsDescription constraints; private: - RWLockImpl::LockHolder tryLockTimed(const RWLock & rwlock, RWLockImpl::Type type, const String & query_id); + RWLockImpl::LockHolder tryLockTimed( + const RWLock & rwlock, RWLockImpl::Type type, const String & query_id, const SettingSeconds & acquire_timeout); public: /// Acquire this lock if you need the table structure to remain constant during the execution of /// the query. If will_add_new_data is true, this means that the query will add new data to the table /// (INSERT or a parts merge). - TableStructureReadLockHolder lockStructureForShare(bool will_add_new_data, const String & query_id); + TableStructureReadLockHolder lockStructureForShare(bool will_add_new_data, const String & query_id, const SettingSeconds & acquire_timeout); /// Acquire this lock at the start of ALTER to lock out other ALTERs and make sure that only you /// can modify the table structure. It can later be upgraded to the exclusive lock. - TableStructureWriteLockHolder lockAlterIntention(const String & query_id); + TableStructureWriteLockHolder lockAlterIntention(const String & query_id, const SettingSeconds & acquire_timeout); /// Upgrade alter intention lock to the full exclusive structure lock. This is done by ALTER queries /// to ensure that no other query uses the table structure and it can be safely changed. - void lockStructureExclusively(TableStructureWriteLockHolder & lock_holder, const String & query_id); + void lockStructureExclusively(TableStructureWriteLockHolder & lock_holder, const String & query_id, const SettingSeconds & acquire_timeout); /// Acquire the full exclusive lock immediately. No other queries can run concurrently. - TableStructureWriteLockHolder lockExclusively(const String & query_id); + TableStructureWriteLockHolder lockExclusively(const String & query_id, const SettingSeconds & acquire_timeout); /** Returns stage to which query is going to be processed in read() function. * (Normally, the function only reads the columns from the list, but in other cases, diff --git a/src/Storages/LiveView/StorageLiveView.cpp b/src/Storages/LiveView/StorageLiveView.cpp index 049110a3294..569e5c24e1c 100644 --- a/src/Storages/LiveView/StorageLiveView.cpp +++ b/src/Storages/LiveView/StorageLiveView.cpp @@ -519,7 +519,7 @@ void StorageLiveView::drop(TableStructureWriteLockHolder &) void StorageLiveView::refresh(const Context & context) { - auto alter_lock = lockAlterIntention(context.getCurrentQueryId()); + auto alter_lock = lockAlterIntention(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); { std::lock_guard lock(mutex); if (getNewBlocks()) diff --git a/src/Storages/MergeTree/DataPartsExchange.cpp b/src/Storages/MergeTree/DataPartsExchange.cpp index 6373c85a15d..c656fbf0c58 100644 --- a/src/Storages/MergeTree/DataPartsExchange.cpp +++ b/src/Storages/MergeTree/DataPartsExchange.cpp @@ -85,7 +85,8 @@ void Service::processQuery(const Poco::Net::HTMLForm & params, ReadBuffer & /*bo try { - auto storage_lock = data.lockStructureForShare(false, RWLockImpl::NO_QUERY); + auto storage_lock = data.lockStructureForShare( + false, RWLockImpl::NO_QUERY, data.getSettings()->lock_acquire_timeout_for_background_operations); MergeTreeData::DataPartPtr part = findPart(part_name); diff --git a/src/Storages/MergeTree/MergeTreeSettings.h b/src/Storages/MergeTree/MergeTreeSettings.h index bbd1fd6cbeb..02c852b4f4b 100644 --- a/src/Storages/MergeTree/MergeTreeSettings.h +++ b/src/Storages/MergeTree/MergeTreeSettings.h @@ -42,6 +42,7 @@ struct MergeTreeSettings : public SettingsCollection M(SettingUInt64, number_of_free_entries_in_pool_to_execute_mutation, 10, "When there is less than specified number of free entries in pool, do not execute part mutations. This is to leave free threads for regular merges and avoid \"Too many parts\"", 0) \ M(SettingSeconds, old_parts_lifetime, 8 * 60, "How many seconds to keep obsolete parts.", 0) \ M(SettingSeconds, temporary_directories_lifetime, 86400, "How many seconds to keep tmp_-directories.", 0) \ + M(SettingSeconds, lock_acquire_timeout_for_background_operations, DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC, "For background operations like merges, mutations etc. How many seconds before failing to acquire table locks.", 0) \ \ /** Inserts settings. */ \ M(SettingUInt64, parts_to_delay_insert, 150, "If table contains at least that many active parts in single partition, artificially slow down insert into table.", 0) \ diff --git a/src/Storages/MergeTree/ReplicatedMergeTreeCleanupThread.cpp b/src/Storages/MergeTree/ReplicatedMergeTreeCleanupThread.cpp index 77a5bca7a92..b1164f6621c 100644 --- a/src/Storages/MergeTree/ReplicatedMergeTreeCleanupThread.cpp +++ b/src/Storages/MergeTree/ReplicatedMergeTreeCleanupThread.cpp @@ -57,7 +57,8 @@ void ReplicatedMergeTreeCleanupThread::iterate() { /// TODO: Implement tryLockStructureForShare. - auto lock = storage.lockStructureForShare(false, ""); + auto lock = storage.lockStructureForShare( + false, RWLockImpl::NO_QUERY, storage.getSettings()->lock_acquire_timeout_for_background_operations); storage.clearOldTemporaryDirectories(); } diff --git a/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.cpp b/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.cpp index 17b716d14c2..b587b5f71c0 100644 --- a/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.cpp +++ b/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.cpp @@ -203,7 +203,9 @@ CheckResult ReplicatedMergeTreePartCheckThread::checkPart(const String & part_na else if (part->name == part_name) { auto zookeeper = storage.getZooKeeper(); - auto table_lock = storage.lockStructureForShare(false, RWLockImpl::NO_QUERY); + + auto table_lock = storage.lockStructureForShare( + false, RWLockImpl::NO_QUERY, storage.getSettings()->lock_acquire_timeout_for_background_operations); auto local_part_header = ReplicatedMergeTreePartHeader::fromColumnsAndChecksums( part->getColumns(), part->checksums); diff --git a/src/Storages/StorageBuffer.cpp b/src/Storages/StorageBuffer.cpp index 7699f8379d9..2702b344dc3 100644 --- a/src/Storages/StorageBuffer.cpp +++ b/src/Storages/StorageBuffer.cpp @@ -168,7 +168,8 @@ Pipes StorageBuffer::read( if (destination.get() == this) throw Exception("Destination table is myself. Read will cause infinite loop.", ErrorCodes::INFINITE_LOOP); - auto destination_lock = destination->lockStructureForShare(false, context.getCurrentQueryId()); + auto destination_lock = destination->lockStructureForShare( + false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); const bool dst_has_same_structure = std::all_of(column_names.begin(), column_names.end(), [this, destination](const String& column_name) { @@ -757,7 +758,7 @@ std::optional StorageBuffer::totalBytes() const void StorageBuffer::alter(const AlterCommands & params, const Context & context, TableStructureWriteLockHolder & table_lock_holder) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto table_id = getStorageID(); checkAlterIsPossible(params, context.getSettingsRef()); diff --git a/src/Storages/StorageDistributed.cpp b/src/Storages/StorageDistributed.cpp index b4375dd5b0a..7e6b9d14e02 100644 --- a/src/Storages/StorageDistributed.cpp +++ b/src/Storages/StorageDistributed.cpp @@ -460,7 +460,7 @@ void StorageDistributed::checkAlterIsPossible(const AlterCommands & commands, co void StorageDistributed::alter(const AlterCommands & params, const Context & context, TableStructureWriteLockHolder & table_lock_holder) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto table_id = getStorageID(); checkAlterIsPossible(params, context.getSettingsRef()); diff --git a/src/Storages/StorageMaterializedView.cpp b/src/Storages/StorageMaterializedView.cpp index 3fb25bf8275..056e2cbb42f 100644 --- a/src/Storages/StorageMaterializedView.cpp +++ b/src/Storages/StorageMaterializedView.cpp @@ -185,7 +185,9 @@ Pipes StorageMaterializedView::read( const unsigned num_streams) { auto storage = getTargetTable(); - auto lock = storage->lockStructureForShare(false, context.getCurrentQueryId()); + auto lock = storage->lockStructureForShare( + false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); + if (query_info.order_by_optimizer) query_info.input_sorting_info = query_info.order_by_optimizer->getInputOrder(storage); @@ -200,7 +202,8 @@ Pipes StorageMaterializedView::read( BlockOutputStreamPtr StorageMaterializedView::write(const ASTPtr & query, const Context & context) { auto storage = getTargetTable(); - auto lock = storage->lockStructureForShare(true, context.getCurrentQueryId()); + auto lock = storage->lockStructureForShare( + true, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto stream = storage->write(query, context); stream->addTableLock(lock); return stream; @@ -258,7 +261,7 @@ void StorageMaterializedView::alter( const Context & context, TableStructureWriteLockHolder & table_lock_holder) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto table_id = getStorageID(); StorageInMemoryMetadata metadata = getInMemoryMetadata(); params.apply(metadata); diff --git a/src/Storages/StorageMerge.cpp b/src/Storages/StorageMerge.cpp index f3322c7dfff..a108e615bee 100644 --- a/src/Storages/StorageMerge.cpp +++ b/src/Storages/StorageMerge.cpp @@ -118,7 +118,8 @@ bool StorageMerge::isRemote() const bool StorageMerge::mayBenefitFromIndexForIn(const ASTPtr & left_in_operand, const Context & query_context) const { /// It's beneficial if it is true for at least one table. - StorageListWithLocks selected_tables = getSelectedTables(query_context.getCurrentQueryId()); + StorageListWithLocks selected_tables = getSelectedTables( + query_context.getCurrentQueryId(), query_context.getSettingsRef()); size_t i = 0; for (const auto & table : selected_tables) @@ -195,7 +196,7 @@ Pipes StorageMerge::read( * This is necessary to correctly pass the recommended number of threads to each table. */ StorageListWithLocks selected_tables = getSelectedTables( - query_info.query, has_table_virtual_column, context.getCurrentQueryId()); + query_info.query, has_table_virtual_column, context.getCurrentQueryId(), context.getSettingsRef()); if (selected_tables.empty()) /// FIXME: do we support sampling in this case? @@ -355,7 +356,7 @@ Pipes StorageMerge::createSources(const SelectQueryInfo & query_info, const Quer } -StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables(const String & query_id) const +StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables(const String & query_id, const Settings & settings) const { StorageListWithLocks selected_tables; auto iterator = getDatabaseIterator(); @@ -364,7 +365,8 @@ StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables(const String { auto & table = iterator->table(); if (table.get() != this) - selected_tables.emplace_back(table, table->lockStructureForShare(false, query_id), iterator->name()); + selected_tables.emplace_back( + table, table->lockStructureForShare(false, query_id, settings.lock_acquire_timeout), iterator->name()); iterator->next(); } @@ -373,7 +375,8 @@ StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables(const String } -StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables(const ASTPtr & query, bool has_virtual_column, const String & query_id) const +StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables( + const ASTPtr & query, bool has_virtual_column, const String & query_id, const Settings & settings) const { StorageListWithLocks selected_tables; DatabaseTablesIteratorPtr iterator = getDatabaseIterator(); @@ -389,7 +392,8 @@ StorageMerge::StorageListWithLocks StorageMerge::getSelectedTables(const ASTPtr if (storage.get() != this) { - selected_tables.emplace_back(storage, storage->lockStructureForShare(false, query_id), iterator->name()); + selected_tables.emplace_back( + storage, storage->lockStructureForShare(false, query_id, settings.lock_acquire_timeout), iterator->name()); virtual_column->insert(iterator->name()); } @@ -434,7 +438,7 @@ void StorageMerge::checkAlterIsPossible(const AlterCommands & commands, const Se void StorageMerge::alter( const AlterCommands & params, const Context & context, TableStructureWriteLockHolder & table_lock_holder) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto table_id = getStorageID(); StorageInMemoryMetadata storage_metadata = getInMemoryMetadata(); diff --git a/src/Storages/StorageMerge.h b/src/Storages/StorageMerge.h index 1d2df3cb9ce..bb3205184b1 100644 --- a/src/Storages/StorageMerge.h +++ b/src/Storages/StorageMerge.h @@ -57,9 +57,10 @@ private: using StorageWithLockAndName = std::tuple; using StorageListWithLocks = std::list; - StorageListWithLocks getSelectedTables(const String & query_id) const; + StorageListWithLocks getSelectedTables(const String & query_id, const Settings & settings) const; - StorageMerge::StorageListWithLocks getSelectedTables(const ASTPtr & query, bool has_virtual_column, const String & query_id) const; + StorageMerge::StorageListWithLocks getSelectedTables( + const ASTPtr & query, bool has_virtual_column, const String & query_id, const Settings & settings) const; template StoragePtr getFirstTable(F && predicate) const; diff --git a/src/Storages/StorageMergeTree.cpp b/src/Storages/StorageMergeTree.cpp index 2efeff19657..5bf16f49fbe 100644 --- a/src/Storages/StorageMergeTree.cpp +++ b/src/Storages/StorageMergeTree.cpp @@ -223,7 +223,7 @@ void StorageMergeTree::alter( /// This alter can be performed at metadata level only if (commands.isSettingsAlter()) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); changeSettings(metadata.settings_ast, table_lock_holder); @@ -231,7 +231,7 @@ void StorageMergeTree::alter( } else { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); changeSettings(metadata.settings_ast, table_lock_holder); /// Reinitialize primary key because primary key column types might have changed. @@ -537,7 +537,8 @@ bool StorageMergeTree::merge( bool deduplicate, String * out_disable_reason) { - auto table_lock_holder = lockStructureForShare(true, RWLockImpl::NO_QUERY); + auto table_lock_holder = lockStructureForShare( + true, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); FutureMergedMutatedPart future_part; @@ -655,7 +656,8 @@ BackgroundProcessingPoolTaskResult StorageMergeTree::movePartsTask() bool StorageMergeTree::tryMutatePart() { - auto table_lock_holder = lockStructureForShare(true, RWLockImpl::NO_QUERY); + auto table_lock_holder = lockStructureForShare( + true, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); size_t max_ast_elements = global_context.getSettingsRef().max_expanded_ast_elements; FutureMergedMutatedPart future_part; @@ -780,7 +782,8 @@ BackgroundProcessingPoolTaskResult StorageMergeTree::mergeMutateTask() { { /// TODO: Implement tryLockStructureForShare. - auto lock_structure = lockStructureForShare(false, ""); + auto lock_structure = lockStructureForShare( + false, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); clearOldPartsFromFilesystem(); clearOldTemporaryDirectories(); } @@ -973,14 +976,16 @@ void StorageMergeTree::alterPartition(const ASTPtr & query, const PartitionComma case PartitionCommand::FREEZE_PARTITION: { - auto lock = lockStructureForShare(false, context.getCurrentQueryId()); + auto lock = lockStructureForShare( + false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); freezePartition(command.partition, command.with_name, context, lock); } break; case PartitionCommand::FREEZE_ALL_PARTITIONS: { - auto lock = lockStructureForShare(false, context.getCurrentQueryId()); + auto lock = lockStructureForShare( + false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); freezeAll(command.with_name, context, lock); } break; @@ -998,7 +1003,7 @@ void StorageMergeTree::dropPartition(const ASTPtr & partition, bool detach, cons /// This protects against "revival" of data for a removed partition after completion of merge. auto merge_blocker = merger_mutator.merges_blocker.cancel(); /// Waits for completion of merge and does not start new ones. - auto lock = lockExclusively(context.getCurrentQueryId()); + auto lock = lockExclusively(context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); String partition_id = getPartitionIDFromQuery(partition, context); @@ -1045,8 +1050,8 @@ void StorageMergeTree::attachPartition(const ASTPtr & partition, bool attach_par void StorageMergeTree::replacePartitionFrom(const StoragePtr & source_table, const ASTPtr & partition, bool replace, const Context & context) { - auto lock1 = lockStructureForShare(false, context.getCurrentQueryId()); - auto lock2 = source_table->lockStructureForShare(false, context.getCurrentQueryId()); + auto lock1 = lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); + auto lock2 = source_table->lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); Stopwatch watch; MergeTreeData & src_data = checkStructureAndGetMergeTreeData(source_table); @@ -1116,8 +1121,8 @@ void StorageMergeTree::replacePartitionFrom(const StoragePtr & source_table, con void StorageMergeTree::movePartitionToTable(const StoragePtr & dest_table, const ASTPtr & partition, const Context & context) { - auto lock1 = lockStructureForShare(false, context.getCurrentQueryId()); - auto lock2 = dest_table->lockStructureForShare(false, context.getCurrentQueryId()); + auto lock1 = lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); + auto lock2 = dest_table->lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto dest_table_storage = std::dynamic_pointer_cast(dest_table); if (!dest_table_storage) diff --git a/src/Storages/StorageNull.cpp b/src/Storages/StorageNull.cpp index 878be5bbf2d..bafb3d9a9fb 100644 --- a/src/Storages/StorageNull.cpp +++ b/src/Storages/StorageNull.cpp @@ -48,7 +48,7 @@ void StorageNull::checkAlterIsPossible(const AlterCommands & commands, const Set void StorageNull::alter( const AlterCommands & params, const Context & context, TableStructureWriteLockHolder & table_lock_holder) { - lockStructureExclusively(table_lock_holder, context.getCurrentQueryId()); + lockStructureExclusively(table_lock_holder, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto table_id = getStorageID(); StorageInMemoryMetadata metadata = getInMemoryMetadata(); diff --git a/src/Storages/StorageReplicatedMergeTree.cpp b/src/Storages/StorageReplicatedMergeTree.cpp index 8896151561b..ab5898458c5 100644 --- a/src/Storages/StorageReplicatedMergeTree.cpp +++ b/src/Storages/StorageReplicatedMergeTree.cpp @@ -1025,7 +1025,8 @@ bool StorageReplicatedMergeTree::tryExecuteMerge(const LogEntry & entry) ReservationPtr reserved_space = reserveSpacePreferringTTLRules(estimated_space_for_merge, ttl_infos, time(nullptr), max_volume_index); - auto table_lock = lockStructureForShare(false, RWLockImpl::NO_QUERY); + auto table_lock = lockStructureForShare( + false, RWLockImpl::NO_QUERY, storage_settings_ptr->lock_acquire_timeout_for_background_operations); FutureMergedMutatedPart future_merged_part(parts, entry.new_part_type); if (future_merged_part.name != entry.new_part_name) @@ -1160,7 +1161,8 @@ bool StorageReplicatedMergeTree::tryExecutePartMutation(const StorageReplicatedM /// Can throw an exception. ReservationPtr reserved_space = reserveSpace(estimated_space_for_result, source_part->disk); - auto table_lock = lockStructureForShare(false, RWLockImpl::NO_QUERY); + auto table_lock = lockStructureForShare( + false, RWLockImpl::NO_QUERY, storage_settings_ptr->lock_acquire_timeout_for_background_operations); MutableDataPartPtr new_part; Transaction transaction(*this); @@ -1514,7 +1516,8 @@ bool StorageReplicatedMergeTree::executeReplaceRange(const LogEntry & entry) PartDescriptions parts_to_add; DataPartsVector parts_to_remove; - auto table_lock_holder_dst_table = lockStructureForShare(false, RWLockImpl::NO_QUERY); + auto table_lock_holder_dst_table = lockStructureForShare( + false, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); for (size_t i = 0; i < entry_replace.new_part_names.size(); ++i) { @@ -1576,7 +1579,8 @@ bool StorageReplicatedMergeTree::executeReplaceRange(const LogEntry & entry) return 0; } - table_lock_holder_src_table = source_table->lockStructureForShare(false, RWLockImpl::NO_QUERY); + table_lock_holder_src_table = source_table->lockStructureForShare( + false, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); DataPartStates valid_states{MergeTreeDataPartState::PreCommitted, MergeTreeDataPartState::Committed, MergeTreeDataPartState::Outdated}; @@ -2699,7 +2703,8 @@ bool StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin TableStructureReadLockHolder table_lock_holder; if (!to_detached) - table_lock_holder = lockStructureForShare(true, RWLockImpl::NO_QUERY); + table_lock_holder = lockStructureForShare( + true, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); /// Logging Stopwatch stopwatch; @@ -3166,7 +3171,7 @@ bool StorageReplicatedMergeTree::executeMetadataAlter(const StorageReplicatedMer { /// TODO (relax this lock) - auto table_lock = lockExclusively(RWLockImpl::NO_QUERY); + auto table_lock = lockExclusively(RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); LOG_INFO(log, "Metadata changed in ZooKeeper. Applying changes locally."); @@ -3193,7 +3198,8 @@ void StorageReplicatedMergeTree::alter( if (params.isSettingsAlter()) { - lockStructureExclusively(table_lock_holder, query_context.getCurrentQueryId()); + lockStructureExclusively( + table_lock_holder, query_context.getCurrentQueryId(), query_context.getSettingsRef().lock_acquire_timeout); /// We don't replicate storage_settings_ptr ALTER. It's local operation. /// Also we don't upgrade alter lock to table structure lock. StorageInMemoryMetadata metadata = getInMemoryMetadata(); @@ -3259,7 +3265,8 @@ void StorageReplicatedMergeTree::alter( if (ast_to_str(current_metadata.settings_ast) != ast_to_str(future_metadata.settings_ast)) { - lockStructureExclusively(table_lock_holder, query_context.getCurrentQueryId()); + lockStructureExclusively( + table_lock_holder, query_context.getCurrentQueryId(), query_context.getSettingsRef().lock_acquire_timeout); /// Just change settings current_metadata.settings_ast = future_metadata.settings_ast; changeSettings(current_metadata.settings_ast, table_lock_holder); @@ -3428,14 +3435,16 @@ void StorageReplicatedMergeTree::alterPartition(const ASTPtr & query, const Part case PartitionCommand::FREEZE_PARTITION: { - auto lock = lockStructureForShare(false, query_context.getCurrentQueryId()); + auto lock = lockStructureForShare( + false, query_context.getCurrentQueryId(), query_context.getSettingsRef().lock_acquire_timeout); freezePartition(command.partition, command.with_name, query_context, lock); } break; case PartitionCommand::FREEZE_ALL_PARTITIONS: { - auto lock = lockStructureForShare(false, query_context.getCurrentQueryId()); + auto lock = lockStructureForShare( + false, query_context.getCurrentQueryId(), query_context.getSettingsRef().lock_acquire_timeout); freezeAll(command.with_name, query_context, lock); } break; @@ -4443,7 +4452,8 @@ void StorageReplicatedMergeTree::clearOldPartsAndRemoveFromZK() { /// Critical section is not required (since grabOldParts() returns unique part set on each call) - auto table_lock = lockStructureForShare(false, RWLockImpl::NO_QUERY); + auto table_lock = lockStructureForShare( + false, RWLockImpl::NO_QUERY, getSettings()->lock_acquire_timeout_for_background_operations); auto zookeeper = getZooKeeper(); DataPartsVector parts = grabOldParts(); @@ -4738,8 +4748,8 @@ void StorageReplicatedMergeTree::replacePartitionFrom(const StoragePtr & source_ const Context & context) { /// First argument is true, because we possibly will add new data to current table. - auto lock1 = lockStructureForShare(true, context.getCurrentQueryId()); - auto lock2 = source_table->lockStructureForShare(false, context.getCurrentQueryId()); + auto lock1 = lockStructureForShare(true, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); + auto lock2 = source_table->lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); Stopwatch watch; MergeTreeData & src_data = checkStructureAndGetMergeTreeData(source_table); @@ -4917,8 +4927,8 @@ void StorageReplicatedMergeTree::replacePartitionFrom(const StoragePtr & source_ void StorageReplicatedMergeTree::movePartitionToTable(const StoragePtr & dest_table, const ASTPtr & partition, const Context & context) { - auto lock1 = lockStructureForShare(false, context.getCurrentQueryId()); - auto lock2 = dest_table->lockStructureForShare(false, context.getCurrentQueryId()); + auto lock1 = lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); + auto lock2 = dest_table->lockStructureForShare(false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); auto dest_table_storage = std::dynamic_pointer_cast(dest_table); if (!dest_table_storage) diff --git a/src/Storages/System/StorageSystemColumns.cpp b/src/Storages/System/StorageSystemColumns.cpp index cbf6ada9ed3..26e2376c3f7 100644 --- a/src/Storages/System/StorageSystemColumns.cpp +++ b/src/Storages/System/StorageSystemColumns.cpp @@ -62,12 +62,12 @@ public: ColumnPtr databases_, ColumnPtr tables_, Storages storages_, - const std::shared_ptr & access_, - String query_id_) + const Context & context) : SourceWithProgress(header_) , columns_mask(std::move(columns_mask_)), max_block_size(max_block_size_) , databases(std::move(databases_)), tables(std::move(tables_)), storages(std::move(storages_)) - , query_id(std::move(query_id_)), total_tables(tables->size()), access(access_) + , total_tables(tables->size()), access(context.getAccess()) + , query_id(context.getCurrentQueryId()), lock_acquire_timeout(context.getSettingsRef().lock_acquire_timeout) { } @@ -103,7 +103,7 @@ protected: try { - table_lock = storage->lockStructureForShare(false, query_id); + table_lock = storage->lockStructureForShare(false, query_id, lock_acquire_timeout); } catch (const Exception & e) { @@ -227,10 +227,11 @@ private: ColumnPtr databases; ColumnPtr tables; Storages storages; - String query_id; size_t db_table_num = 0; size_t total_tables; std::shared_ptr access; + String query_id; + SettingSeconds lock_acquire_timeout; }; @@ -331,8 +332,8 @@ Pipes StorageSystemColumns::read( pipes.emplace_back(std::make_shared( std::move(columns_mask), std::move(header), max_block_size, - std::move(filtered_database_column), std::move(filtered_table_column), std::move(storages), - context.getAccess(), context.getCurrentQueryId())); + std::move(filtered_database_column), std::move(filtered_table_column), + std::move(storages), context)); return pipes; } diff --git a/src/Storages/System/StorageSystemPartsBase.cpp b/src/Storages/System/StorageSystemPartsBase.cpp index d8f564b0160..19c6f6b3d03 100644 --- a/src/Storages/System/StorageSystemPartsBase.cpp +++ b/src/Storages/System/StorageSystemPartsBase.cpp @@ -62,7 +62,7 @@ StoragesInfo::getParts(MergeTreeData::DataPartStateVector & state, bool has_stat } StoragesInfoStream::StoragesInfoStream(const SelectQueryInfo & query_info, const Context & context) - : query_id(context.getCurrentQueryId()) + : query_id(context.getCurrentQueryId()), settings(context.getSettings()) { /// Will apply WHERE to subset of columns and then add more columns. /// This is kind of complicated, but we use WHERE to do less work. @@ -192,7 +192,7 @@ StoragesInfo StoragesInfoStream::next() try { /// For table not to be dropped and set of columns to remain constant. - info.table_lock = info.storage->lockStructureForShare(false, query_id); + info.table_lock = info.storage->lockStructureForShare(false, query_id, settings.lock_acquire_timeout); } catch (const Exception & e) { diff --git a/src/Storages/System/StorageSystemPartsBase.h b/src/Storages/System/StorageSystemPartsBase.h index b30f7c62914..be8e45146cb 100644 --- a/src/Storages/System/StorageSystemPartsBase.h +++ b/src/Storages/System/StorageSystemPartsBase.h @@ -36,6 +36,8 @@ public: private: String query_id; + Settings settings; + ColumnPtr database_column; ColumnPtr table_column; diff --git a/src/Storages/System/StorageSystemTables.cpp b/src/Storages/System/StorageSystemTables.cpp index a8d5fc2ec57..f4ce4a8b717 100644 --- a/src/Storages/System/StorageSystemTables.cpp +++ b/src/Storages/System/StorageSystemTables.cpp @@ -244,7 +244,8 @@ protected: if (need_lock_structure) { table = tables_it->table(); - lock = table->lockStructureForShare(false, context.getCurrentQueryId()); + lock = table->lockStructureForShare( + false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); } } catch (const Exception & e) From 0accd2908c347038db03f26911a8d2de5ae72ea5 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Thu, 9 Apr 2020 23:11:20 +0300 Subject: [PATCH 043/208] Fix up styler's grudge --- src/Storages/IStorage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/IStorage.cpp b/src/Storages/IStorage.cpp index 3bf8054485c..5a792080370 100644 --- a/src/Storages/IStorage.cpp +++ b/src/Storages/IStorage.cpp @@ -324,7 +324,7 @@ RWLockImpl::LockHolder IStorage::tryLockTimed( const String type_str = type == RWLockImpl::Type::Read ? "READ" : "WRITE"; throw Exception( type_str + " locking attempt on \"" + getStorageID().getFullTableName() + - "\" has timed out! (" + toString(acquire_timeout.totalMilliseconds()) + "ms ). " + "\" has timed out! (" + toString(acquire_timeout.totalMilliseconds()) + "ms) " "Possible deadlock avoided. Client should retry.", ErrorCodes::DEADLOCK_AVOIDED); } From c39e3a51adf41e429560e5e06118d7faffea2431 Mon Sep 17 00:00:00 2001 From: "philip.han" Date: Fri, 10 Apr 2020 12:30:54 +0900 Subject: [PATCH 044/208] Fix Set::insertFromBlockImplCase() --- src/Interpreters/Set.cpp | 7 +++++-- .../queries/0_stateless/01231_operator_null_in.sql | 14 +++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Interpreters/Set.cpp b/src/Interpreters/Set.cpp index 0504f9d9e6d..54992eeff2c 100644 --- a/src/Interpreters/Set.cpp +++ b/src/Interpreters/Set.cpp @@ -87,7 +87,10 @@ void NO_INLINE Set::insertFromBlockImplCase( { if ((*null_map)[i]) { - has_null = true; + if (transform_null_in) + { + has_null = true; + } if constexpr (build_filter) { @@ -180,7 +183,7 @@ bool Set::insertFromBlock(const Block & block) /// We will insert to the Set only keys, where all components are not NULL. ConstNullMapPtr null_map{}; - ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map); + ColumnPtr null_map_holder = extractNestedColumnsAndNullMap(key_columns, null_map, transform_null_in); /// Filter to extract distinct values from the block. ColumnUInt8::MutablePtr filter; diff --git a/tests/queries/0_stateless/01231_operator_null_in.sql b/tests/queries/0_stateless/01231_operator_null_in.sql index 12361373001..3c4333c8ea6 100644 --- a/tests/queries/0_stateless/01231_operator_null_in.sql +++ b/tests/queries/0_stateless/01231_operator_null_in.sql @@ -90,4 +90,16 @@ SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3')] FRO SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1'), (NULL, NULL)] FROM null_in_tuple WHERE t global in ((1, '1'), (NULL, NULL)); SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3')] FROM null_in_tuple WHERE t global not in ((1, '1'), (NULL, NULL)); -DROP TABLE IF EXISTS null_in_subquery; +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1')] FROM null_in_tuple WHERE t in ((1, '1'), (1, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1')] FROM null_in_tuple WHERE t in ((1, '1'), (NULL, '1')); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1'), (2, NULL)] FROM null_in_tuple WHERE t in ((1, '1'), (NULL, '1'), (2, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1'), (NULL, '3')] FROM null_in_tuple WHERE t in ((1, '1'), (1, NULL), (NULL, '3')); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(1, '1'), (2, NULL), (NULL, '3'), (NULL, NULL)] FROM null_in_tuple WHERE t in ((1, '1'), (1, NULL), (2, NULL), (NULL, '3'), (NULL, NULL)); + +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3'), (NULL, NULL)] FROM null_in_tuple WHERE t not in ((1, '1'), (1, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, '3'), (NULL, NULL)] FROM null_in_tuple WHERE t not in ((1, '1'), (NULL, '1')); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(NULL, '3'), (NULL, NULL)] FROM null_in_tuple WHERE t not in ((1, '1'), (NULL, '1'), (2, NULL)); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [(2, NULL), (NULL, NULL)] FROM null_in_tuple WHERE t not in ((1, '1'), (1, NULL), (NULL, '3')); +SELECT arraySort(x -> (x.1, x.2), groupArray(t)) == [] FROM null_in_tuple WHERE t not in ((1, '1'), (1, NULL), (2, NULL), (NULL, '3'), (NULL, NULL)); + +DROP TABLE IF EXISTS null_in_tuple; From c6bf39d7a9a8606fa00caff764cb16133a3620f0 Mon Sep 17 00:00:00 2001 From: "philip.han" Date: Fri, 10 Apr 2020 14:02:55 +0900 Subject: [PATCH 045/208] Fix 01231_operator_null_in.reference --- .../0_stateless/01231_operator_null_in.reference | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/queries/0_stateless/01231_operator_null_in.reference b/tests/queries/0_stateless/01231_operator_null_in.reference index 7432b657191..5cd5e5ee5fb 100644 --- a/tests/queries/0_stateless/01231_operator_null_in.reference +++ b/tests/queries/0_stateless/01231_operator_null_in.reference @@ -52,3 +52,13 @@ 1 1 1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 From 7fa5afecb44484e04f710ee7876ee590fbf2d1cd Mon Sep 17 00:00:00 2001 From: "philip.han" Date: Fri, 10 Apr 2020 14:42:36 +0900 Subject: [PATCH 046/208] Support transform_null_in option for StorageSet --- src/Interpreters/Set.cpp | 7 +--- src/Storages/StorageSet.cpp | 6 +-- .../01231_operator_null_in.reference | 16 ++++++++ .../0_stateless/01231_operator_null_in.sql | 38 +++++++++++++++++++ 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/Interpreters/Set.cpp b/src/Interpreters/Set.cpp index 54992eeff2c..a4fea5dd705 100644 --- a/src/Interpreters/Set.cpp +++ b/src/Interpreters/Set.cpp @@ -87,10 +87,7 @@ void NO_INLINE Set::insertFromBlockImplCase( { if ((*null_map)[i]) { - if (transform_null_in) - { - has_null = true; - } + has_null = true; if constexpr (build_filter) { @@ -397,7 +394,7 @@ void NO_INLINE Set::executeImplCase( { if (has_null_map && (*null_map)[i]) { - if (has_null) + if (transform_null_in && has_null) vec_res[i] = !negative; else vec_res[i] = negative; diff --git a/src/Storages/StorageSet.cpp b/src/Storages/StorageSet.cpp index 7d2a7ee128f..79f5198b304 100644 --- a/src/Storages/StorageSet.cpp +++ b/src/Storages/StorageSet.cpp @@ -112,7 +112,7 @@ StorageSet::StorageSet( const ConstraintsDescription & constraints_, const Context & context_) : StorageSetOrJoinBase{relative_path_, table_id_, columns_, constraints_, context_}, - set(std::make_shared(SizeLimits(), false, context_.getSettingsRef().transform_null_in)) + set(std::make_shared(SizeLimits(), false, true)) { Block header = getSampleBlock(); header = header.sortColumns(); @@ -127,7 +127,7 @@ void StorageSet::finishInsert() { set->finishInsert(); } size_t StorageSet::getSize() const { return set->getTotalRowCount(); } -void StorageSet::truncate(const ASTPtr &, const Context & context, TableStructureWriteLockHolder &) +void StorageSet::truncate(const ASTPtr &, const Context &, TableStructureWriteLockHolder &) { Poco::File(path).remove(true); Poco::File(path).createDirectories(); @@ -137,7 +137,7 @@ void StorageSet::truncate(const ASTPtr &, const Context & context, TableStructur header = header.sortColumns(); increment = 0; - set = std::make_shared(SizeLimits(), false, context.getSettingsRef().transform_null_in); + set = std::make_shared(SizeLimits(), false, true); set->setHeader(header); } diff --git a/tests/queries/0_stateless/01231_operator_null_in.reference b/tests/queries/0_stateless/01231_operator_null_in.reference index 5cd5e5ee5fb..b76f42e9af4 100644 --- a/tests/queries/0_stateless/01231_operator_null_in.reference +++ b/tests/queries/0_stateless/01231_operator_null_in.reference @@ -62,3 +62,19 @@ 1 1 1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 diff --git a/tests/queries/0_stateless/01231_operator_null_in.sql b/tests/queries/0_stateless/01231_operator_null_in.sql index 3c4333c8ea6..ddebaf23900 100644 --- a/tests/queries/0_stateless/01231_operator_null_in.sql +++ b/tests/queries/0_stateless/01231_operator_null_in.sql @@ -40,8 +40,46 @@ SELECT count() == 3 FROM null_in WHERE i global not in (1, 3); SELECT count() == 3 FROM null_in WHERE i global not in range(4); SELECT count() == 3 FROM null_in WHERE s global not in ('1', '3'); +DROP TABLE IF EXISTS test_set; +CREATE TABLE test_set (i Nullable(int)) ENGINE = Set(); +INSERT INTO test_set VALUES (1), (NULL); + +SET transform_null_in = 0; + +SELECT count() == 1 FROM null_in WHERE i in test_set; +SELECT count() == 2 FROM null_in WHERE i not in test_set; +SELECT count() == 1 FROM null_in WHERE i global in test_set; +SELECT count() == 2 FROM null_in WHERE i global not in test_set; + +SET transform_null_in = 1; + +SELECT count() == 3 FROM null_in WHERE i in test_set; +SELECT count() == 2 FROM null_in WHERE i not in test_set; +SELECT count() == 3 FROM null_in WHERE i global in test_set; +SELECT count() == 2 FROM null_in WHERE i global not in test_set; + +-- Create with transform_null_in +CREATE TABLE test_set2 (i Nullable(int)) ENGINE = Set(); +INSERT INTO test_set2 VALUES (1), (NULL); + +SET transform_null_in = 0; + +SELECT count() == 1 FROM null_in WHERE i in test_set2; +SELECT count() == 2 FROM null_in WHERE i not in test_set2; +SELECT count() == 1 FROM null_in WHERE i global in test_set2; +SELECT count() == 2 FROM null_in WHERE i global not in test_set2; + +SET transform_null_in = 1; + +SELECT count() == 3 FROM null_in WHERE i in test_set2; +SELECT count() == 2 FROM null_in WHERE i not in test_set2; +SELECT count() == 3 FROM null_in WHERE i global in test_set2; +SELECT count() == 2 FROM null_in WHERE i global not in test_set2; + +DROP TABLE IF EXISTS test_set; DROP TABLE IF EXISTS null_in; + DROP TABLE IF EXISTS null_in_subquery; CREATE TABLE null_in_subquery (dt DateTime, idx int, i Nullable(UInt64)) ENGINE = MergeTree() PARTITION BY dt ORDER BY idx; INSERT INTO null_in_subquery SELECT number % 3, number, number FROM system.numbers LIMIT 99999; From 888baad56574822348f744d2ff85a845fd3c70b5 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 10 Apr 2020 10:35:13 +0300 Subject: [PATCH 047/208] tests/queries/0_stateless/01056_create_table_as: drop dictionary at start --- tests/queries/0_stateless/01056_create_table_as.sql | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/queries/0_stateless/01056_create_table_as.sql b/tests/queries/0_stateless/01056_create_table_as.sql index 868e1f082dd..f95df9b7906 100644 --- a/tests/queries/0_stateless/01056_create_table_as.sql +++ b/tests/queries/0_stateless/01056_create_table_as.sql @@ -15,6 +15,7 @@ CREATE TABLE t3 AS v; -- { serverError 80; } DROP TABLE v; -- dictionary +DROP DICTIONARY IF EXISTS dict; DROP DATABASE if exists test_01056_dict_data; CREATE DATABASE test_01056_dict_data; CREATE TABLE test_01056_dict_data.dict_data (key Int, value UInt16) Engine=Memory(); From 569b85eda4b73110fe26f39e26fed94645ba4cb2 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 10 Apr 2020 10:46:23 +0300 Subject: [PATCH 048/208] Add ability to use unbundled msgpack Actually it works before but by accidentally and with warnings. --- cmake/find/msgpack.cmake | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cmake/find/msgpack.cmake b/cmake/find/msgpack.cmake index a1f18bb1eb0..0b56bbc1a0d 100644 --- a/cmake/find/msgpack.cmake +++ b/cmake/find/msgpack.cmake @@ -1,2 +1,17 @@ -set(MSGPACK_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/msgpack-c/include) +option (USE_INTERNAL_MSGPACK_LIBRARY "Set to FALSE to use system msgpack library instead of bundled" ${NOT_UNBUNDLED}) + +if (USE_INTERNAL_MSGPACK_LIBRARY) + if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/msgpack-c/include/msgpack.hpp") + message(WARNING "submodule contrib/msgpack-c is missing. to fix try run: \n git submodule update --init --recursive") + set(USE_INTERNAL_MSGPACK_LIBRARY 0) + set(MISSING_INTERNAL_MSGPACK_LIBRARY 1) + endif() +endif() + +if (USE_INTERNAL_MSGPACK_LIBRARY) + set(MSGPACK_INCLUDE_DIR ${ClickHouse_SOURCE_DIR}/contrib/msgpack-c/include) +else() + find_path(MSGPACK_INCLUDE_DIR NAMES msgpack.hpp PATHS ${MSGPACK_INCLUDE_PATHS}) +endif() + message(STATUS "Using msgpack: ${MSGPACK_INCLUDE_DIR}") From 66d443df14da259b49c95481f4d21a48376f072b Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 10 Apr 2020 11:30:23 +0300 Subject: [PATCH 049/208] Add libmsgpack-dev into the image (for unbundled build) --- docker/packager/deb/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/packager/deb/Dockerfile b/docker/packager/deb/Dockerfile index bedde0a2013..6aa550aaf82 100644 --- a/docker/packager/deb/Dockerfile +++ b/docker/packager/deb/Dockerfile @@ -48,6 +48,7 @@ RUN apt-get --allow-unauthenticated update -y \ libltdl-dev \ libre2-dev \ libjemalloc-dev \ + libmsgpack-dev \ unixodbc-dev \ odbcinst \ tzdata \ From a4f5280d80e6459dcaba5b34b542f41512207df6 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 12:32:37 +0300 Subject: [PATCH 050/208] Remove excessive } --- website/templates/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/templates/footer.html b/website/templates/footer.html index 42f1e4263be..765ea63d528 100644 --- a/website/templates/footer.html +++ b/website/templates/footer.html @@ -8,7 +8,7 @@ {{ _('ClickHouse source code is published under the Apache 2.0 License.') }} {{ _('Software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.') }}
- © 2016–2020 {{ _('Yandex LLC') }}} + © 2016–2020 {{ _('Yandex LLC') }}
From 564bec176ead92e937efa689b4c3b139264da4e5 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 13:40:59 +0300 Subject: [PATCH 051/208] Update codebrowser links (#10166) * Put single-page content into a separate js file * move break comments * Update codebrowser links --- docs/en/development/browse_code.md | 2 +- docs/en/whats_new/changelog/index.md | 2 +- docs/es/development/browse_code.md | 2 +- docs/es/whats_new/changelog/index.md | 2 +- docs/fa/development/browse_code.md | 2 +- docs/fa/whats_new/changelog/index.md | 2 +- docs/fr/development/browse_code.md | 2 +- docs/fr/whats_new/changelog/index.md | 2 +- docs/ja/development/browse_code.md | 2 +- docs/ja/whats_new/changelog/index.md | 2 +- docs/ru/development/browse_code.md | 2 +- docs/ru/whats_new/changelog/index.md | 2 +- docs/zh/changelog/index.md | 2 +- docs/zh/development/browse_code.md | 2 +- docs/zh/whats_new/changelog/index.md | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/en/development/browse_code.md b/docs/en/development/browse_code.md index 69b15df3629..8e98e3f5f0f 100644 --- a/docs/en/development/browse_code.md +++ b/docs/en/development/browse_code.md @@ -5,7 +5,7 @@ toc_title: Browse ClickHouse Source Code # Browse ClickHouse Source Code {#browse-clickhouse-source-code} -You can use **Woboq** online code browser available [here](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/src/index.html). It provides code navigation and semantic highlighting, search and indexing. The code snapshot is updated daily. +You can use **Woboq** online code browser available [here](https://clickhouse.tech/codebrowser/html_report///ClickHouse/src/index.html). It provides code navigation and semantic highlighting, search and indexing. The code snapshot is updated daily. Also, you can browse sources on [GitHub](https://github.com/ClickHouse/ClickHouse) as usual. diff --git a/docs/en/whats_new/changelog/index.md b/docs/en/whats_new/changelog/index.md index bcfe62cbd0b..969e71fbf42 100644 --- a/docs/en/whats_new/changelog/index.md +++ b/docs/en/whats_new/changelog/index.md @@ -240,7 +240,7 @@ toc_title: '2020' * Updated checking for hung queries in clickhouse-test script [#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([Alexander Kazakov](https://github.com/Akazz)) * Removed some useless files from repository. [#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([alexey-milovidov](https://github.com/alexey-milovidov)) * Changed type of math perftests from `once` to `loop`. [#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([Nikolai Kochetov](https://github.com/KochetovNicolai)) -* Add docker image which allows to build interactive code browser HTML report for our codebase. [#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin)) See [Woboq Code Browser](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/src/index.html) +* Add docker image which allows to build interactive code browser HTML report for our codebase. [#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin)) See [Woboq Code Browser](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/src/index.html) * Suppress some test failures under MSan. [#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alexander Kuzmenkov](https://github.com/akuzm)) * Speedup "exception while insert" test. This test often time out in debug-with-coverage build. [#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([alexey-milovidov](https://github.com/alexey-milovidov)) * Updated `libcxx` and `libcxxabi` to master. In preparation to [#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([alexey-milovidov](https://github.com/alexey-milovidov)) diff --git a/docs/es/development/browse_code.md b/docs/es/development/browse_code.md index 6bbc9d57729..393577e8dca 100644 --- a/docs/es/development/browse_code.md +++ b/docs/es/development/browse_code.md @@ -7,7 +7,7 @@ toc_title: "Examinar el c\xF3digo fuente de ClickHouse" # Examinar el código fuente de ClickHouse {#browse-clickhouse-source-code} -Usted puede utilizar **Woboq** navegador de código en línea disponible [aqui](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/src/index.html). Proporciona navegación de código y resaltado semántico, búsqueda e indexación. La instantánea de código se actualiza diariamente. +Usted puede utilizar **Woboq** navegador de código en línea disponible [aqui](https://clickhouse.tech/codebrowser/html_report///ClickHouse/src/index.html). Proporciona navegación de código y resaltado semántico, búsqueda e indexación. La instantánea de código se actualiza diariamente. Además, puede navegar por las fuentes en [GitHub](https://github.com/ClickHouse/ClickHouse) como de costumbre. diff --git a/docs/es/whats_new/changelog/index.md b/docs/es/whats_new/changelog/index.md index 03c8ea00cbe..053f924099a 100644 --- a/docs/es/whats_new/changelog/index.md +++ b/docs/es/whats_new/changelog/index.md @@ -249,7 +249,7 @@ toc_title: '2020' - Comprobación actualizada de consultas colgadas en el script de prueba de clickhouse [\#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([Alejandro Kazakov](https://github.com/Akazz)) - Se eliminaron algunos archivos inútiles del repositorio. [\#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([alexey-milovidov](https://github.com/alexey-milovidov)) - Tipo cambiado de perftests matemáticos de `once` a `loop`. [\#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([Nikolai Kochetov](https://github.com/KochetovNicolai)) -- Agregue una imagen acoplable que permite construir un informe HTML del navegador de código interactivo para nuestra base de código. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin)) Ver [Navegador de código Woboq](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/src/index.html) +- Agregue una imagen acoplable que permite construir un informe HTML del navegador de código interactivo para nuestra base de código. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin)) Ver [Navegador de código Woboq](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/src/index.html) - Suprima algunas fallas de prueba bajo MSan. [\#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alejandro Kuzmenkov](https://github.com/akuzm)) - Aceleración “exception while insert” prueba. Esta prueba a menudo se agota en la compilación de depuración con cobertura. [\#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([alexey-milovidov](https://github.com/alexey-milovidov)) - Actualizar `libcxx` y `libcxxabi` dominar. En preparación para [\#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [\#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([alexey-milovidov](https://github.com/alexey-milovidov)) diff --git a/docs/fa/development/browse_code.md b/docs/fa/development/browse_code.md index 1609e4b1d77..0338511c44c 100644 --- a/docs/fa/development/browse_code.md +++ b/docs/fa/development/browse_code.md @@ -8,7 +8,7 @@ toc_title: "\u0645\u0631\u0648\u0631 \u06A9\u062F \u0645\u0646\u0628\u0639 \u06A # فهرست clickhouse کد منبع {#browse-clickhouse-source-code} -شما می توانید استفاده کنید **ووبوک** آنلاین کد مرورگر موجود [اینجا](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/index.html). این فراهم می کند ناوبری کد و برجسته معنایی, جستجو و نمایه سازی. عکس فوری کد روزانه به روز می شود. +شما می توانید استفاده کنید **ووبوک** آنلاین کد مرورگر موجود [اینجا](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/index.html). این فراهم می کند ناوبری کد و برجسته معنایی, جستجو و نمایه سازی. عکس فوری کد روزانه به روز می شود. همچنین شما می توانید فهرست منابع در [گیتهاب](https://github.com/ClickHouse/ClickHouse) به عنوان معمول است. diff --git a/docs/fa/whats_new/changelog/index.md b/docs/fa/whats_new/changelog/index.md index c7eb257e5a9..8dcc20e9409 100644 --- a/docs/fa/whats_new/changelog/index.md +++ b/docs/fa/whats_new/changelog/index.md @@ -249,7 +249,7 @@ toc_title: '2020' - به روز شده در چک کردن برای نمایش داده شد را قطع کرد در اسکریپت کلیک تست [\#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([الکساندر کازاکوف](https://github.com/Akazz)) - حذف برخی از فایل های بی فایده از مخزن. [\#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([الکسی میلویدو](https://github.com/alexey-milovidov)) - نوع تغییر کامل ریاضی از `once` به `loop`. [\#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([نیکولای کوچتو](https://github.com/KochetovNicolai)) -- اضافه کردن تصویر کارگر بارانداز که اجازه می دهد تا برای ساخت کد تعاملی مرورگر گزارش متنی برای کدهای ما. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([الساپین](https://github.com/alesapin)) ببینید [مرورگر کد ووبوک](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/src/index.html) +- اضافه کردن تصویر کارگر بارانداز که اجازه می دهد تا برای ساخت کد تعاملی مرورگر گزارش متنی برای کدهای ما. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([الساپین](https://github.com/alesapin)) ببینید [مرورگر کد ووبوک](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/src/index.html) - سرکوب برخی از شکست تست تحت مسان. [\#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([الکساندر کوزمنکوف](https://github.com/akuzm)) - افزایش سرعت “exception while insert” امتحان این تست اغلب زمان در اشکال زدایی با پوشش ساخت. [\#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([الکسی میلویدو](https://github.com/alexey-milovidov)) - به روز شده `libcxx` و `libcxxabi` به سلامتی استاد در تهیه به [\#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [\#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([الکسی میلویدو](https://github.com/alexey-milovidov)) diff --git a/docs/fr/development/browse_code.md b/docs/fr/development/browse_code.md index 62caa530b5d..0d708da5beb 100644 --- a/docs/fr/development/browse_code.md +++ b/docs/fr/development/browse_code.md @@ -7,7 +7,7 @@ toc_title: Parcourir Le Code Source De ClickHouse # Parcourir Le Code Source De ClickHouse {#browse-clickhouse-source-code} -Vous pouvez utiliser **Woboq** navigateur de code en ligne disponible [ici](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/index.html). Il fournit la navigation de code et la mise en évidence sémantique, la recherche et l'indexation. L'instantané de code est mis à jour quotidiennement. +Vous pouvez utiliser **Woboq** navigateur de code en ligne disponible [ici](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/index.html). Il fournit la navigation de code et la mise en évidence sémantique, la recherche et l'indexation. L'instantané de code est mis à jour quotidiennement. Aussi, vous pouvez parcourir les sources sur [GitHub](https://github.com/ClickHouse/ClickHouse) comme à l'habitude. diff --git a/docs/fr/whats_new/changelog/index.md b/docs/fr/whats_new/changelog/index.md index d45e36b1d8f..fe49ce8244c 100644 --- a/docs/fr/whats_new/changelog/index.md +++ b/docs/fr/whats_new/changelog/index.md @@ -249,7 +249,7 @@ toc_title: '2020' - Mise à jour de la vérification des requêtes suspendues dans le script clickhouse-test [\#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([Alexander Kazakov](https://github.com/Akazz)) - Suppression de certains fichiers inutiles du référentiel. [\#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([alexeï-milovidov](https://github.com/alexey-milovidov)) - Changement de type de math perftests de `once` de `loop`. [\#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([Nikolai Kochetov](https://github.com/KochetovNicolai)) -- Ajouter une image docker qui permet de créer un rapport HTML interactif du navigateur de code pour notre base de code. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alésapine](https://github.com/alesapin)) Voir [Navigateur De Code Woboq](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/src/src/index.html) +- Ajouter une image docker qui permet de créer un rapport HTML interactif du navigateur de code pour notre base de code. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alésapine](https://github.com/alesapin)) Voir [Navigateur De Code Woboq](https://clickhouse.tech/codebrowser/html_report///ClickHouse/src/src/index.html) - Supprimer certains échecs de test sous MSan. [\#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alexander Kuzmenkov](https://github.com/akuzm)) - SpeedUp “exception while insert” test. Ce test expire souvent dans la construction debug-with-coverage. [\#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([alexeï-milovidov](https://github.com/alexey-milovidov)) - Mettre `libcxx` et `libcxxabi` maîtriser. En préparation à [\#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [\#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([alexeï-milovidov](https://github.com/alexey-milovidov)) diff --git a/docs/ja/development/browse_code.md b/docs/ja/development/browse_code.md index f8357fcca27..d66b14e400f 100644 --- a/docs/ja/development/browse_code.md +++ b/docs/ja/development/browse_code.md @@ -7,7 +7,7 @@ toc_title: "ClickHouse\u306E\u30BD\u30FC\u30B9\u30B3\u30FC\u30C9\u3092\u53C2\u71 # ClickHouseのソースコードを参照 {#browse-clickhouse-source-code} -を使用することができ **Woboq** オンラインのコードブラウザをご利用 [ここに](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/index.html). このコードナビゲーションや意味のハイライト表示、検索インデックス. コードのスナップショットは随時更新中です。 +を使用することができ **Woboq** オンラインのコードブラウザをご利用 [ここに](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/index.html). このコードナビゲーションや意味のハイライト表示、検索インデックス. コードのスナップショットは随時更新中です。 また、ソースを閲覧することもできます [GitHub](https://github.com/ClickHouse/ClickHouse) いつものように diff --git a/docs/ja/whats_new/changelog/index.md b/docs/ja/whats_new/changelog/index.md index dd382ebf5ce..0d90862ee11 100644 --- a/docs/ja/whats_new/changelog/index.md +++ b/docs/ja/whats_new/changelog/index.md @@ -249,7 +249,7 @@ toc_title: '2020' - Clickhouseテストスクリプトでハングクエリのチェックを更新 [\#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([Alexander Kazakov](https://github.com/Akazz)) - リポジトリか [\#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([alexey-milovidov](https://github.com/alexey-milovidov)) - から数学perftestsの変更タイプ `once` に `loop`. [\#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([Nikolai Kochetov](https://github.com/KochetovNicolai)) -- 追加docker画像を構築ィコードのブラウザのhtmlレポート当社のコードベース. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin))見る [Woboqコードブラウザ](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/src/index.html) +- 追加docker画像を構築ィコードのブラウザのhtmlレポート当社のコードベース. [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin))見る [Woboqコードブラウザ](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/src/index.html) - MSanの下でいくつかのテストの失敗を抑制. [\#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alexander Kuzmenkov](https://github.com/akuzm)) - スピードアップ “exception while insert” テスト。 このテス [\#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([alexey-milovidov](https://github.com/alexey-milovidov)) - 更新 `libcxx` と `libcxxabi` マスターに。 準備のために [\#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [\#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([alexey-milovidov](https://github.com/alexey-milovidov)) diff --git a/docs/ru/development/browse_code.md b/docs/ru/development/browse_code.md index f87e3be7f4b..814b213a6a7 100644 --- a/docs/ru/development/browse_code.md +++ b/docs/ru/development/browse_code.md @@ -1,6 +1,6 @@ # Навигация по коду ClickHouse {#navigatsiia-po-kodu-clickhouse} -Для навигации по коду онлайн доступен **Woboq**, он расположен [здесь](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/src/index.html). В нём реализовано удобное перемещение между исходными файлами, семантическая подсветка, подсказки, индексация и поиск. Слепок кода обновляется ежедневно. +Для навигации по коду онлайн доступен **Woboq**, он расположен [здесь](https://clickhouse.tech/codebrowser/html_report///ClickHouse/src/index.html). В нём реализовано удобное перемещение между исходными файлами, семантическая подсветка, подсказки, индексация и поиск. Слепок кода обновляется ежедневно. Также вы можете просматривать исходники на [GitHub](https://github.com/ClickHouse/ClickHouse). diff --git a/docs/ru/whats_new/changelog/index.md b/docs/ru/whats_new/changelog/index.md index bcfe62cbd0b..969e71fbf42 100644 --- a/docs/ru/whats_new/changelog/index.md +++ b/docs/ru/whats_new/changelog/index.md @@ -240,7 +240,7 @@ toc_title: '2020' * Updated checking for hung queries in clickhouse-test script [#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([Alexander Kazakov](https://github.com/Akazz)) * Removed some useless files from repository. [#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([alexey-milovidov](https://github.com/alexey-milovidov)) * Changed type of math perftests from `once` to `loop`. [#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([Nikolai Kochetov](https://github.com/KochetovNicolai)) -* Add docker image which allows to build interactive code browser HTML report for our codebase. [#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin)) See [Woboq Code Browser](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/src/index.html) +* Add docker image which allows to build interactive code browser HTML report for our codebase. [#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([alesapin](https://github.com/alesapin)) See [Woboq Code Browser](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/src/index.html) * Suppress some test failures under MSan. [#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alexander Kuzmenkov](https://github.com/akuzm)) * Speedup "exception while insert" test. This test often time out in debug-with-coverage build. [#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([alexey-milovidov](https://github.com/alexey-milovidov)) * Updated `libcxx` and `libcxxabi` to master. In preparation to [#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([alexey-milovidov](https://github.com/alexey-milovidov)) diff --git a/docs/zh/changelog/index.md b/docs/zh/changelog/index.md index 90bb7abe0b0..33bb7bfd5f1 100644 --- a/docs/zh/changelog/index.md +++ b/docs/zh/changelog/index.md @@ -246,7 +246,7 @@ machine_translated_rev: b111334d6614a02564cf32f379679e9ff970d9b1 - 更新了clickhouse-test脚本中挂起查询的检查 [\#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([亚历山大\*卡扎科夫](https://github.com/Akazz)) - 从存储库中删除了一些无用的文件。 [\#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([阿列克谢-米洛维多夫](https://github.com/alexey-milovidov)) - 更改类型的数学perftests从 `once` 到 `loop`. [\#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([尼古拉\*科切托夫](https://github.com/KochetovNicolai)) -- 添加码头镜像,它允许为我们的代码库构建交互式代码浏览器HTML报告。 [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([阿利沙平](https://github.com/alesapin))见 [Woboq代码浏览器](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/index.html) +- 添加码头镜像,它允许为我们的代码库构建交互式代码浏览器HTML报告。 [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([阿利沙平](https://github.com/alesapin))见 [Woboq代码浏览器](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/index.html) - 抑制MSan下的一些测试失败。 [\#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alexander Kuzmenkov](https://github.com/akuzm)) - 加速 “exception while insert” 测试 此测试通常在具有复盖率的调试版本中超时。 [\#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([阿列克谢-米洛维多夫](https://github.com/alexey-milovidov)) - 更新 `libcxx` 和 `libcxxabi` 为了主人 在准备 [\#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [\#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([阿列克谢-米洛维多夫](https://github.com/alexey-milovidov)) diff --git a/docs/zh/development/browse_code.md b/docs/zh/development/browse_code.md index 10d3ffecd15..d098675b6a0 100644 --- a/docs/zh/development/browse_code.md +++ b/docs/zh/development/browse_code.md @@ -7,7 +7,7 @@ toc_title: "\u6D4F\u89C8ClickHouse\u6E90\u4EE3\u7801" # 浏览ClickHouse源代码 {#browse-clickhouse-source-code} -您可以使用 **Woboq** 在线代码浏览器可用 [这里](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/src/index.html). 它提供了代码导航和语义突出显示,搜索和索引。 代码快照每天更新。 +您可以使用 **Woboq** 在线代码浏览器可用 [这里](https://clickhouse.tech/codebrowser/html_report///ClickHouse/src/index.html). 它提供了代码导航和语义突出显示,搜索和索引。 代码快照每天更新。 此外,您还可以浏览源 [GitHub](https://github.com/ClickHouse/ClickHouse) 像往常一样 diff --git a/docs/zh/whats_new/changelog/index.md b/docs/zh/whats_new/changelog/index.md index 90bb7abe0b0..33bb7bfd5f1 100644 --- a/docs/zh/whats_new/changelog/index.md +++ b/docs/zh/whats_new/changelog/index.md @@ -246,7 +246,7 @@ machine_translated_rev: b111334d6614a02564cf32f379679e9ff970d9b1 - 更新了clickhouse-test脚本中挂起查询的检查 [\#8858](https://github.com/ClickHouse/ClickHouse/pull/8858) ([亚历山大\*卡扎科夫](https://github.com/Akazz)) - 从存储库中删除了一些无用的文件。 [\#8843](https://github.com/ClickHouse/ClickHouse/pull/8843) ([阿列克谢-米洛维多夫](https://github.com/alexey-milovidov)) - 更改类型的数学perftests从 `once` 到 `loop`. [\#8783](https://github.com/ClickHouse/ClickHouse/pull/8783) ([尼古拉\*科切托夫](https://github.com/KochetovNicolai)) -- 添加码头镜像,它允许为我们的代码库构建交互式代码浏览器HTML报告。 [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([阿利沙平](https://github.com/alesapin))见 [Woboq代码浏览器](https://clickhouse-test-reports.s3.yandex.net/codebrowser/html_report///ClickHouse/dbms/index.html) +- 添加码头镜像,它允许为我们的代码库构建交互式代码浏览器HTML报告。 [\#8781](https://github.com/ClickHouse/ClickHouse/pull/8781) ([阿利沙平](https://github.com/alesapin))见 [Woboq代码浏览器](https://clickhouse.tech/codebrowser/html_report///ClickHouse/dbms/index.html) - 抑制MSan下的一些测试失败。 [\#8780](https://github.com/ClickHouse/ClickHouse/pull/8780) ([Alexander Kuzmenkov](https://github.com/akuzm)) - 加速 “exception while insert” 测试 此测试通常在具有复盖率的调试版本中超时。 [\#8711](https://github.com/ClickHouse/ClickHouse/pull/8711) ([阿列克谢-米洛维多夫](https://github.com/alexey-milovidov)) - 更新 `libcxx` 和 `libcxxabi` 为了主人 在准备 [\#9304](https://github.com/ClickHouse/ClickHouse/issues/9304) [\#9308](https://github.com/ClickHouse/ClickHouse/pull/9308) ([阿列克谢-米洛维多夫](https://github.com/alexey-milovidov)) From 91a33e1eec27b31a262ac409ecd3f3dd976e1516 Mon Sep 17 00:00:00 2001 From: "Mikhail f. Shiryaev" Date: Fri, 10 Apr 2020 12:45:25 +0200 Subject: [PATCH 052/208] Fix code wrapping for non-code part (#10129) * Fix code wrapping for non-code part * Fix links, fix formatting --- docs/en/sql_reference/statements/create.md | 24 ++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/docs/en/sql_reference/statements/create.md b/docs/en/sql_reference/statements/create.md index fbfe3eb2cfb..36dd3aced8d 100644 --- a/docs/en/sql_reference/statements/create.md +++ b/docs/en/sql_reference/statements/create.md @@ -15,24 +15,18 @@ CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(.. ### Clauses {#clauses} -- `IF NOT EXISTS` +- `IF NOT EXISTS` + If the `db_name` database already exists, then ClickHouse doesn't create a new database and: + - Doesn't throw an exception if clause is specified. + - Throws an exception if clause isn't specified. - If the `db_name` database already exists, then ClickHouse doesn't create a new database and: - - - Doesn't throw an exception if clause is specified. - - Throws an exception if clause isn't specified. - -- `ON CLUSTER` - - ClickHouse creates the `db_name` database on all the servers of a specified cluster. +- `ON CLUSTER` + ClickHouse creates the `db_name` database on all the servers of a specified cluster. - `ENGINE` - - - [MySQL](../engines/database_engines/mysql.md) - - Allows you to retrieve data from the remote MySQL server. - - By default, ClickHouse uses its own [database engine](../engines/database_engines/index.md). + - [MySQL](../../engines/database_engines/mysql.md) + Allows you to retrieve data from the remote MySQL server. + By default, ClickHouse uses its own [database engine](../../engines/database_engines/index.md). ## CREATE TABLE {#create-table-query} From 9b0640a3b53aff4de72c0bd85c45a8440d68193c Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 10 Apr 2020 14:29:56 +0300 Subject: [PATCH 053/208] Fix odbc round trip test --- .../0_stateless/01086_odbc_roundtrip.sh | 24 +++++++++++++++++++ .../0_stateless/01086_odbc_roundtrip.sql | 14 ----------- 2 files changed, 24 insertions(+), 14 deletions(-) create mode 100755 tests/queries/0_stateless/01086_odbc_roundtrip.sh delete mode 100644 tests/queries/0_stateless/01086_odbc_roundtrip.sql diff --git a/tests/queries/0_stateless/01086_odbc_roundtrip.sh b/tests/queries/0_stateless/01086_odbc_roundtrip.sh new file mode 100755 index 00000000000..827376395d1 --- /dev/null +++ b/tests/queries/0_stateless/01086_odbc_roundtrip.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CUR_DIR/../shell_config.sh + + +for i in $(seq 1 10); do + ${CLICKHOUSE_CLIENT} -q "select count() > 1 as ok from (select * from odbc('DSN={ClickHouse DSN (ANSI)}','system','tables'))" 2>/dev/null && break +done + +${CLICKHOUSE_CLIENT} --query "select count() > 1 as ok from (select * from odbc('DSN={ClickHouse DSN (Unicode)}','system','tables'))" + +${CLICKHOUSE_CLIENT} --query "DROP DATABASE IF EXISTS test_01086" +${CLICKHOUSE_CLIENT} --query "CREATE DATABASE test_01086" + + +${CLICKHOUSE_CLIENT} --query "CREATE TABLE test_01086.t (x UInt8, y Float32, z String) ENGINE = Memory" +${CLICKHOUSE_CLIENT} --query "INSERT INTO test_01086.t VALUES (1,0.1,'a я'),(2,0.2,'b ą'),(3,0.3,'c d')" + +${CLICKHOUSE_CLIENT} --query "SELECT * FROM odbc('DSN={ClickHouse DSN (ANSI)}','test_01086','t') ORDER BY x" + +${CLICKHOUSE_CLIENT} --query "SELECT * FROM odbc('DSN={ClickHouse DSN (Unicode)}','test_01086','t') ORDER BY x" + +${CLICKHOUSE_CLIENT} --query "DROP DATABASE test_01086;" diff --git a/tests/queries/0_stateless/01086_odbc_roundtrip.sql b/tests/queries/0_stateless/01086_odbc_roundtrip.sql deleted file mode 100644 index 2c31711d895..00000000000 --- a/tests/queries/0_stateless/01086_odbc_roundtrip.sql +++ /dev/null @@ -1,14 +0,0 @@ -select count() > 1 as ok from (select * from odbc('DSN={ClickHouse DSN (ANSI)}','system','tables')); -select count() > 1 as ok from (select * from odbc('DSN={ClickHouse DSN (Unicode)}','system','tables')); - -DROP DATABASE IF EXISTS test_01086; -CREATE DATABASE test_01086; -USE test_01086; - -CREATE TABLE t (x UInt8, y Float32, z String) ENGINE = Memory; -INSERT INTO t VALUES (1,0.1,'a я'),(2,0.2,'b ą'),(3,0.3,'c d'); - -select * from odbc('DSN={ClickHouse DSN (ANSI)}','test_01086','t') ORDER BY x; -select * from odbc('DSN={ClickHouse DSN (Unicode)}','test_01086','t') ORDER BY x; - -DROP DATABASE test_01086; From 2108f621ddb5497ba22b8feba2edff85b503c14e Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 14:31:21 +0300 Subject: [PATCH 054/208] Disable webvisor on single-page docs --- website/js/base.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/website/js/base.js b/website/js/base.js index 2c43e435f48..ae8b3c01573 100644 --- a/website/js/base.js +++ b/website/js/base.js @@ -50,13 +50,14 @@ (function (d, w, c) { (w[c] = w[c] || []).push(function() { + var is_single_page = $('html').attr('data-single-page') === 'true'; try { w.yaCounter18343495 = new Ya.Metrika2({ - id:18343495, - clickmap:true, - trackLinks:true, - accurateTrackBounce:true, - webvisor:true + id: 18343495, + clickmap: !is_single_page, + trackLinks: !is_single_page, + accurateTrackBounce: !is_single_page, + webvisor: !is_single_page }); } catch(e) { } }); From 88657cfbe1ce48cbcedf469d5a3f16be89f335b9 Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 10 Apr 2020 15:14:27 +0300 Subject: [PATCH 055/208] Add retries to test --- tests/queries/0_stateless/00646_url_engine.python | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/queries/0_stateless/00646_url_engine.python b/tests/queries/0_stateless/00646_url_engine.python index 960048dbb8f..1b41216b198 100644 --- a/tests/queries/0_stateless/00646_url_engine.python +++ b/tests/queries/0_stateless/00646_url_engine.python @@ -180,7 +180,14 @@ def main(): if __name__ == "__main__": - try: - main() - except: + exception_text = '' + for i in range(1, 5): + try: + main() + break + except Exception as ex: + exception_text = str(ex) + + if exception_text: + print("Exception: {}".format(exception_text), file=sys.stderr) os._exit(1) From d4bc6662cd441321e9f9170ff83aebdf9cc6ef31 Mon Sep 17 00:00:00 2001 From: Ilya Yatsishin <2159081+qoega@users.noreply.github.com> Date: Fri, 10 Apr 2020 15:29:25 +0300 Subject: [PATCH 056/208] Update extended_roadmap.md --- docs/ru/extended_roadmap.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/extended_roadmap.md b/docs/ru/extended_roadmap.md index 193e2035b56..1637b54311a 100644 --- a/docs/ru/extended_roadmap.md +++ b/docs/ru/extended_roadmap.md @@ -761,7 +761,7 @@ ClickHouse предоставляет возможность обратитьс Вместо этого предлагается описывать необходимые данные в конфигурационном файле сервера или в отдельном сервисе и ссылаться на них по именам. ### 9.3. Поддержка TLS для ZooKeeper. {#podderzhka-tls-dlia-zookeeper} - +[#10174](https://github.com/ClickHouse/ClickHouse/issues/10174) ## 10. Внешние словари. {#vneshnie-slovari} ### 10.1. + Исправление зависания в библиотеке доступа к YT. {#ispravlenie-zavisaniia-v-biblioteke-dostupa-k-yt} From d018977f4b0de8c933a6d90995cb0c17ae9a744e Mon Sep 17 00:00:00 2001 From: Anton Popov Date: Fri, 10 Apr 2020 16:36:51 +0300 Subject: [PATCH 057/208] fix 'ALTER CLEAR INDEX/COLUMN' queries with compact parts --- .../MergeTree/IMergeTreeDataPartWriter.h | 5 ++-- src/Storages/MergeTree/MergeTreeData.h | 5 ---- .../MergeTree/MergeTreeDataMergerMutator.cpp | 24 +++++++++++++++++-- .../MergeTree/MergeTreeDataMergerMutator.h | 6 +++++ .../MergeTree/MergeTreeDataWriter.cpp | 2 +- src/Storages/MergeTree/MergeTreeIndices.h | 2 +- .../MergeTree/MergedBlockOutputStream.cpp | 6 +++-- .../MergeTree/MergedBlockOutputStream.h | 2 ++ 8 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/Storages/MergeTree/IMergeTreeDataPartWriter.h b/src/Storages/MergeTree/IMergeTreeDataPartWriter.h index 4eb842f9279..d18b31edc72 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPartWriter.h +++ b/src/Storages/MergeTree/IMergeTreeDataPartWriter.h @@ -102,8 +102,7 @@ public: written_offset_columns = written_offset_columns_; } - using SkipIndices = std::vector; - const SkipIndices & getSkipIndices() { return skip_indices; } + const MergeTreeIndices & getSkipIndices() { return skip_indices; } void initSkipIndices(); void initPrimaryIndex(); @@ -126,7 +125,7 @@ protected: CompressionCodecPtr default_codec; - std::vector skip_indices; + MergeTreeIndices skip_indices; MergeTreeWriterSettings settings; diff --git a/src/Storages/MergeTree/MergeTreeData.h b/src/Storages/MergeTree/MergeTreeData.h index 125a90d26e0..d299d39726e 100644 --- a/src/Storages/MergeTree/MergeTreeData.h +++ b/src/Storages/MergeTree/MergeTreeData.h @@ -433,11 +433,6 @@ public: DataPartPtr getPartIfExists(const String & part_name, const DataPartStates & valid_states); DataPartPtr getPartIfExists(const MergeTreePartInfo & part_info, const DataPartStates & valid_states); - std::vector getSkipIndices() const - { - return std::vector(std::begin(skip_indices), std::end(skip_indices)); - } - /// Total size of active parts in bytes. size_t getTotalActiveSizeInBytes() const; diff --git a/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp b/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp index 2b732d879b0..c10a6c6dd59 100644 --- a/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp +++ b/src/Storages/MergeTree/MergeTreeDataMergerMutator.cpp @@ -773,6 +773,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mergePartsToTempor MergedBlockOutputStream to{ new_data_part, merging_columns, + data.skip_indices, compression_codec, merged_column_to_size, data_settings->min_merge_bytes_to_use_direct_io, @@ -991,7 +992,6 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor splitMutationCommands(source_part, commands_for_part, for_interpreter, for_file_renames); - UInt64 watch_prev_elapsed = 0; MergeStageProgress stage_progress(1.0); @@ -1043,8 +1043,10 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataMergerMutator::mutatePartToTempor /// All columns from part are changed and may be some more that were missing before in part if (isCompactPart(source_part) || source_part->getColumns().isSubsetOf(updated_header.getNamesAndTypesList())) { + auto part_indices = getIndicesForNewDataPart(data.skip_indices, for_file_renames); mutateAllPartColumns( new_data_part, + part_indices, in, time_of_mutation, compression_codec, @@ -1260,6 +1262,7 @@ void MergeTreeDataMergerMutator::splitMutationCommands( else if (is_compact_part && command.type == MutationCommand::Type::DROP_COLUMN) { removed_columns_from_compact_part.emplace(command.column_name); + for_file_renames.push_back(command); } else if (command.type == MutationCommand::Type::RENAME_COLUMN) { @@ -1439,6 +1442,22 @@ NamesAndTypesList MergeTreeDataMergerMutator::getColumnsForNewDataPart( return all_columns; } +MergeTreeIndices MergeTreeDataMergerMutator::getIndicesForNewDataPart( + const MergeTreeIndices & all_indices, + const MutationCommands & commands_for_removes) +{ + NameSet removed_indices; + for (const auto & command : commands_for_removes) + if (command.type == MutationCommand::DROP_INDEX) + removed_indices.insert(command.column_name); + + MergeTreeIndices new_indices; + for (const auto & index : all_indices) + if (!removed_indices.count(index->name)) + new_indices.push_back(index); + + return new_indices; +} std::set MergeTreeDataMergerMutator::getIndicesToRecalculate( BlockInputStreamPtr & input_stream, @@ -1503,6 +1522,7 @@ bool MergeTreeDataMergerMutator::shouldExecuteTTL(const Names & columns, const M void MergeTreeDataMergerMutator::mutateAllPartColumns( MergeTreeData::MutableDataPartPtr new_data_part, + const MergeTreeIndices & skip_indices, BlockInputStreamPtr mutating_stream, time_t time_of_mutation, const CompressionCodecPtr & compression_codec, @@ -1524,6 +1544,7 @@ void MergeTreeDataMergerMutator::mutateAllPartColumns( MergedBlockOutputStream out{ new_data_part, new_data_part->getColumns(), + skip_indices, compression_codec}; mutating_stream->readPrefix(); @@ -1560,7 +1581,6 @@ void MergeTreeDataMergerMutator::mutateSomePartColumns( if (mutating_stream == nullptr) throw Exception("Cannot mutate part columns with uninitialized mutations stream. It's a bug", ErrorCodes::LOGICAL_ERROR); - if (need_remove_expired_values) mutating_stream = std::make_shared(mutating_stream, data, new_data_part, time_of_mutation, true); diff --git a/src/Storages/MergeTree/MergeTreeDataMergerMutator.h b/src/Storages/MergeTree/MergeTreeDataMergerMutator.h index b24b56a4780..6f4f8a03e9a 100644 --- a/src/Storages/MergeTree/MergeTreeDataMergerMutator.h +++ b/src/Storages/MergeTree/MergeTreeDataMergerMutator.h @@ -160,6 +160,11 @@ private: NamesAndTypesList all_columns, const MutationCommands & commands_for_removes); + /// Get skip indcies, that should exists in the resulting data part. + static MergeTreeIndices getIndicesForNewDataPart( + const MergeTreeIndices & all_indices, + const MutationCommands & commands_for_removes); + bool shouldExecuteTTL(const Names & columns, const MutationCommands & commands) const; /// Return set of indices which should be recalculated during mutation also @@ -173,6 +178,7 @@ private: /// Override all columns of new part using mutating_stream void mutateAllPartColumns( MergeTreeData::MutableDataPartPtr new_data_part, + const MergeTreeIndices & skip_indices, BlockInputStreamPtr mutating_stream, time_t time_of_mutation, const CompressionCodecPtr & codec, diff --git a/src/Storages/MergeTree/MergeTreeDataWriter.cpp b/src/Storages/MergeTree/MergeTreeDataWriter.cpp index c560583259c..34c615994f0 100644 --- a/src/Storages/MergeTree/MergeTreeDataWriter.cpp +++ b/src/Storages/MergeTree/MergeTreeDataWriter.cpp @@ -294,7 +294,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataWriter::writeTempPart(BlockWithPa /// either default lz4 or compression method with zero thresholds on absolute and relative part size. auto compression_codec = data.global_context.chooseCompressionCodec(0, 0); - MergedBlockOutputStream out(new_data_part, columns, compression_codec); + MergedBlockOutputStream out(new_data_part, columns, data.skip_indices, compression_codec); out.writePrefix(); out.writeWithPermutation(block, perm_ptr); diff --git a/src/Storages/MergeTree/MergeTreeIndices.h b/src/Storages/MergeTree/MergeTreeIndices.h index 007851f2912..d871a522e6c 100644 --- a/src/Storages/MergeTree/MergeTreeIndices.h +++ b/src/Storages/MergeTree/MergeTreeIndices.h @@ -125,7 +125,7 @@ public: size_t granularity; }; -using MergeTreeIndices = std::vector; +using MergeTreeIndices = std::vector; class MergeTreeIndexFactory : private boost::noncopyable diff --git a/src/Storages/MergeTree/MergedBlockOutputStream.cpp b/src/Storages/MergeTree/MergedBlockOutputStream.cpp index 221170b7a32..2b482ac7c29 100644 --- a/src/Storages/MergeTree/MergedBlockOutputStream.cpp +++ b/src/Storages/MergeTree/MergedBlockOutputStream.cpp @@ -15,10 +15,11 @@ namespace ErrorCodes MergedBlockOutputStream::MergedBlockOutputStream( const MergeTreeDataPartPtr & data_part, const NamesAndTypesList & columns_list_, + const MergeTreeIndices & skip_indices, CompressionCodecPtr default_codec, bool blocks_are_granules_size) : MergedBlockOutputStream( - data_part, columns_list_, default_codec, {}, + data_part, columns_list_, skip_indices, default_codec, {}, data_part->storage.global_context.getSettings().min_bytes_to_use_direct_io, blocks_are_granules_size) { @@ -27,6 +28,7 @@ MergedBlockOutputStream::MergedBlockOutputStream( MergedBlockOutputStream::MergedBlockOutputStream( const MergeTreeDataPartPtr & data_part, const NamesAndTypesList & columns_list_, + const MergeTreeIndices & skip_indices, CompressionCodecPtr default_codec, const MergeTreeData::DataPart::ColumnToSize & merged_column_to_size, size_t aio_threshold, @@ -49,7 +51,7 @@ MergedBlockOutputStream::MergedBlockOutputStream( disk->createDirectories(part_path); - writer = data_part->getWriter(columns_list, data_part->storage.getSkipIndices(), default_codec, writer_settings); + writer = data_part->getWriter(columns_list, skip_indices, default_codec, writer_settings); writer->initPrimaryIndex(); writer->initSkipIndices(); } diff --git a/src/Storages/MergeTree/MergedBlockOutputStream.h b/src/Storages/MergeTree/MergedBlockOutputStream.h index ee453f41a31..5a92977640e 100644 --- a/src/Storages/MergeTree/MergedBlockOutputStream.h +++ b/src/Storages/MergeTree/MergedBlockOutputStream.h @@ -16,12 +16,14 @@ public: MergedBlockOutputStream( const MergeTreeDataPartPtr & data_part, const NamesAndTypesList & columns_list_, + const MergeTreeIndices & skip_indices, CompressionCodecPtr default_codec, bool blocks_are_granules_size = false); MergedBlockOutputStream( const MergeTreeDataPartPtr & data_part, const NamesAndTypesList & columns_list_, + const MergeTreeIndices & skip_indices, CompressionCodecPtr default_codec, const MergeTreeData::DataPart::ColumnToSize & merged_column_to_size, size_t aio_threshold, From 2034f09b2af9697f90502acb0619749499fdfe5b Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 16:50:38 +0300 Subject: [PATCH 058/208] Grammar in syntax.md --- docs/en/sql_reference/syntax.md | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/en/sql_reference/syntax.md b/docs/en/sql_reference/syntax.md index 12a4b9df7ef..10e8c421f6d 100644 --- a/docs/en/sql_reference/syntax.md +++ b/docs/en/sql_reference/syntax.md @@ -16,11 +16,11 @@ INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def') The `INSERT INTO t VALUES` fragment is parsed by the full parser, and the data `(1, 'Hello, world'), (2, 'abc'), (3, 'def')` is parsed by the fast stream parser. You can also turn on the full parser for the data by using the [input\_format\_values\_interpret\_expressions](../operations/settings/settings.md#settings-input_format_values_interpret_expressions) setting. When `input_format_values_interpret_expressions = 1`, ClickHouse first tries to parse values with the fast stream parser. If it fails, ClickHouse tries to use the full parser for the data, treating it like an SQL [expression](#syntax-expressions). Data can have any format. When a query is received, the server calculates no more than [max\_query\_size](../operations/settings/settings.md#settings-max_query_size) bytes of the request in RAM (by default, 1 MB), and the rest is stream parsed. -This means the system doesn’t have problems with large `INSERT` queries, like MySQL does. +It allows for avoiding issues with large `INSERT` queries. When using the `Values` format in an `INSERT` query, it may seem that data is parsed the same as expressions in a `SELECT` query, but this is not true. The `Values` format is much more limited. -Next we will cover the full parser. For more information about format parsers, see the [Formats](../interfaces/formats.md) section. +The rest of this article covers the full parser. For more information about format parsers, see the [Formats](../interfaces/formats.md) section. ## Spaces {#spaces} @@ -28,33 +28,33 @@ There may be any number of space symbols between syntactical constructions (incl ## Comments {#comments} -SQL-style and C-style comments are supported. -SQL-style comments: from `--` to the end of the line. The space after `--` can be omitted. -Comments in C-style: from `/*` to `*/`. These comments can be multiline. Spaces are not required here, either. +ClickHouse supports either SQL-style and C-style comments. +SQL-style comments start with `--` and continue to the end of the line, a space after `--` can be omitted. +C-style are from `/*` to `*/`and can be multiline, spaces are not required either. ## Keywords {#syntax-keywords} Keywords are case-insensitive when they correspond to: - SQL standard. For example, `SELECT`, `select` and `SeLeCt` are all valid. -- Implementation in some popular DBMS (MySQL or Postgres). For example, `DateTime` is same as `datetime`. +- Implementation in some popular DBMS (MySQL or Postgres). For example, `DateTime` is the same as `datetime`. Whether data type name is case-sensitive can be checked in the `system.data_type_families` table. -In contrast to standard SQL all other keywords (including functions names) are **case-sensitive**. +In contrast to standard SQL, all other keywords (including functions names) are **case-sensitive**. -Keywords are not reserved (they are just parsed as keywords in the corresponding context). If you use [identifiers](#syntax-identifiers) the same as the keywords, enclose them into quotes. For example, the query `SELECT "FROM" FROM table_name` is valid if the table `table_name` has column with the name `"FROM"`. +Keywords are not reserved; they are treated as such only in the corresponding context. If you use [identifiers](#syntax-identifiers) with the same name as the keywords, enclose them into double-quotes or backticks. For example, the query `SELECT "FROM" FROM table_name` is valid if the table `table_name` has column with the name `"FROM"`. ## Identifiers {#syntax-identifiers} Identifiers are: -- Cluster, database, table, partition and column names. +- Cluster, database, table, partition, and column names. - Functions. - Data types. - [Expression aliases](#syntax-expression_aliases). -Identifiers can be quoted or non-quoted. It is recommended to use non-quoted identifiers. +Identifiers can be quoted or non-quoted. The latter is preferred. Non-quoted identifiers must match the regex `^[a-zA-Z_][0-9a-zA-Z_]*$` and can not be equal to [keywords](#syntax-keywords). Examples: `x, _1, X_y__Z123_.` @@ -62,34 +62,34 @@ If you want to use identifiers the same as keywords or you want to use other sym ## Literals {#literals} -There are: numeric, string, compound and `NULL` literals. +There are numeric, string, compound, and `NULL` literals. ### Numeric {#numeric} -A numeric literal tries to be parsed: +Numeric literal tries to be parsed: -- First as a 64-bit signed number, using the [strtoull](https://en.cppreference.com/w/cpp/string/byte/strtoul) function. +- First, as a 64-bit signed number, using the [strtoull](https://en.cppreference.com/w/cpp/string/byte/strtoul) function. - If unsuccessful, as a 64-bit unsigned number, using the [strtoll](https://en.cppreference.com/w/cpp/string/byte/strtol) function. - If unsuccessful, as a floating-point number using the [strtod](https://en.cppreference.com/w/cpp/string/byte/strtof) function. -- Otherwise, an error is returned. +- Otherwise, it returns an error. -The corresponding value will have the smallest type that the value fits in. +Literal value has the smallest type that the value fits in. For example, 1 is parsed as `UInt8`, but 256 is parsed as `UInt16`. For more information, see [Data types](../sql_reference/data_types/index.md). Examples: `1`, `18446744073709551615`, `0xDEADBEEF`, `01`, `0.1`, `1e100`, `-1e-100`, `inf`, `nan`. ### String {#syntax-string-literal} -Only string literals in single quotes are supported. The enclosed characters can be backslash-escaped. The following escape sequences have a corresponding special value: `\b`, `\f`, `\r`, `\n`, `\t`, `\0`, `\a`, `\v`, `\xHH`. In all other cases, escape sequences in the format `\c`, where `c` is any character, are converted to `c`. This means that you can use the sequences `\'`and`\\`. The value will have the [String](../sql_reference/data_types/string.md) type. +Only string literals in single quotes are supported. The enclosed characters can be backslash-escaped. The following escape sequences have a corresponding special value: `\b`, `\f`, `\r`, `\n`, `\t`, `\0`, `\a`, `\v`, `\xHH`. In all other cases, escape sequences in the format `\c`, where `c` is any character, are converted to `c`. It means that you can use the sequences `\'`and`\\`. The value will have the [String](../sql_reference/data_types/string.md) type. -The minimum set of characters that you need to escape in string literals: `'` and `\`. Single quote can be escaped with the single quote, literals `'It\'s'` and `'It''s'` are equal. +In string literals, you need to escape at least `'` and `\`. Single quotes can be escaped with the single quote, literals `'It\'s'` and `'It''s'` are equal. ### Compound {#compound} -Constructions are supported for arrays: `[1, 2, 3]` and tuples: `(1, 'Hello, world!', 2)`.. -Actually, these are not literals, but expressions with the array creation operator and the tuple creation operator, respectively. +Arrays are constructed with square brackets `[1, 2, 3]`. Nuples are constructed with round brackets `(1, 'Hello, world!', 2)`. +Technically these are not literals, but expressions with the array creation operator and the tuple creation operator, respectively. An array must consist of at least one item, and a tuple must have at least two items. -Tuples have a special purpose for use in the `IN` clause of a `SELECT` query. Tuples can be obtained as the result of a query, but they can’t be saved to a database (with the exception of [Memory](../engines/table_engines/special/memory.md) tables). +There's a separate case when tuples appear in the `IN` clause of a `SELECT` query. Query results can include tuples, but tuples can’t be saved to a database (except of tables with [Memory](../engines/table_engines/special/memory.md) engine). ### NULL {#null-literal} @@ -99,13 +99,13 @@ In order to store `NULL` in a table field, it must be of the [Nullable](../sql_r Depending on the data format (input or output), `NULL` may have a different representation. For more information, see the documentation for [data formats](../interfaces/formats.md#formats). -There are many nuances to processing `NULL`. For example, if at least one of the arguments of a comparison operation is `NULL`, the result of this operation will also be `NULL`. The same is true for multiplication, addition, and other operations. For more information, read the documentation for each operation. +There are many nuances to processing `NULL`. For example, if at least one of the arguments of a comparison operation is `NULL`, the result of this operation is also `NULL`. The same is true for multiplication, addition, and other operations. For more information, read the documentation for each operation. In queries, you can check `NULL` using the [IS NULL](operators.md#operator-is-null) and [IS NOT NULL](operators.md) operators and the related functions `isNull` and `isNotNull`. ## Functions {#functions} -Functions are written like an identifier with a list of arguments (possibly empty) in brackets. In contrast to standard SQL, the brackets are required, even for an empty arguments list. Example: `now()`. +Function calls are written like an identifier with a list of arguments (possibly empty) in round brackets. In contrast to standard SQL, the brackets are required, even for an empty argument list. Example: `now()`. There are regular and aggregate functions (see the section “Aggregate functions”). Some aggregate functions can contain two lists of arguments in brackets. Example: `quantile (0.9) (x)`. These aggregate functions are called “parametric” functions, and the arguments in the first list are called “parameters”. The syntax of aggregate functions without parameters is the same as for regular functions. ## Operators {#operators} @@ -115,11 +115,11 @@ For example, the expression `1 + 2 * 3 + 4` is transformed to `plus(plus(1, mult ## Data Types and Database Table Engines {#data_types-and-database-table-engines} -Data types and table engines in the `CREATE` query are written the same way as identifiers or functions. In other words, they may or may not contain an arguments list in brackets. For more information, see the sections “Data types,” “Table engines,” and “CREATE”. +Data types and table engines in the `CREATE` query are written the same way as identifiers or functions. In other words, they may or may not contain an argument list in brackets. For more information, see the sections “Data types,” “Table engines,” and “CREATE”. ## Expression Aliases {#syntax-expression_aliases} -An alias is a user-defined name for an expression in a query. +An alias is a user-defined name for expression in a query. ``` sql expr AS alias @@ -141,7 +141,7 @@ expr AS alias ### Notes on Usage {#notes-on-usage} -Aliases are global for a query or subquery and you can define an alias in any part of a query for any expression. For example, `SELECT (1 AS n) + 2, n`. +Aliases are global for a query or subquery, and you can define an alias in any part of a query for any expression. For example, `SELECT (1 AS n) + 2, n`. Aliases are not visible in subqueries and between subqueries. For example, while executing the query `SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a` ClickHouse generates the exception `Unknown identifier: num`. @@ -182,4 +182,4 @@ An expression is a function, identifier, literal, application of an operator, ex A list of expressions is one or more expressions separated by commas. Functions and operators, in turn, can have expressions as arguments. -[Original article](https://clickhouse.tech/docs/en/query_language/syntax/) +[Original article](https://clickhouse.tech/docs/en/sql_reference/syntax/) From 9d81f896488d5f8496f598f1544d2a754617f906 Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 10 Apr 2020 16:51:09 +0300 Subject: [PATCH 059/208] Add sleep to test --- tests/queries/0_stateless/01086_odbc_roundtrip.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/queries/0_stateless/01086_odbc_roundtrip.sh b/tests/queries/0_stateless/01086_odbc_roundtrip.sh index 827376395d1..71ea517f4dd 100755 --- a/tests/queries/0_stateless/01086_odbc_roundtrip.sh +++ b/tests/queries/0_stateless/01086_odbc_roundtrip.sh @@ -6,6 +6,7 @@ CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) for i in $(seq 1 10); do ${CLICKHOUSE_CLIENT} -q "select count() > 1 as ok from (select * from odbc('DSN={ClickHouse DSN (ANSI)}','system','tables'))" 2>/dev/null && break + sleep 0.1 done ${CLICKHOUSE_CLIENT} --query "select count() > 1 as ok from (select * from odbc('DSN={ClickHouse DSN (Unicode)}','system','tables'))" From 81a7b4b248ef77e5fb71502fbbeb93dcb135ed59 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 16:55:00 +0300 Subject: [PATCH 060/208] Grammar in operators.md --- docs/en/sql_reference/operators.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/en/sql_reference/operators.md b/docs/en/sql_reference/operators.md index 418a9e32771..8ae9e460d87 100644 --- a/docs/en/sql_reference/operators.md +++ b/docs/en/sql_reference/operators.md @@ -5,8 +5,7 @@ toc_title: Operators # Operators {#operators} -All operators are transformed to their corresponding functions at the query parsing stage in accordance with their precedence and associativity. -Groups of operators are listed in order of priority (the higher it is in the list, the earlier the operator is connected to its arguments). +ClickHouse transforms operators to their corresponding functions at the query parsing stage according to their priority, precedence, and associativity. ## Access Operators {#access-operators} @@ -78,7 +77,7 @@ Groups of operators are listed in order of priority (the higher it is in the lis EXTRACT(part FROM date); ``` -Extracts a part from a given date. For example, you can retrieve a month from a given date, or a second from a time. +Extract parts from a given date. For example, you can retrieve a month from a given date, or a second from a time. The `part` parameter specifies which part of the date to retrieve. The following values are available: @@ -151,7 +150,7 @@ Types of intervals: - `YEAR` !!! warning "Warning" - Intervals with different types can’t be combined. You can’t use expressions like `INTERVAL 4 DAY 1 HOUR`. Express intervals in units that are smaller or equal the the smallest unit of the interval, for example `INTERVAL 25 HOUR`. You can use consequtive operations like in the example below. + Intervals with different types can’t be combined. You can’t use expressions like `INTERVAL 4 DAY 1 HOUR`. Specify intervals in units that are smaller or equal to the smallest unit of the interval, for example, `INTERVAL 25 HOUR`. You can use consecutive operations, like in the example below. Example: @@ -214,7 +213,7 @@ The `transform` function does not work with `NULL`. `x -> expr` – The `lambda(x, expr) function.` -The following operators do not have a priority, since they are brackets: +The following operators do not have a priority since they are brackets: ## Array Creation Operator {#array-creation-operator} @@ -229,7 +228,7 @@ The following operators do not have a priority, since they are brackets: All binary operators have left associativity. For example, `1 + 2 + 3` is transformed to `plus(plus(1, 2), 3)`. Sometimes this doesn’t work the way you expect. For example, `SELECT 4 > 2 > 3` will result in 0. -For efficiency, the `and` and `or` functions accept any number of arguments. The corresponding chains of `AND` and `OR` operators are transformed to a single call of these functions. +For efficiency, the `and` and `or` functions accept any number of arguments. The corresponding chains of `AND` and `OR` operators are transformed into a single call of these functions. ## Checking for `NULL` {#checking-for-null} From 0b4019becb61d63e9d20efccc8b7899e9ff778b3 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 16:56:25 +0300 Subject: [PATCH 061/208] Website performance improvements (#10175) * workers moved to separate repo https://github.com/ClickHouse/clickhouse-website-worker * support prefetch tag * Prefetch docs from front page + async load of secondary images --- website/index.html | 4 ++ website/js/base.js | 6 +++ website/templates/common_meta.html | 4 ++ website/templates/index/community.html | 18 +++---- website/templates/index/efficient.html | 4 +- website/templates/index/scalable.html | 2 +- website/templates/index/why.html | 8 +-- website/workers/events.js | 34 ------------ website/workers/meet-form.js | 75 -------------------------- website/workers/play-api.js | 24 --------- website/workers/repo.js | 10 ---- 11 files changed, 30 insertions(+), 159 deletions(-) delete mode 100644 website/workers/events.js delete mode 100644 website/workers/meet-form.js delete mode 100644 website/workers/play-api.js delete mode 100644 website/workers/repo.js diff --git a/website/index.html b/website/index.html index b249fc31285..e2ac6e31441 100644 --- a/website/index.html +++ b/website/index.html @@ -1,3 +1,7 @@ +{% set prefetch_items = [ + ('/docs/en/', 'document') +] %} + {% extends "templates/base.html" %} {% block content %} diff --git a/website/js/base.js b/website/js/base.js index ae8b3c01573..4e43a44d63a 100644 --- a/website/js/base.js +++ b/website/js/base.js @@ -47,6 +47,12 @@ }, 70); } + $('img').each(function() { + var src = $(this).attr('data-src'); + if (src) { + $(this).attr('src', src); + } + }); (function (d, w, c) { (w[c] = w[c] || []).push(function() { diff --git a/website/templates/common_meta.html b/website/templates/common_meta.html index 7ed5a8409ec..2aca17f93a2 100644 --- a/website/templates/common_meta.html +++ b/website/templates/common_meta.html @@ -19,3 +19,7 @@ content="{% if description %}{{ description }}{% else %}{{ _('ClickHouse is an open source distributed column-oriented database management system that allows generating analytical data reports in real time using SQL queries. Сreated by Yandex ClickHouse manages extremely large volumes of data in a stable and sustainable manner.') }}{% endif %}"/> + +{% for prefetch_item in prefetch_items %} + +{% endfor %} diff --git a/website/templates/index/community.html b/website/templates/index/community.html index e48edb311b6..47bcbd67218 100644 --- a/website/templates/index/community.html +++ b/website/templates/index/community.html @@ -9,7 +9,7 @@
- {{ _('ClickHouse YouTube Channel') }} @@ -21,7 +21,7 @@
- {{ _('ClickHouse Official Twitter Account') }} @@ -32,7 +32,7 @@
- {{ _('ClickHouse at Telegram') }} @@ -56,7 +56,7 @@
- ClickHouse GitHub @@ -72,7 +72,7 @@
- Blazing fast + Blazing fast

Blazing fast

@@ -15,7 +15,7 @@ processing performance for a single query stands at more than 2 terabytes per second (after decompression, only used columns). In distributed setup reads are automatically balanced among healthy replicas to avoid increasing latency.

- Fault tolerant + Fault tolerant

Fault-tolerant

@@ -24,14 +24,14 @@
- Easy to use + Easy to use

Easy to use

ClickHouse is simple and works out-of-the-box. It streamlines all your data processing: ingest all your structured data into the system and it becomes instantly available for building reports. SQL dialect allows expressing the desired result without involving any custom non-standard API that could be found in some DBMS.

- Highly reliable + Highly reliable

Highly reliable

diff --git a/website/workers/events.js b/website/workers/events.js deleted file mode 100644 index 653139af9f9..00000000000 --- a/website/workers/events.js +++ /dev/null @@ -1,34 +0,0 @@ -addEventListener('fetch', event => { - event.respondWith(handleRequest(event.request)) -}) - -async function handleRequest(request) { - let raw = await fetch('https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/README.md'); - let text = await raw.text(); - let lines = text.split('\n'); - let skip = true; - let events = []; - for (let idx in lines) { - let line = lines[idx]; - if (skip) { - if (line.includes('Upcoming Events')) { - skip = false; - } - } else { - if (!line) { continue; }; - line = line.split(']('); - var tail = line[1].split(') '); - events.push({ - 'signup_link': tail[0], - 'event_name': line[0].replace('* [', ''), - 'event_date': tail[1].slice(0, -1).replace('on ', '') - }); - } - } - - let response = new Response(JSON.stringify({ - 'events': events - })); - response.headers.set('Content-Type', 'application/json'); - return response; -} diff --git a/website/workers/meet-form.js b/website/workers/meet-form.js deleted file mode 100644 index 6506d59522e..00000000000 --- a/website/workers/meet-form.js +++ /dev/null @@ -1,75 +0,0 @@ - -addEventListener('fetch', event => { - event.respondWith(handleRequest(event.request)) -}) - -async function handleRequest(request) { - if (request.method != 'POST') { - return new Response('Bad request', { - status: 400, - statusText: 'Bad request' - }); - } - let url = new URL('https://api.sendgrid.com/v3/mail/send'); - let newHdrs = new Headers(); - newHdrs.set('Authorization', 'Bearer ' + SENDGRID_TOKEN); - newHdrs.set('Content-Type', 'application/json'); - let args = await request.json(); - let subject = args['name'] + ' wants to meet'; - let content = ''; - let argsKeys = Object.keys(args); - if (['name', 'email', 'city', 'company'].filter(n=>!argsKeys.includes(n)).length) { - return new Response('Bad request', { - status: 400, - statusText: 'Bad request' - }); - } - for (let key in args) { - content += key.charAt(0).toUpperCase() + key.slice(1); - content += ':\r\n' + args[key] + '\r\n\r\n'; - } - let body = { - "personalizations": [ - { - "to": [ - { - "email": "clickhouse-feedback@yandex-team.ru", - "name": "ClickHouse Core Team" - } - ], - "subject": subject - } - ], "content": [ - { - "type": "text/plain", - "value": content - } - ], "from": { - "email": "no-reply@clickhouse.tech", - "name": "ClickHouse Website" - }, "reply_to": - { - "email": "no-reply@clickhouse.tech", - "name": "ClickHouse Website" - } - }; - const init = { - body: JSON.stringify(body), - headers: newHdrs, - method: 'POST' - } - - let response = await fetch(url, init); - let status = 200; - if (response.status != 202) { - status = 200; - } - - return new Response('{}', { - status: status, - statusText: response.statusText.replace('Accepted', 'OK'), - headers: new Headers({ - 'Content-Type': 'application/json' - }) - }) -} diff --git a/website/workers/play-api.js b/website/workers/play-api.js deleted file mode 100644 index 62792d37a4d..00000000000 --- a/website/workers/play-api.js +++ /dev/null @@ -1,24 +0,0 @@ -addEventListener('fetch', event => { - event.respondWith(handleRequest(event.request)) -}) - -async function handleRequest(request) { - let url = new URL(request.url); - url.hostname = 'play-api.clickhouse.tech'; - url.port = 8443; - url.pathname = url.pathname.replace('/api/', '/'); - let newHdrs = new Headers() - - const init = { - body: request.body, - headers: request.headers, - method: request.method - } - - let response = await fetch(url, init); - - return new Response(response.body, { - status: response.status, - statusText: response.statusText - }) -} diff --git a/website/workers/repo.js b/website/workers/repo.js deleted file mode 100644 index 470391cf225..00000000000 --- a/website/workers/repo.js +++ /dev/null @@ -1,10 +0,0 @@ -addEventListener('fetch', event => { - event.respondWith(handleRequest(event.request)) -}) - -async function handleRequest(request) { - let url = new URL(request.url); - url.hostname = 'repo.yandex.ru'; - url.pathname = '/clickhouse' + url.pathname; - return fetch(url) -} From 27eaea184a54d27f3724b533b77e8a9180560add Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 10 Apr 2020 17:03:42 +0300 Subject: [PATCH 062/208] Add small timeout --- tests/queries/0_stateless/00646_url_engine.python | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/queries/0_stateless/00646_url_engine.python b/tests/queries/0_stateless/00646_url_engine.python index 1b41216b198..494eb12b0ef 100644 --- a/tests/queries/0_stateless/00646_url_engine.python +++ b/tests/queries/0_stateless/00646_url_engine.python @@ -2,6 +2,7 @@ from __future__ import print_function import csv import sys +import time import tempfile import threading import os, urllib @@ -187,6 +188,7 @@ if __name__ == "__main__": break except Exception as ex: exception_text = str(ex) + time.sleep(0.1) if exception_text: print("Exception: {}".format(exception_text), file=sys.stderr) From 5e860ddb0482deb97147934190bb7cd4e4ecb884 Mon Sep 17 00:00:00 2001 From: tavplubix Date: Fri, 10 Apr 2020 17:09:47 +0300 Subject: [PATCH 063/208] fix 01098_temporary_and_external_tables --- .../0_stateless/01098_temporary_and_external_tables.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/queries/0_stateless/01098_temporary_and_external_tables.sh b/tests/queries/0_stateless/01098_temporary_and_external_tables.sh index f8b9862c1c1..c984f363c31 100755 --- a/tests/queries/0_stateless/01098_temporary_and_external_tables.sh +++ b/tests/queries/0_stateless/01098_temporary_and_external_tables.sh @@ -5,12 +5,12 @@ CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) url="https://${CLICKHOUSE_HOST}:${CLICKHOUSE_PORT_HTTPS}/?session_id=test_01098" -${CLICKHOUSE_CURL} -sSk "$url" --data "CREATE TEMPORARY TABLE tmp_table AS SELECT number AS n FROM numbers(42)" > /dev/null; +${CLICKHOUSE_CURL} -m 30 -sSk "$url" --data "CREATE TEMPORARY TABLE tmp_table AS SELECT number AS n FROM numbers(42)" > /dev/null; name_expr="'\`' || database || '\`.\`' || name || '\`'" -full_tmp_name=`echo "SELECT $name_expr FROM system.tables WHERE database='_temporary_and_external_tables' AND create_table_query LIKE '%tmp_table%'" | ${CLICKHOUSE_CURL} -sSgk $url -d @-` +full_tmp_name=`echo "SELECT $name_expr FROM system.tables WHERE database='_temporary_and_external_tables' AND create_table_query LIKE '%tmp_table%'" | ${CLICKHOUSE_CURL} -m 30 -sSgk $url -d @-` -echo "SELECT * FROM $full_tmp_name" | ${CLICKHOUSE_CURL} -sSgk $url -d @- | grep -F "Code: 291" > /dev/null && echo "OK" +echo "SELECT * FROM $full_tmp_name" | ${CLICKHOUSE_CURL} -m 60 -sSgk $url -d @- | grep -F "Code: 291" > /dev/null && echo "OK" -echo -ne '0\n1\n' | ${CLICKHOUSE_CURL} -sSkF 'file=@-' "$url&file_format=CSV&file_types=UInt64&query=SELECT+sum((number+GLOBAL+IN+(SELECT+number+AS+n+FROM+remote('127.0.0.2',+numbers(5))+WHERE+n+GLOBAL+IN+(SELECT+*+FROM+tmp_table)+AND+n+GLOBAL+NOT+IN+(SELECT+*+FROM+file)+))+AS+res),+sum(number*res)+FROM+remote('127.0.0.2',+numbers(10))"; +echo -ne '0\n1\n' | ${CLICKHOUSE_CURL} -m 30 -sSkF 'file=@-' "$url&file_format=CSV&file_types=UInt64&query=SELECT+sum((number+GLOBAL+IN+(SELECT+number+AS+n+FROM+remote('127.0.0.2',+numbers(5))+WHERE+n+GLOBAL+IN+(SELECT+*+FROM+tmp_table)+AND+n+GLOBAL+NOT+IN+(SELECT+*+FROM+file)+))+AS+res),+sum(number*res)+FROM+remote('127.0.0.2',+numbers(10))"; From d2237c3ab850c4aeb924cf7ed7c061acac7d5bfa Mon Sep 17 00:00:00 2001 From: alesapin Date: Fri, 10 Apr 2020 17:17:32 +0300 Subject: [PATCH 064/208] Update msgpack.cmake --- cmake/find/msgpack.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/find/msgpack.cmake b/cmake/find/msgpack.cmake index 0b56bbc1a0d..093555bebc0 100644 --- a/cmake/find/msgpack.cmake +++ b/cmake/find/msgpack.cmake @@ -2,7 +2,7 @@ option (USE_INTERNAL_MSGPACK_LIBRARY "Set to FALSE to use system msgpack library if (USE_INTERNAL_MSGPACK_LIBRARY) if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/msgpack-c/include/msgpack.hpp") - message(WARNING "submodule contrib/msgpack-c is missing. to fix try run: \n git submodule update --init --recursive") + message(WARNING "submodule contrib/msgpack-c is missing. To fix try run: \n git submodule update --init --recursive") set(USE_INTERNAL_MSGPACK_LIBRARY 0) set(MISSING_INTERNAL_MSGPACK_LIBRARY 1) endif() From 7177bc4cbf10524f8d9fa630db4ca113e6232ad2 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 17:40:55 +0300 Subject: [PATCH 065/208] fix to_url with version_prefix --- docs/tools/build.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tools/build.py b/docs/tools/build.py index 1719fe051d3..fb3dba8a529 100755 --- a/docs/tools/build.py +++ b/docs/tools/build.py @@ -307,7 +307,7 @@ def write_redirect_html(out_path, to_url): Page Redirection @@ -320,7 +320,7 @@ def write_redirect_html(out_path, to_url): def build_redirect_html(args, from_path, to_path): for lang in ['en', 'es', 'fr', 'ja', 'fa']: # TODO: args.lang.split(','): out_path = os.path.join(args.docs_output_dir, lang, from_path.replace('.md', '/index.html')) - version_prefix = args.version_prefix + '/' if args.version_prefix else '/' + version_prefix = f'/{args.version_prefix}/' if args.version_prefix else '/' target_path = to_path.replace('.md', '/') to_url = f'/docs{version_prefix}{lang}/{target_path}' to_url = to_url.strip() From 770bc149df7f85107020aad11f2ed59c65ae6859 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 17:54:20 +0300 Subject: [PATCH 066/208] Extra mark for redirect template page --- docs/tools/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tools/build.py b/docs/tools/build.py index fb3dba8a529..7508a072acb 100755 --- a/docs/tools/build.py +++ b/docs/tools/build.py @@ -301,7 +301,8 @@ def write_redirect_html(out_path, to_url): except OSError: pass with open(out_path, 'w') as f: - f.write(f''' + f.write(f''' + From ca1aba62b3706c78f819ef0583318b6ec7003582 Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 17:56:09 +0300 Subject: [PATCH 067/208] Do not minify redirects --- docs/tools/website.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/tools/website.py b/docs/tools/website.py index 9704cf7d5a4..83eef270fc5 100644 --- a/docs/tools/website.py +++ b/docs/tools/website.py @@ -155,7 +155,8 @@ def minify_website(args): with open(path, 'rb') as f: content = f.read().decode('utf-8') if filename.endswith('.html'): - content = htmlmin.minify(content, remove_empty_space=False) + if not content.startswith(' diff --git a/docs/en/introduction/features_considered_disadvantages.md b/docs/en/introduction/features_considered_disadvantages.md deleted file mode 100644 index e295b5570ab..00000000000 --- a/docs/en/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -toc_priority: 5 -toc_title: ClickHouse Features that Can Be Considered Disadvantages ---- - -# ClickHouse Features that Can Be Considered Disadvantages {#clickhouse-features-that-can-be-considered-disadvantages} - -1. No full-fledged transactions. -2. Lack of ability to modify or delete already inserted data with high rate and low latency. There are batch deletes and updates available to clean up or modify data, for example to comply with [GDPR](https://gdpr-info.eu). -3. The sparse index makes ClickHouse not so suitable for point queries retrieving single rows by their keys. - -[Original article](https://clickhouse.tech/docs/en/introduction/features_considered_disadvantages/) diff --git a/docs/en/sql_reference/statements/index.md b/docs/en/sql_reference/statements/index.md index 1adf93a153e..507d858c14a 100644 --- a/docs/en/sql_reference/statements/index.md +++ b/docs/en/sql_reference/statements/index.md @@ -2,4 +2,3 @@ toc_folder_title: Statements toc_priority: 31 --- - diff --git a/docs/es/introduction/distinctive_features.md b/docs/es/introduction/distinctive_features.md index 5117fcf9324..82b757341be 100644 --- a/docs/es/introduction/distinctive_features.md +++ b/docs/es/introduction/distinctive_features.md @@ -68,4 +68,10 @@ ClickHouse utiliza la replicación multi-maestro asincrónica. Después de escri Para obtener más información, consulte la sección [Replicación de datos](../engines/table_engines/mergetree_family/replication.md). +## Características que pueden considerarse desventajas {#clickhouse-features-that-can-be-considered-disadvantages} + +1. No hay transacciones completas. +2. Falta de capacidad para modificar o eliminar datos ya insertados con alta tasa y baja latencia. Hay eliminaciones y actualizaciones por lotes disponibles para limpiar o modificar datos, por ejemplo, para cumplir con [GDPR](https://gdpr-info.eu). +3. El índice disperso hace que ClickHouse no sea tan adecuado para consultas de puntos que recuperan filas individuales por sus claves. + [Artículo Original](https://clickhouse.tech/docs/en/introduction/distinctive_features/) diff --git a/docs/es/introduction/features_considered_disadvantages.md b/docs/es/introduction/features_considered_disadvantages.md deleted file mode 100644 index 60eabad3102..00000000000 --- a/docs/es/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 3e185d24c9fe772c7cf03d5475247fb829a21dfa -toc_priority: 5 -toc_title: "Caracter\xEDsticas de ClickHouse que pueden considerarse desventajas" ---- - -# Características de ClickHouse que pueden considerarse desventajas {#clickhouse-features-that-can-be-considered-disadvantages} - -1. No hay transacciones completas. -2. Falta de capacidad para modificar o eliminar datos ya insertados con alta tasa y baja latencia. Hay eliminaciones y actualizaciones por lotes disponibles para limpiar o modificar datos, por ejemplo, para cumplir con [GDPR](https://gdpr-info.eu). -3. El índice disperso hace que ClickHouse no sea tan adecuado para consultas de puntos que recuperan filas individuales por sus claves. - -[Artículo Original](https://clickhouse.tech/docs/en/introduction/features_considered_disadvantages/) diff --git a/docs/fa/introduction/distinctive_features.md b/docs/fa/introduction/distinctive_features.md index a4313168796..71a8f3eb543 100644 --- a/docs/fa/introduction/distinctive_features.md +++ b/docs/fa/introduction/distinctive_features.md @@ -62,6 +62,12 @@ ClickHouse از روش asynchronous multimaster replication استفاده می برای اطلاعات بیشتر، به بخش [replication داده ها](../engines/table_engines/mergetree_family/replication.md) مراجعه کنید. +## ویژگی های از ClickHouse که می تواند معایبی باشد. {#wyjgy-hy-z-clickhouse-khh-my-twnd-m-yby-bshd} + +1. بدون پشتیبانی کامل از تراکنش +2. عدم توانایی برای تغییر و یا حذف داده های در حال حاضر وارد شده با سرعت بالا و تاخیر کم. برای پاک کردن و یا اصلاح داده ها، به عنوان مثال برای پیروی از [GDPR](https://gdpr-info.eu)، دسته ای پاک و به روزرسانی وجود دارد.حال توسعه می باشد. +3. Sparse index باعث می شود ClickHouse چندان مناسب اجرای پرسمان های point query برای دریافت یک ردیف از داده ها با استفاده از کلید آنها نباشد. +
[مقاله اصلی](https://clickhouse.tech/docs/fa/introduction/distinctive_features/) diff --git a/docs/fa/introduction/features_considered_disadvantages.md b/docs/fa/introduction/features_considered_disadvantages.md deleted file mode 100644 index 5a8ea156da5..00000000000 --- a/docs/fa/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,11 +0,0 @@ -
- -# ویژگی های از ClickHouse که می تواند معایبی باشد. {#wyjgy-hy-z-clickhouse-khh-my-twnd-m-yby-bshd} - -1. بدون پشتیبانی کامل از تراکنش -2. عدم توانایی برای تغییر و یا حذف داده های در حال حاضر وارد شده با سرعت بالا و تاخیر کم. برای پاک کردن و یا اصلاح داده ها، به عنوان مثال برای پیروی از [GDPR](https://gdpr-info.eu)، دسته ای پاک و به روزرسانی وجود دارد.حال توسعه می باشد. -3. Sparse index باعث می شود ClickHouse چندان مناسب اجرای پرسمان های point query برای دریافت یک ردیف از داده ها با استفاده از کلید آنها نباشد. - -
- -[مقاله اصلی](https://clickhouse.tech/docs/fa/introduction/features_considered_disadvantages/) diff --git a/docs/fr/introduction/distinctive_features.md b/docs/fr/introduction/distinctive_features.md index dcea4046fcd..2c825cac85a 100644 --- a/docs/fr/introduction/distinctive_features.md +++ b/docs/fr/introduction/distinctive_features.md @@ -68,4 +68,10 @@ ClickHouse utilise la réplication multi-maître asynchrone. Après avoir été Pour plus d'informations, consultez la section [Réplication des données](../engines/table_engines/mergetree_family/replication.md). +## Caractéristiques de ClickHouse qui peuvent être considérées comme des inconvénients {#clickhouse-features-that-can-be-considered-disadvantages} + +1. Pas de transactions à part entière. +2. Manque de capacité à modifier ou supprimer des données déjà insérées avec un taux élevé et une faible latence. Des suppressions et des mises à jour par lots sont disponibles pour nettoyer ou modifier les données, par exemple pour [GDPR](https://gdpr-info.eu). +3. L'index clairsemé rend ClickHouse pas si approprié pour les requêtes ponctuelles récupérant des lignes simples par leurs clés. + [Article Original](https://clickhouse.tech/docs/en/introduction/distinctive_features/) diff --git a/docs/fr/introduction/features_considered_disadvantages.md b/docs/fr/introduction/features_considered_disadvantages.md deleted file mode 100644 index dc9fe708fef..00000000000 --- a/docs/fr/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: f865c9653f9df092694258e0ccdd733c339112f5 -toc_priority: 5 -toc_title: "Caract\xE9ristiques de ClickHouse qui peuvent \xEAtre consid\xE9r\xE9\ - es comme des inconv\xE9nients" ---- - -# Caractéristiques de ClickHouse qui peuvent être considérées comme des inconvénients {#clickhouse-features-that-can-be-considered-disadvantages} - -1. Pas de transactions à part entière. -2. Manque de capacité à modifier ou supprimer des données déjà insérées avec un taux élevé et une faible latence. Des suppressions et des mises à jour par lots sont disponibles pour nettoyer ou modifier les données, par exemple pour [GDPR](https://gdpr-info.eu). -3. L'index clairsemé rend ClickHouse pas si approprié pour les requêtes ponctuelles récupérant des lignes simples par leurs clés. - -[Article Original](https://clickhouse.tech/docs/en/introduction/features_considered_disadvantages/) diff --git a/docs/ja/introduction/distinctive_features.md b/docs/ja/introduction/distinctive_features.md index 6cd0834708c..5c4b91759dc 100644 --- a/docs/ja/introduction/distinctive_features.md +++ b/docs/ja/introduction/distinctive_features.md @@ -63,4 +63,10 @@ ClickHouseには、精度を犠牲にしてパフォーマンスを得るため 詳細については、[データ複製](../engines/table_engines/mergetree_family/replication.md) セクションを参照してください。 +## 欠点と考えられるClickHouseの機能 {#qian-dian-tokao-erareruclickhousenoji-neng} + +1. 本格的なトランザクションはありません。 +2. 既に挿入されたデータの変更または削除を、高頻度かつ低遅延に行う機能はありません。 [GDPR](https://gdpr-info.eu)に準拠するなど、データをクリーンアップまたは変更するために、バッチ削除およびバッチ更新が利用可能です。 +3. インデックスが疎であるため、ClickHouseは、キーで単一行を取得するようなクエリにはあまり適していません。 + [Original article](https://clickhouse.yandex/docs/en/introduction/distinctive_features/) diff --git a/docs/ja/introduction/features_considered_disadvantages.md b/docs/ja/introduction/features_considered_disadvantages.md deleted file mode 100644 index 8c766e06fe8..00000000000 --- a/docs/ja/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -toc_priority: 5 -toc_title: 欠点と見なすことができるClickHouseの機能 ---- - -# 欠点と考えられるClickHouseの機能 {#qian-dian-tokao-erareruclickhousenoji-neng} - -1. 本格的なトランザクションはありません。 -2. 既に挿入されたデータの変更または削除を、高頻度かつ低遅延に行う機能はありません。 [GDPR](https://gdpr-info.eu)に準拠するなど、データをクリーンアップまたは変更するために、バッチ削除およびバッチ更新が利用可能です。 -3. インデックスが疎であるため、ClickHouseは、キーで単一行を取得するようなクエリにはあまり適していません。 - -[Original article](https://clickhouse.yandex/docs/en/introduction/features_considered_disadvantages/) diff --git a/docs/redirects.txt b/docs/redirects.txt index c0f3c81813f..95df6773359 100644 --- a/docs/redirects.txt +++ b/docs/redirects.txt @@ -98,6 +98,7 @@ functions/ym_dict_functions.md query_language/functions/ym_dict_functions.md interfaces/http_interface.md interfaces/http.md interfaces/third-party_client_libraries.md interfaces/third-party/client_libraries.md interfaces/third-party_gui.md interfaces/third-party/gui.md +introduction/features_considered_disadvantages.md introduction/distinctive_features.md introduction/possible_silly_questions.md faq/general.md introduction/ya_metrika_task.md introduction/history.md operations/performance/sampling_query_profiler.md operations/optimizing_performance/sampling_query_profiler.md diff --git a/docs/ru/introduction/distinctive_features.md b/docs/ru/introduction/distinctive_features.md index 0cc40e4e162..079a0667070 100644 --- a/docs/ru/introduction/distinctive_features.md +++ b/docs/ru/introduction/distinctive_features.md @@ -61,4 +61,11 @@ ClickHouse предоставляет различные способы разм Подробнее смотрите раздел [Репликация данных](../engines/table_engines/mergetree_family/replication.md). +## Особенности, которые могут считаться недостатками {#osobennosti-clickhouse-kotorye-mogut-schitatsia-nedostatkami} + +1. Отсутствие полноценных транзакций. +2. Возможность изменять или удалять ранее записанные данные с низкими задержками и высокой частотой запросов не предоставляется. Есть массовое удаление и изменение данных для очистки более не нужного или соответствия [GDPR](https://gdpr-info.eu). +3. Разреженный индекс делает ClickHouse плохо пригодным для точечных чтений одиночных строк по своим + ключам. + [Оригинальная статья](https://clickhouse.tech/docs/ru/introduction/distinctive_features/) diff --git a/docs/ru/introduction/features_considered_disadvantages.md b/docs/ru/introduction/features_considered_disadvantages.md deleted file mode 100644 index 0cd4838d908..00000000000 --- a/docs/ru/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,8 +0,0 @@ -# Особенности ClickHouse, которые могут считаться недостатками {#osobennosti-clickhouse-kotorye-mogut-schitatsia-nedostatkami} - -1. Отсутствие полноценных транзакций. -2. Возможность изменять или удалять ранее записанные данные с низкими задержками и высокой частотой запросов не предоставляется. Есть массовое удаление и изменение данных для очистки более не нужного или соответствия [GDPR](https://gdpr-info.eu). -3. Разреженный индекс делает ClickHouse плохо пригодным для точечных чтений одиночных строк по своим - ключам. - -[Оригинальная статья](https://clickhouse.tech/docs/ru/introduction/features_considered_disadvantages/) diff --git a/docs/tools/nav.py b/docs/tools/nav.py index 56d47d58d07..fe11b21d8e7 100644 --- a/docs/tools/nav.py +++ b/docs/tools/nav.py @@ -35,6 +35,8 @@ def build_nav_entry(root): title = meta.get('toc_folder_title', 'hidden') prio = meta.get('toc_priority', 9999) logging.debug(f'Nav entry: {prio}, {title}, {path}') + if not content.strip(): + title = 'hidden' result_items.append((prio, title, path)) result_items = sorted(result_items, key=lambda x: (x[0], x[1])) result = collections.OrderedDict([(item[1], item[2]) for item in result_items]) @@ -45,8 +47,16 @@ def build_nav(lang, args): docs_dir = os.path.join(args.docs_dir, lang) _, _, nav = build_nav_entry(docs_dir) result = [] + index_key = None for key, value in nav.items(): if key and value: + if value == 'index.md': + index_key = key + continue result.append({key: value}) + if index_key: + key = list(result[0].keys())[0] + result[0][key][index_key] = 'index.md' + result[0][key].move_to_end(index_key, last=False) print('result', result) return result diff --git a/docs/zh/introduction/distinctive_features.md b/docs/zh/introduction/distinctive_features.md index 3b1e7a8c716..a267a49bf8a 100644 --- a/docs/zh/introduction/distinctive_features.md +++ b/docs/zh/introduction/distinctive_features.md @@ -62,4 +62,10 @@ ClickHouse使用异步的多主复制技术。当数据被写入任何一个可 更多信息,参见 [数据复制](../engines/table_engines/mergetree_family/replication.md)。 +# 的限制 {#clickhouseke-yi-ren-wei-shi-que-dian-de-gong-neng} + +1. 没有完整的事务支持。 +2. 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合 [GDPR](https://gdpr-info.eu)。 +3. 稀疏索引使得ClickHouse不适合通过其键检索单行的点查询。 + [来源文章](https://clickhouse.tech/docs/en/introduction/distinctive_features/) diff --git a/docs/zh/introduction/features_considered_disadvantages.md b/docs/zh/introduction/features_considered_disadvantages.md deleted file mode 100644 index efc967e90ac..00000000000 --- a/docs/zh/introduction/features_considered_disadvantages.md +++ /dev/null @@ -1,8 +0,0 @@ - -# ClickHouse的限制 {#clickhouseke-yi-ren-wei-shi-que-dian-de-gong-neng} - -1. 没有完整的事务支持。 -2. 缺少高频率,低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合 [GDPR](https://gdpr-info.eu)。 -3. 稀疏索引使得ClickHouse不适合通过其键检索单行的点查询。 - -[来源文章](https://clickhouse.tech/docs/zh/introduction/features_considered_disadvantages/) From 2f5b4b0f9b3d3738291f190da11c5d43d5c36b21 Mon Sep 17 00:00:00 2001 From: Mikhail Filimonov Date: Fri, 10 Apr 2020 22:01:10 +0200 Subject: [PATCH 080/208] Added ability to relax the restriction on non-deterministic functions usage in mutations with allow_nondeterministic_mutations setting. --- src/Core/Settings.h | 2 +- src/Interpreters/MutationsInterpreter.cpp | 4 ++- ...eterministic_functions_zookeeper.reference | 3 ++ ...th_nondeterministic_functions_zookeeper.sh | 28 +++++++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 753231603b2..31b8bd6ab02 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -418,7 +418,7 @@ struct Settings : public SettingsCollection M(SettingBool, merge_tree_uniform_read_distribution, true, "Obsolete setting, does nothing. Will be removed after 2020-05-20", 0) \ M(SettingUInt64, mark_cache_min_lifetime, 0, "Obsolete setting, does nothing. Will be removed after 2020-05-31", 0) \ M(SettingBool, partial_merge_join, false, "Obsolete. Use join_algorithm='prefer_partial_merge' instead.", 0) \ - + M(SettingBool, allow_nondeterministic_mutations, false, "Allow non-deterministic functions in ALTER UPDATE/ALTER DELETE statements", 0) \ DECLARE_SETTINGS_COLLECTION(LIST_OF_SETTINGS) diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index 669b72c6317..df0267b9450 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -661,9 +661,11 @@ BlockInputStreamPtr MutationsInterpreter::addStreamsForLaterStages(const std::ve void MutationsInterpreter::validate(TableStructureReadLockHolder &) { + const Settings & settings = context.getSettingsRef(); + /// For Replicated* storages mutations cannot employ non-deterministic functions /// because that produces inconsistencies between replicas - if (startsWith(storage->getName(), "Replicated")) + if (startsWith(storage->getName(), "Replicated") && !settings.allow_nondeterministic_mutations) { for (const auto & command : commands) { diff --git a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference index b462a5a7baa..f799e8ed8f0 100644 --- a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference +++ b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference @@ -2,3 +2,6 @@ OK OK OK OK +OK +OK +OK diff --git a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh index ac66dbc352a..9b190855adf 100755 --- a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh +++ b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh @@ -11,6 +11,22 @@ T1=table_1017_merge ${CLICKHOUSE_CLIENT} -n -q " DROP TABLE IF EXISTS $R1; DROP TABLE IF EXISTS $R2; + DROP TABLE IF EXISTS $T1; + + DROP TABLE IF EXISTS lookup_table; + DROP TABLE IF EXISTS table_for_dict; + DROP DICTIONARY IF EXISTS dict1; + + CREATE TABLE table_for_dict (y UInt64, y_new UInt32) ENGINE = Log; + INSERT INTO table_for_dict VALUES (3, 3003),(4,4004); + + CREATE DICTIONARY dict1( y UInt64 DEFAULT 0, y_new UInt32 DEFAULT 0 ) PRIMARY KEY y + SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'table_for_dict' PASSWORD '' DB '${CLICKHOUSE_DATABASE}')) + LIFETIME(MIN 1 MAX 10) + LAYOUT(FLAT()); + + CREATE TABLE lookup_table (y UInt32, y_new UInt32) ENGINE = Join(ANY, LEFT, y); + INSERT INTO lookup_table VALUES(1,1001),(2,1002); CREATE TABLE $R1 (x UInt32, y UInt32) ENGINE ReplicatedMergeTree('/clickhouse/tables/${CLICKHOUSE_DATABASE}.table_1017', 'r1') ORDER BY x; CREATE TABLE $R2 (x UInt32, y UInt32) ENGINE ReplicatedMergeTree('/clickhouse/tables/${CLICKHOUSE_DATABASE}.table_1017', 'r2') ORDER BY x; @@ -35,9 +51,21 @@ ${CLICKHOUSE_CLIENT} --query "ALTER TABLE $T1 DELETE WHERE rand() = 0" 2>&1 > /d ${CLICKHOUSE_CLIENT} --query "ALTER TABLE $T1 UPDATE y = y + rand() % 1 WHERE not ignore()" 2>&1 > /dev/null \ && echo 'OK' || echo 'FAIL' +# hm... it looks like joinGet condidered determenistic +${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 UPDATE y = joinGet('${CLICKHOUSE_DATABASE}.lookup_table', 'y_new', y) WHERE x=1" 2>&1 \ +| echo 'OK' || echo 'FAIL' + +${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 DELETE WHERE dictHas('${CLICKHOUSE_DATABASE}.dict1', toUInt64(x))" 2>&1 \ +| fgrep -q "must use only deterministic functions" && echo 'OK' || echo 'FAIL' + +${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 DELETE WHERE dictHas('${CLICKHOUSE_DATABASE}.dict1', toUInt64(x))" --allow_nondeterministic_mutations=1 2>&1 \ +&& echo 'OK' || echo 'FAIL' ${CLICKHOUSE_CLIENT} -n -q " DROP TABLE IF EXISTS $R2; DROP TABLE IF EXISTS $R1; DROP TABLE IF EXISTS $T1; + DROP TABLE IF EXISTS lookup_table; + DROP TABLE IF EXISTS table_for_dict; + DROP DICTIONARY IF EXISTS dict1; " From 2122eab14eda10dc3bb8f68192bad3da47ecf51e Mon Sep 17 00:00:00 2001 From: Ivan Blinkov Date: Fri, 10 Apr 2020 23:02:36 +0300 Subject: [PATCH 081/208] Update adopters.md --- docs/ru/introduction/adopters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/ru/introduction/adopters.md b/docs/ru/introduction/adopters.md index 20c465f6418..5f8b825353c 100644 --- a/docs/ru/introduction/adopters.md +++ b/docs/ru/introduction/adopters.md @@ -3,7 +3,7 @@ machine_translated: true machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 --- -# Усыновители ClickHouse {#clickhouse-adopters} +# Пользователи ClickHouse {#clickhouse-adopters} !!! warning "Оговорка" Следующий список компаний, использующих ClickHouse, и их истории успеха собраны из открытых источников, поэтому они могут отличаться от текущей реальности. Мы были бы очень признательны, если бы вы поделились историей принятия ClickHouse в свою компанию и [добавьте его в список](https://github.com/ClickHouse/ClickHouse/edit/master/docs/en/introduction/adopters.md), но, пожалуйста, убедитесь, что у вас не будет никаких проблем с NDA, сделав это. Предоставление обновлений с публикациями от других компаний также полезно. From 330d13810666b1044b99f6e3916bc61ecade8c7d Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Fri, 10 Apr 2020 23:58:13 +0300 Subject: [PATCH 082/208] Update Settings.h --- src/Core/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 31b8bd6ab02..bb2b0a20b81 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -406,6 +406,7 @@ struct Settings : public SettingsCollection M(SettingBool, validate_polygons, true, "Throw exception if polygon is invalid in function pointInPolygon (e.g. self-tangent, self-intersecting). If the setting is false, the function will accept invalid polygons but may silently return wrong result.", 0) \ M(SettingUInt64, max_parser_depth, 1000, "Maximum parser depth.", 0) \ M(SettingSeconds, temporary_live_view_timeout, DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC, "Timeout after which temporary live view is deleted.", 0) \ + M(SettingBool, allow_nondeterministic_mutations, false, "Allow non-deterministic functions in ALTER UPDATE/ALTER DELETE statements", 0) \ \ /** Obsolete settings that do nothing but left for compatibility reasons. Remove each one after half a year of obsolescence. */ \ \ @@ -418,7 +419,6 @@ struct Settings : public SettingsCollection M(SettingBool, merge_tree_uniform_read_distribution, true, "Obsolete setting, does nothing. Will be removed after 2020-05-20", 0) \ M(SettingUInt64, mark_cache_min_lifetime, 0, "Obsolete setting, does nothing. Will be removed after 2020-05-31", 0) \ M(SettingBool, partial_merge_join, false, "Obsolete. Use join_algorithm='prefer_partial_merge' instead.", 0) \ - M(SettingBool, allow_nondeterministic_mutations, false, "Allow non-deterministic functions in ALTER UPDATE/ALTER DELETE statements", 0) \ DECLARE_SETTINGS_COLLECTION(LIST_OF_SETTINGS) From 9208847a85a6db66ead9983a33d864f7164c2668 Mon Sep 17 00:00:00 2001 From: Vitaly Baranov Date: Sat, 11 Apr 2020 00:07:08 +0300 Subject: [PATCH 083/208] Update submodule libc-headers to a new version. --- contrib/libc-headers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/libc-headers b/contrib/libc-headers index 9676d2645a7..92c74f938cf 160000 --- a/contrib/libc-headers +++ b/contrib/libc-headers @@ -1 +1 @@ -Subproject commit 9676d2645a713e679dc981ffd84dee99fcd68b8e +Subproject commit 92c74f938cf2c4dd529cae4f3d2923d153b029a7 From c9542b66018bc2e0ca124572642af364f627ebcb Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev Date: Sat, 11 Apr 2020 01:08:43 +0300 Subject: [PATCH 084/208] Style fixes for communication between ClickHouse and Zookeeper over SSL --- src/Common/ZooKeeper/ZooKeeper.cpp | 3 +-- src/Common/ZooKeeper/ZooKeeperImpl.h | 3 ++- src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Common/ZooKeeper/ZooKeeper.cpp b/src/Common/ZooKeeper/ZooKeeper.cpp index f2442f3f5c5..032d1e90ff5 100644 --- a/src/Common/ZooKeeper/ZooKeeper.cpp +++ b/src/Common/ZooKeeper/ZooKeeper.cpp @@ -72,9 +72,8 @@ void ZooKeeper::init(const std::string & implementation_, const std::string & ho { bool secure = bool(startsWith(host_string, "secure://")); - if (secure) { + if (secure) host_string.erase(0, strlen("secure://")); - } nodes.emplace_back(Coordination::ZooKeeper::Node{Poco::Net::SocketAddress{host_string}, secure}); } diff --git a/src/Common/ZooKeeper/ZooKeeperImpl.h b/src/Common/ZooKeeper/ZooKeeperImpl.h index 069df723d43..840cbdbde3f 100644 --- a/src/Common/ZooKeeper/ZooKeeperImpl.h +++ b/src/Common/ZooKeeper/ZooKeeperImpl.h @@ -93,7 +93,8 @@ struct ZooKeeperRequest; class ZooKeeper : public IKeeper { public: - struct Node { + struct Node + { Poco::Net::SocketAddress address; bool secure; }; diff --git a/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp b/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp index 0bca8e0f561..d9d3402fa32 100644 --- a/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp +++ b/src/Common/ZooKeeper/tests/zkutil_test_commands_new_lib.cpp @@ -29,12 +29,12 @@ try splitInto<','>(hosts_strings, hosts_arg); ZooKeeper::Nodes nodes; nodes.reserve(hosts_strings.size()); - for (auto & host_string : hosts_strings) { + for (auto & host_string : hosts_strings) + { bool secure = bool(startsWith(host_string, "secure://")); - if (secure) { + if (secure) host_string.erase(0, strlen("secure://")); - } nodes.emplace_back(ZooKeeper::Node{Poco::Net::SocketAddress{host_string},secure}); } From c3a71616d9a55b6745fbd4872ef0990a2816d5f9 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Sat, 11 Apr 2020 01:29:15 +0300 Subject: [PATCH 085/208] simplified backport script --- utils/simple-backport/.gitignore | 1 + utils/simple-backport/README.md | 73 ++++++++++++++++++++++++ utils/simple-backport/backport.sh | 95 +++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 utils/simple-backport/.gitignore create mode 100644 utils/simple-backport/README.md create mode 100755 utils/simple-backport/backport.sh diff --git a/utils/simple-backport/.gitignore b/utils/simple-backport/.gitignore new file mode 100644 index 00000000000..72e8ffc0db8 --- /dev/null +++ b/utils/simple-backport/.gitignore @@ -0,0 +1 @@ +* diff --git a/utils/simple-backport/README.md b/utils/simple-backport/README.md new file mode 100644 index 00000000000..89a0c6d6f22 --- /dev/null +++ b/utils/simple-backport/README.md @@ -0,0 +1,73 @@ +# Упрощённый скрипт для бекпортирования + +Это упрощённый скрипт для бекпортирования. Он определяет, какие пулреквесты ещё не бекпортировали из мастера в указанную ветку. Запускать скрипт нужно из папки, где он лежит, указав ему название ветки. Он предполагает, что ваш апстримный remote называется origin. +``` +cd my-clickhouse-repo/simple-backport +git fetch origin +time GITHUB_TOKEN= ./backport.sh 20.1 +``` + +Скрипт выведет примитивный отчёт: +``` +$ time GITHUB_TOKEN= ~/backport.sh 20.3 +144 PRs differ between 20.3 and master. +backport https://github.com/ClickHouse/ClickHouse/pull/10135 +backport https://github.com/ClickHouse/ClickHouse/pull/10121 +... +backport https://github.com/ClickHouse/ClickHouse/pull/9808 +backport https://github.com/ClickHouse/ClickHouse/pull/9410 + +real 0m1.213s +user 0m1.065s +sys 0m0.311s +``` + +Также в рабочей папке сгенерируется отчёт `<ваша-ветка>-report.tsv`: + +``` +$ cat 20.3-report.tsv +skip 10153 https://github.com/ClickHouse/ClickHouse/pull/10153 pr10153.json +skip 10147 https://github.com/ClickHouse/ClickHouse/pull/10147 pr10147.json +no-backport 10138 https://github.com/ClickHouse/ClickHouse/pull/10138 pr10138.json +backport 10135 https://github.com/ClickHouse/ClickHouse/pull/10135 pr10135.json +skip 10134 https://github.com/ClickHouse/ClickHouse/pull/10134 pr10134.json +... +``` + +Можно кликать по ссылкам прям из консоли, а можно ещё проще: + +``` +$ cat <ветка>-report.tsv | grep ^backport | cut -f3 +$ cat <ветка>-report.tsv | grep ^backport | cut -f3 | xargs -n1 xdg-open +``` + +Такая команда откроет в браузере все пулреквесты, которые надо бекпортировать. Есть и другие статусы, посмотрите какие: + +``` +$ cat 20.1-report.tsv | cut -f1 | sort | uniq -c | sort -rn + 446 skip + 38 done + 25 conflict + 18 backport + 10 no-backport +``` + + +### Как разметить пулреквест? +По умолчанию бекпортируются все пулреквесты, у которых в описании указана категория чейнжлога Bug fix. Если этого недостаточно, используйте теги: +* v20.1-backported -- этот пулреквест уже бекпортирован в ветку 20.1. На случай, если автоматически не определилось. +* v20.1-no-backport -- в ветку 20.1 бекпортировать не нужно. +* pr-no-backport -- ни в какие ветки бекпортировать не нужно. +* v20.1-conflicts -- при бекпорте в 20.1 произошёл конфликт. Такие пулреквесты скрипт пропускает, к ним можно потом вернуться. +* pr-should-backport -- нужно бекпортировать в поддерживаемые ветки. +* v20.1-must-backport -- нужно бекпортировать в 20.1. + + +### Я поправил пулреквест, почему скрипт не видит? +В процессе работы скрипт кеширует данные о пулреквестах в текущей папке, чтобы экономить квоту гитхаба. Удалите закешированные файлы, например, для всех реквестов, которые не помечены как пропущенные: +``` +$ cat <ваша-ветка>-report.tsv | grep -v "^skip" | cut -f4 +$ cat <ваша-ветка>-report.tsv | grep -v "^skip" | cut -f4 | xargs rm +``` + + diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh new file mode 100755 index 00000000000..4a39f9d97c3 --- /dev/null +++ b/utils/simple-backport/backport.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -e + +branch="$1" +merge_base=$(git merge-base origin/master "origin/$branch") + +# Make lists of PRs that were merged into each branch. Use first parent here, or else +# we'll get weird things like seeing older master that was merged into a PR branch +# that was then merged into master. +git log "$merge_base..origin/master" --first-parent --oneline > master-log.txt +sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p" master-log.txt | sort -rn > master-prs.txt + +git log "$merge_base..origin/$branch" --first-parent --oneline > "$branch-log.txt" +sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p" "$branch-log.txt" | sort -rn > "$branch-prs.txt" + +# Find all master PRs that are not in branch by calculating differences of two PR lists. +grep -f "$branch-prs.txt" -F -x -v master-prs.txt > "$branch-diff-prs.txt" + +rm "$branch-report.tsv" ||: + +echo "$(wc -l < "$branch-diff-prs".txt) PRs differ between $branch and master." + +for pr in $(cat "$branch-diff-prs.txt") +do + # Download PR info from github. + file="pr$pr.json" + if ! [ -f "$file" ] + then + if ! curl -H "Authorization: token $GITHUB_TOKEN" \ + -sSf "https://api.github.com/repos/ClickHouse/ClickHouse/pulls/$pr" \ + > "$file" + then + >&2 cat "$file" + rm "$file" + break + fi + sleep 0.5 + fi + + if ! [ "$pr" == "$(jq -r .number "$file")" ] + then + >&2 echo "File $file is broken (no PR number)." + continue + fi + + action="skip" + + # First, check the changelog category. We port all bugfixes. + if jq -r .body "$file" | grep -i "^- bug[ -]*fix" > /dev/null + then + action="backport" + fi + + # Next, check the tag. They might override the decision. + matched_labels=() + for label in $(jq -r .labels[].name "$file") + do + label_action="" + case "$label" in + pr-must-backport | "v$branch-must-backport") + label_action="backport" + ;; + pr-no-backport | "v$branch-no-backport") + label_action="no-backport" + ;; + "v$branch-conflicts") + label_action="conflict" + ;; + "v$branch" | "v$branch-backported") + label_action="done" + ;; + esac + if [ "$label_action" != "" ] + then + action="$label_action" + matched_labels+=("$label") + fi + done + + # Show an error if there are conflicting labels. + if [ ${#matched_labels[@]} -gt 1 ] + then + >&2 echo "PR #$pr has conflicting labels: ${matched_labels[*]}" + continue + fi + + url="https://github.com/ClickHouse/ClickHouse/pull/$pr" + printf "%s\t%s\t%s\t%s\n" "$action" "$pr" "$url" "$file" >> "$branch-report.tsv" + if [ "$action" == "backport" ] + then + printf "%s\t%s\n" "$action" "$url" + fi +done + +wait From c097e1f9e5d766989666ffec371ff7dd0b75ca6a Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Sat, 11 Apr 2020 01:38:40 +0300 Subject: [PATCH 086/208] Update README.md --- utils/simple-backport/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/simple-backport/README.md b/utils/simple-backport/README.md index 89a0c6d6f22..89a9ce36934 100644 --- a/utils/simple-backport/README.md +++ b/utils/simple-backport/README.md @@ -2,7 +2,7 @@ Это упрощённый скрипт для бекпортирования. Он определяет, какие пулреквесты ещё не бекпортировали из мастера в указанную ветку. Запускать скрипт нужно из папки, где он лежит, указав ему название ветки. Он предполагает, что ваш апстримный remote называется origin. ``` -cd my-clickhouse-repo/simple-backport +cd my-clickhouse-repo/utils/simple-backport git fetch origin time GITHUB_TOKEN= ./backport.sh 20.1 ``` From 32f0789eaa98dd4c03554c054bdba4bcf19a1340 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Sat, 11 Apr 2020 01:41:47 +0300 Subject: [PATCH 087/208] Update README.md --- utils/simple-backport/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/simple-backport/README.md b/utils/simple-backport/README.md index 89a9ce36934..13378f93989 100644 --- a/utils/simple-backport/README.md +++ b/utils/simple-backport/README.md @@ -59,7 +59,7 @@ $ cat 20.1-report.tsv | cut -f1 | sort | uniq -c | sort -rn * v20.1-no-backport -- в ветку 20.1 бекпортировать не нужно. * pr-no-backport -- ни в какие ветки бекпортировать не нужно. * v20.1-conflicts -- при бекпорте в 20.1 произошёл конфликт. Такие пулреквесты скрипт пропускает, к ним можно потом вернуться. -* pr-should-backport -- нужно бекпортировать в поддерживаемые ветки. +* pr-must-backport -- нужно бекпортировать в поддерживаемые ветки. * v20.1-must-backport -- нужно бекпортировать в 20.1. From 7c57876ea4edbec8e6da7b0c4e207a807de468db Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Sat, 11 Apr 2020 03:00:33 +0300 Subject: [PATCH 088/208] simplified backport script --- utils/simple-backport/backport.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index 4a39f9d97c3..a0143108383 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -8,10 +8,15 @@ merge_base=$(git merge-base origin/master "origin/$branch") # we'll get weird things like seeing older master that was merged into a PR branch # that was then merged into master. git log "$merge_base..origin/master" --first-parent --oneline > master-log.txt -sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p" master-log.txt | sort -rn > master-prs.txt - git log "$merge_base..origin/$branch" --first-parent --oneline > "$branch-log.txt" -sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p" "$branch-log.txt" | sort -rn > "$branch-prs.txt" + +# Search for PR numbers in commit messages. First variant is normal merge, and second +# variant is squashed. +find_prs=(sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p; + s/^.*(#\([[:digit:]]\+\))$/\1/p") + +"${find_prs[@]}" master-log.txt | sort -rn > master-prs.txt +"${find_prs[@]}" "$branch-log.txt" | sort -rn > "$branch-prs.txt" # Find all master PRs that are not in branch by calculating differences of two PR lists. grep -f "$branch-prs.txt" -F -x -v master-prs.txt > "$branch-diff-prs.txt" @@ -39,7 +44,7 @@ do if ! [ "$pr" == "$(jq -r .number "$file")" ] then - >&2 echo "File $file is broken (no PR number)." + >&2 echo "Got wrong data for PR #$pr (please check and remove '$file')." continue fi @@ -92,4 +97,3 @@ do fi done -wait From 68fa04054aec7ef6314b6850f95f4adcb1fe823e Mon Sep 17 00:00:00 2001 From: Eugene Klimov Date: Sat, 11 Apr 2020 08:27:24 +0300 Subject: [PATCH 089/208] add in server settings and monitoring section (#10015) * add description for in server settings and monitoring section Signed-off-by: Slach * Update docs/en/operations/server_settings/settings.md Co-Authored-By: BayoNet * Update docs/en/operations/server_settings/settings.md Co-Authored-By: BayoNet * Update docs/en/operations/server_settings/settings.md Co-Authored-By: BayoNet * Update docs/en/operations/server_settings/settings.md Co-Authored-By: BayoNet * Update docs/en/operations/server_settings/settings.md Co-Authored-By: BayoNet * Update docs/en/operations/server_settings/settings.md Co-Authored-By: BayoNet * sync russian description with english Signed-off-by: Slach * Update docs/ru/operations/server_settings/settings.md * sync russian description with english Signed-off-by: Slach Co-authored-by: BayoNet Co-authored-by: Ilya Yatsishin <2159081+qoega@users.noreply.github.com> --- docs/en/operations/monitoring.md | 2 ++ .../settings.md | 24 +++++++++++++++++++ docs/ru/operations/monitoring.md | 2 ++ .../settings.md | 24 +++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/docs/en/operations/monitoring.md b/docs/en/operations/monitoring.md index 363e9cc4bff..dee1255569b 100644 --- a/docs/en/operations/monitoring.md +++ b/docs/en/operations/monitoring.md @@ -37,6 +37,8 @@ You can find metrics in the [system.metrics](../operations/system_tables.md#syst You can configure ClickHouse to export metrics to [Graphite](https://github.com/graphite-project). See the [Graphite section](server_configuration_parameters/settings.md#server_configuration_parameters-graphite) in the ClickHouse server configuration file. Before configuring export of metrics, you should set up Graphite by following their official [guide](https://graphite.readthedocs.io/en/latest/install.html). +You can configure ClickHouse to export metrics to [Prometheus](https://prometheus.io). See the [Prometheus section](server_configuration_parameters/settings.md#server_configuration_parameters-prometheus) in the ClickHouse server configuration file. Before configuring export of metrics, you should set up Prometheus by following their official [guide](https://prometheus.io/docs/prometheus/latest/installation/). + Additionally, you can monitor server availability through the HTTP API. Send the `HTTP GET` request to `/ping`. If the server is available, it responds with `200 OK`. To monitor servers in a cluster configuration, you should set the [max\_replica\_delay\_for\_distributed\_queries](settings/settings.md#settings-max_replica_delay_for_distributed_queries) parameter and use the HTTP resource `/replicas_status`. A request to `/replicas_status` returns `200 OK` if the replica is available and is not delayed behind the other replicas. If a replica is delayed, it returns `503 HTTP_SERVICE_UNAVAILABLE` with information about the gap. diff --git a/docs/en/operations/server_configuration_parameters/settings.md b/docs/en/operations/server_configuration_parameters/settings.md index 85744a039f4..02c00fababf 100644 --- a/docs/en/operations/server_configuration_parameters/settings.md +++ b/docs/en/operations/server_configuration_parameters/settings.md @@ -536,6 +536,30 @@ The path to the directory containing data. /var/lib/clickhouse/ ``` +## prometheus {#server_configuration_parameters-prometheus} + +Exposing metrics data for scraping from [Prometheus](https://prometheus.io). + +Settings: + +- `endpoint` – HTTP endpoint for scraping metrics by prometheus server. Start from '/'. +- `port` – Port for `endpoint`. +- `metrics` – Flag that sets to expose metrics from the [system.metrics](../system_tables.md#system_tables-metrics) table. +- `events` – Flag that sets to expose metrics from the [system.events](../system_tables.md#system_tables-events) table. +- `asynchronous_metrics` – Flag that sets to expose current metrics values from the [system.asynchronous\_metrics](../system_tables.md#system_tables-asynchronous_metrics) table. + +**Example** + +``` xml + + /metrics + 8001 + true + true + true + +``` + ## query\_log {#server_configuration_parameters-query-log} Setting for logging queries received with the [log\_queries=1](../settings/settings.md) setting. diff --git a/docs/ru/operations/monitoring.md b/docs/ru/operations/monitoring.md index 469d712376b..2629a4da931 100644 --- a/docs/ru/operations/monitoring.md +++ b/docs/ru/operations/monitoring.md @@ -32,6 +32,8 @@ ClickHouse собирает: Можно настроить экспорт метрик из ClickHouse в [Graphite](https://github.com/graphite-project). Смотрите секцию [graphite](server_configuration_parameters/settings.md#server_configuration_parameters-graphite) конфигурационного файла ClickHouse. Перед настройкой экспорта метрик необходимо настроить Graphite, как указано в [официальном руководстве](https://graphite.readthedocs.io/en/latest/install.html). +Можно настроить экспорт метрик из ClickHouse в [Prometheus](https://prometheus.io). Смотрите [prometheus](server_configuration_parameters/settings.md#server_configuration_parameters-prometheus) конфигурационного файла ClickHouse. Перед настройкой экспорта метрик необходимо настроить Prometheus, как указано в [официальном руководстве](https://prometheus.io/docs/prometheus/latest/installation/). + Также, можно отслеживать доступность сервера через HTTP API. Отправьте `HTTP GET` к ресурсу `/ping`. Если сервер доступен, он отвечает `200 OK`. Для мониторинга серверов в кластерной конфигурации необходимо установить параметр [max\_replica\_delay\_for\_distributed\_queries](settings/settings.md#settings-max_replica_delay_for_distributed_queries) и использовать HTTP ресурс `/replicas_status`. Если реплика доступна и не отстаёт от других реплик, то запрос к `/replicas_status` возвращает `200 OK`. Если реплика отстаёт, то запрос возвращает `503 HTTP_SERVICE_UNAVAILABLE`, включая информацию о размере отставания. diff --git a/docs/ru/operations/server_configuration_parameters/settings.md b/docs/ru/operations/server_configuration_parameters/settings.md index 16f00a82016..618bb9764ad 100644 --- a/docs/ru/operations/server_configuration_parameters/settings.md +++ b/docs/ru/operations/server_configuration_parameters/settings.md @@ -524,6 +524,30 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat /var/lib/clickhouse/ ``` +## prometheus {#server_configuration_parameters-prometheus} + +Опубликовать данные о метриках, для сбора с помощью системы мониторинга [Prometheus](https://prometheus.io). + +Настройки: + +- `endpoint` – путь по которому будет осуществляться экспорт данных метрик по HTTP протоколу для сбора с помощью prometheus. Должен начинаться с '/'. +- `port` – порт по которому будет доступен endpoint для сбора метрик. +- `metrics` – флаг для экспорта текущих значений метрик из таблицы [system.metrics](../system_tables.md#system_tables-metrics). +- `events` – флаг для экспорта текущих значений метрик из таблицы [system.events](../system_tables.md#system_tables-events). +- `asynchronous_metrics` – флаг для экспорта текущих значений значения метрик из таблицы [system.asynchronous\_metrics](../system_tables.md#system_tables-asynchronous_metrics). + +**Пример** + +``` xml + + /metrics + 8001 + true + true + true + +``` + ## query\_log {#server_configuration_parameters-query-log} Настройка логирования запросов, принятых с настройкой [log\_queries=1](../settings/settings.md). From e0c972448ea92bf77d41ac0b53e139185115e1ec Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sat, 11 Apr 2020 13:25:53 +0300 Subject: [PATCH 090/208] Cover SHOW CREATE TABLE from database with Dictionary ENGINE --- ...how_create_table_from_dictionary.reference | 6 ++++++ ...1225_show_create_table_from_dictionary.sql | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 tests/queries/0_stateless/01225_show_create_table_from_dictionary.reference create mode 100644 tests/queries/0_stateless/01225_show_create_table_from_dictionary.sql diff --git a/tests/queries/0_stateless/01225_show_create_table_from_dictionary.reference b/tests/queries/0_stateless/01225_show_create_table_from_dictionary.reference new file mode 100644 index 00000000000..14ddc093143 --- /dev/null +++ b/tests/queries/0_stateless/01225_show_create_table_from_dictionary.reference @@ -0,0 +1,6 @@ +CREATE TABLE dict_db_01225_dictionary.`dict_db_01225.dict` +( + `key` UInt64, + `val` UInt64 +) +ENGINE = Dictionary(`dict_db_01225.dict`) diff --git a/tests/queries/0_stateless/01225_show_create_table_from_dictionary.sql b/tests/queries/0_stateless/01225_show_create_table_from_dictionary.sql new file mode 100644 index 00000000000..7550d5292d0 --- /dev/null +++ b/tests/queries/0_stateless/01225_show_create_table_from_dictionary.sql @@ -0,0 +1,21 @@ +DROP DATABASE IF EXISTS dict_db_01225; +DROP DATABASE IF EXISTS dict_db_01225_dictionary; +CREATE DATABASE dict_db_01225; +CREATE DATABASE dict_db_01225_dictionary Engine=Dictionary; + +CREATE TABLE dict_db_01225.dict_data (key UInt64, val UInt64) Engine=Memory(); +CREATE DICTIONARY dict_db_01225.dict +( + key UInt64 DEFAULT 0, + val UInt64 DEFAULT 10 +) +PRIMARY KEY key +SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict_data' PASSWORD '' DB 'dict_db_01225')) +LIFETIME(MIN 0 MAX 0) +LAYOUT(FLAT()); + +SHOW CREATE TABLE dict_db_01225_dictionary.`dict_db_01225.dict` FORMAT TSVRaw; +SHOW CREATE TABLE dict_db_01225_dictionary.`dict_db_01225.no_such_dict`; -- { serverError 36; } + +DROP DATABASE dict_db_01225; +DROP DATABASE dict_db_01225_dictionary; From 55a143d1a559a4cdbf915da15972500b1f28a7eb Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 10 Apr 2020 01:32:59 +0300 Subject: [PATCH 091/208] Avoid superfluous dictionaries load (system.tables, SHOW CREATE TABLE) This patch avoids loading dictionaries for: - SELECT * FROM system.tables (used by clickhouse-client for completion) - SHOW CREATE TABLE some_dict But the dictionary will still be loaded on: - SHOW CREATE TABLE some_dict (from the database with Dictionary engine) --- src/Databases/DatabaseDictionary.cpp | 4 +-- src/Databases/DatabaseWithDictionaries.cpp | 36 ++++++++++++++++--- src/Databases/DatabaseWithDictionaries.h | 6 +++- src/Interpreters/ExternalDictionariesLoader.h | 7 ++-- ...01224_no_superfluous_dict_reload.reference | 19 ++++++++++ .../01224_no_superfluous_dict_reload.sql | 32 +++++++++++++++++ 6 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 tests/queries/0_stateless/01224_no_superfluous_dict_reload.reference create mode 100644 tests/queries/0_stateless/01224_no_superfluous_dict_reload.sql diff --git a/src/Databases/DatabaseDictionary.cpp b/src/Databases/DatabaseDictionary.cpp index 006eb1656a2..9e7788bf846 100644 --- a/src/Databases/DatabaseDictionary.cpp +++ b/src/Databases/DatabaseDictionary.cpp @@ -64,7 +64,7 @@ StoragePtr DatabaseDictionary::tryGetTable( const Context & context, const String & table_name) const { - auto dict_ptr = context.getExternalDictionariesLoader().tryGetDictionary(table_name); + auto dict_ptr = context.getExternalDictionariesLoader().tryGetDictionary(table_name, true /*load*/); if (dict_ptr) { const DictionaryStructure & dictionary_structure = dict_ptr->getStructure(); @@ -94,7 +94,7 @@ ASTPtr DatabaseDictionary::getCreateTableQueryImpl(const Context & context, const auto & dictionaries = context.getExternalDictionariesLoader(); auto dictionary = throw_on_error ? dictionaries.getDictionary(table_name) - : dictionaries.tryGetDictionary(table_name); + : dictionaries.tryGetDictionary(table_name, true /*load*/); if (!dictionary) return {}; diff --git a/src/Databases/DatabaseWithDictionaries.cpp b/src/Databases/DatabaseWithDictionaries.cpp index e849962aae3..6673fdf8075 100644 --- a/src/Databases/DatabaseWithDictionaries.cpp +++ b/src/Databases/DatabaseWithDictionaries.cpp @@ -26,6 +26,8 @@ namespace ErrorCodes extern const int TABLE_ALREADY_EXISTS; extern const int UNKNOWN_TABLE; extern const int DICTIONARY_ALREADY_EXISTS; + extern const int FILE_DOESNT_EXIST; + extern const int CANNOT_GET_CREATE_TABLE_QUERY; } @@ -165,7 +167,7 @@ void DatabaseWithDictionaries::removeDictionary(const Context & context, const S } } -StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const String & table_name) const +StoragePtr DatabaseWithDictionaries::tryGetTableImpl(const Context & context, const String & table_name, bool load) const { if (auto table_ptr = DatabaseWithOwnTablesBase::tryGetTable(context, table_name)) return table_ptr; @@ -173,10 +175,34 @@ StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const if (isDictionaryExist(context, table_name)) /// We don't need lock database here, because database doesn't store dictionary itself /// just metadata - return getDictionaryStorage(context, table_name); + return getDictionaryStorage(context, table_name, load); return {}; } +StoragePtr DatabaseWithDictionaries::tryGetTable(const Context & context, const String & table_name) const +{ + return tryGetTableImpl(context, table_name, true /*load*/); +} + +ASTPtr DatabaseWithDictionaries::getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const +{ + ASTPtr ast; + bool has_table = tryGetTableImpl(context, table_name, false /*load*/) != nullptr; + auto table_metadata_path = getObjectMetadataPath(table_name); + try + { + ast = getCreateQueryFromMetadata(context, table_metadata_path, throw_on_error); + } + catch (const Exception & e) + { + if (!has_table && e.code() == ErrorCodes::FILE_DOESNT_EXIST && throw_on_error) + throw Exception{"Table " + backQuote(table_name) + " doesn't exist", + ErrorCodes::CANNOT_GET_CREATE_TABLE_QUERY}; + else if (throw_on_error) + throw; + } + return ast; +} DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTablesIterator( const Context & context, const FilterByNameFunction & filter_by_dictionary_name) @@ -195,7 +221,7 @@ DatabaseTablesIteratorPtr DatabaseWithDictionaries::getTablesWithDictionaryTable while (dictionaries_it && dictionaries_it->isValid()) { auto table_name = dictionaries_it->name(); - auto table_ptr = getDictionaryStorage(context, table_name); + auto table_ptr = getDictionaryStorage(context, table_name, false /*load*/); if (table_ptr) result.emplace(table_name, table_ptr); dictionaries_it->next(); @@ -223,11 +249,11 @@ bool DatabaseWithDictionaries::isDictionaryExist(const Context & /*context*/, co return dictionaries.find(dictionary_name) != dictionaries.end(); } -StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const Context & context, const String & table_name) const +StoragePtr DatabaseWithDictionaries::getDictionaryStorage(const Context & context, const String & table_name, bool load) const { auto dict_name = database_name + "." + table_name; const auto & external_loader = context.getExternalDictionariesLoader(); - auto dict_ptr = external_loader.tryGetDictionary(dict_name); + auto dict_ptr = external_loader.tryGetDictionary(dict_name, load); if (dict_ptr) { const DictionaryStructure & dictionary_structure = dict_ptr->getStructure(); diff --git a/src/Databases/DatabaseWithDictionaries.h b/src/Databases/DatabaseWithDictionaries.h index e47ab6206c5..50e4dca671f 100644 --- a/src/Databases/DatabaseWithDictionaries.h +++ b/src/Databases/DatabaseWithDictionaries.h @@ -20,6 +20,8 @@ public: StoragePtr tryGetTable(const Context & context, const String & table_name) const override; + ASTPtr getCreateTableQueryImpl(const Context & context, const String & table_name, bool throw_on_error) const override; + DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name) override; DatabaseDictionariesIteratorPtr getDictionariesIterator(const Context & context, const FilterByNameFunction & filter_by_dictionary_name) override; @@ -37,7 +39,7 @@ protected: void attachToExternalDictionariesLoader(Context & context); void detachFromExternalDictionariesLoader(); - StoragePtr getDictionaryStorage(const Context & context, const String & table_name) const; + StoragePtr getDictionaryStorage(const Context & context, const String & table_name, bool load) const; ASTPtr getCreateDictionaryQueryImpl(const Context & context, const String & dictionary_name, @@ -45,6 +47,8 @@ protected: private: ext::scope_guard database_as_config_repo_for_external_loader; + + StoragePtr tryGetTableImpl(const Context & context, const String & table_name, bool load) const; }; } diff --git a/src/Interpreters/ExternalDictionariesLoader.h b/src/Interpreters/ExternalDictionariesLoader.h index 68913ffa166..4a54a9963e7 100644 --- a/src/Interpreters/ExternalDictionariesLoader.h +++ b/src/Interpreters/ExternalDictionariesLoader.h @@ -23,9 +23,12 @@ public: return std::static_pointer_cast(load(name)); } - DictPtr tryGetDictionary(const std::string & name) const + DictPtr tryGetDictionary(const std::string & name, bool load) const { - return std::static_pointer_cast(tryLoad(name)); + if (load) + return std::static_pointer_cast(tryLoad(name)); + else + return std::static_pointer_cast(getCurrentLoadResult(name).object); } static void resetAll(); diff --git a/tests/queries/0_stateless/01224_no_superfluous_dict_reload.reference b/tests/queries/0_stateless/01224_no_superfluous_dict_reload.reference new file mode 100644 index 00000000000..5321624de02 --- /dev/null +++ b/tests/queries/0_stateless/01224_no_superfluous_dict_reload.reference @@ -0,0 +1,19 @@ +NOT_LOADED +NOT_LOADED +CREATE DICTIONARY dict_db_01224.dict +( + `key` UInt64 DEFAULT 0, + `val` UInt64 DEFAULT 10 +) +PRIMARY KEY key +SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict_data' PASSWORD '' DB 'dict_db_01224')) +LIFETIME(MIN 0 MAX 0) +LAYOUT(FLAT()) +NOT_LOADED +CREATE TABLE dict_db_01224_dictionary.`dict_db_01224.dict` +( + `key` UInt64, + `val` UInt64 +) +ENGINE = Dictionary(`dict_db_01224.dict`) +LOADED diff --git a/tests/queries/0_stateless/01224_no_superfluous_dict_reload.sql b/tests/queries/0_stateless/01224_no_superfluous_dict_reload.sql new file mode 100644 index 00000000000..a6eed6f072c --- /dev/null +++ b/tests/queries/0_stateless/01224_no_superfluous_dict_reload.sql @@ -0,0 +1,32 @@ +DROP DATABASE IF EXISTS dict_db_01224; +DROP DATABASE IF EXISTS dict_db_01224_dictionary; +CREATE DATABASE dict_db_01224; + +CREATE TABLE dict_db_01224.dict_data (key UInt64, val UInt64) Engine=Memory(); +CREATE DICTIONARY dict_db_01224.dict +( + key UInt64 DEFAULT 0, + val UInt64 DEFAULT 10 +) +PRIMARY KEY key +SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'dict_data' PASSWORD '' DB 'dict_db_01224')) +LIFETIME(MIN 0 MAX 0) +LAYOUT(FLAT()); + +SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict'; + +SELECT * FROM system.tables FORMAT Null; +SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict'; + +SHOW CREATE TABLE dict_db_01224.dict FORMAT TSVRaw; +SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict'; + +CREATE DATABASE dict_db_01224_dictionary Engine=Dictionary; +SHOW CREATE TABLE dict_db_01224_dictionary.`dict_db_01224.dict` FORMAT TSVRaw; +SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict'; + +DROP DICTIONARY dict_db_01224.dict; +SELECT status FROM system.dictionaries WHERE database = 'dict_db_01224' AND name = 'dict'; + +DROP DATABASE dict_db_01224; +DROP DATABASE dict_db_01224_dictionary; From 67235834b3cb40ccc457f659ba7c23a6891c8765 Mon Sep 17 00:00:00 2001 From: Ivan <5627721+abyss7@users.noreply.github.com> Date: Sat, 11 Apr 2020 14:14:01 +0300 Subject: [PATCH 092/208] Update libdivide to v3.0 (#10169) --- contrib/libdivide/libdivide.h | 2807 +++++++++++++--------- src/Functions/intDiv.cpp | 7 +- src/Functions/modulo.cpp | 4 +- src/Interpreters/createBlockSelector.cpp | 4 +- 4 files changed, 1732 insertions(+), 1090 deletions(-) diff --git a/contrib/libdivide/libdivide.h b/contrib/libdivide/libdivide.h index eaeaec7db6b..a153e7f9c5e 100644 --- a/contrib/libdivide/libdivide.h +++ b/contrib/libdivide/libdivide.h @@ -1,117 +1,106 @@ -/* libdivide.h - Copyright 2010 ridiculous_fish -*/ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wold-style-cast" +// libdivide.h - Optimized integer division +// https://libdivide.com +// +// Copyright (C) 2010 - 2019 ridiculous_fish, +// Copyright (C) 2016 - 2019 Kim Walisch, +// +// libdivide is dual-licensed under the Boost or zlib licenses. +// You may use libdivide under the terms of either of these. +// See LICENSE.txt for more details. -#if defined(_WIN32) || defined(WIN32) -#define LIBDIVIDE_WINDOWS 1 -#endif +#ifndef LIBDIVIDE_H +#define LIBDIVIDE_H -#if defined(_MSC_VER) -#define LIBDIVIDE_VC 1 -#endif +#define LIBDIVIDE_VERSION "3.0" +#define LIBDIVIDE_VERSION_MAJOR 3 +#define LIBDIVIDE_VERSION_MINOR 0 -#ifdef __cplusplus -#include -#include -#include -#else -#include -#include -#include -#endif - -#if ! LIBDIVIDE_HAS_STDINT_TYPES && (! LIBDIVIDE_VC || _MSC_VER >= 1600) -/* Only Visual C++ 2010 and later include stdint.h */ #include -#define LIBDIVIDE_HAS_STDINT_TYPES 1 + +#if defined(__cplusplus) + #include + #include + #include +#else + #include + #include #endif -#if ! LIBDIVIDE_HAS_STDINT_TYPES -typedef __int32 int32_t; -typedef unsigned __int32 uint32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -typedef __int8 int8_t; -typedef unsigned __int8 uint8_t; -#endif - -#if LIBDIVIDE_USE_SSE2 +#if defined(LIBDIVIDE_AVX512) + #include +#elif defined(LIBDIVIDE_AVX2) + #include +#elif defined(LIBDIVIDE_SSE2) #include #endif -#if LIBDIVIDE_VC +#if defined(_MSC_VER) #include + // disable warning C4146: unary minus operator applied + // to unsigned type, result still unsigned + #pragma warning(disable: 4146) + #define LIBDIVIDE_VC #endif -#ifndef __has_builtin -#define __has_builtin(x) 0 // Compatibility with non-clang compilers. +#if !defined(__has_builtin) + #define __has_builtin(x) 0 #endif -#ifdef __ICC -#define HAS_INT128_T 0 -#else -#define HAS_INT128_T __LP64__ +#if defined(__SIZEOF_INT128__) + #define HAS_INT128_T + // clang-cl on Windows does not yet support 128-bit division + #if !(defined(__clang__) && defined(LIBDIVIDE_VC)) + #define HAS_INT128_DIV + #endif #endif -#if defined(__x86_64__) || defined(_WIN64) || defined(_M_64) -#define LIBDIVIDE_IS_X86_64 1 +#if defined(__x86_64__) || defined(_M_X64) + #define LIBDIVIDE_X86_64 #endif #if defined(__i386__) -#define LIBDIVIDE_IS_i386 1 + #define LIBDIVIDE_i386 #endif -#if __GNUC__ || __clang__ -#define LIBDIVIDE_GCC_STYLE_ASM 1 +#if defined(__GNUC__) || defined(__clang__) + #define LIBDIVIDE_GCC_STYLE_ASM #endif +#if defined(__cplusplus) || defined(LIBDIVIDE_VC) + #define LIBDIVIDE_FUNCTION __FUNCTION__ +#else + #define LIBDIVIDE_FUNCTION __func__ +#endif -/* libdivide may use the pmuldq (vector signed 32x32->64 mult instruction) which is in SSE 4.1. However, signed multiplication can be emulated efficiently with unsigned multiplication, and SSE 4.1 is currently rare, so it is OK to not turn this on */ -#ifdef LIBDIVIDE_USE_SSE4_1 -#include +#define LIBDIVIDE_ERROR(msg) \ + do { \ + fprintf(stderr, "libdivide.h:%d: %s(): Error: %s\n", \ + __LINE__, LIBDIVIDE_FUNCTION, msg); \ + exit(-1); \ + } while (0) + +#if defined(LIBDIVIDE_ASSERTIONS_ON) + #define LIBDIVIDE_ASSERT(x) \ + do { \ + if (!(x)) { \ + fprintf(stderr, "libdivide.h:%d: %s(): Assertion failed: %s\n", \ + __LINE__, LIBDIVIDE_FUNCTION, #x); \ + exit(-1); \ + } \ + } while (0) +#else + #define LIBDIVIDE_ASSERT(x) #endif #ifdef __cplusplus -/* We place libdivide within the libdivide namespace, and that goes in an anonymous namespace so that the functions are only visible to files that #include this header and don't get external linkage. At least that's the theory. */ -namespace { namespace libdivide { #endif -/* Explanation of "more" field: bit 6 is whether to use shift path. If we are using the shift path, bit 7 is whether the divisor is negative in the signed case; in the unsigned case it is 0. Bits 0-4 is shift value (for shift path or mult path). In 32 bit case, bit 5 is always 0. We use bit 7 as the "negative divisor indicator" so that we can use sign extension to efficiently go to a full-width -1. - - -u32: [0-4] shift value - [5] ignored - [6] add indicator - [7] shift path - -s32: [0-4] shift value - [5] shift path - [6] add indicator - [7] indicates negative divisor - -u64: [0-5] shift value - [6] add indicator - [7] shift path - -s64: [0-5] shift value - [6] add indicator - [7] indicates negative divisor - magic number of 0 indicates shift path (we ran out of bits!) -*/ - -enum { - LIBDIVIDE_32_SHIFT_MASK = 0x1F, - LIBDIVIDE_64_SHIFT_MASK = 0x3F, - LIBDIVIDE_ADD_MARKER = 0x40, - LIBDIVIDE_U32_SHIFT_PATH = 0x80, - LIBDIVIDE_U64_SHIFT_PATH = 0x80, - LIBDIVIDE_S32_SHIFT_PATH = 0x20, - LIBDIVIDE_NEGATIVE_DIVISOR = 0x80 -}; - +// pack divider structs to prevent compilers from padding. +// This reduces memory usage by up to 43% when using a large +// array of libdivide dividers and improves performance +// by up to 10% because of reduced memory bandwidth. +#pragma pack(push, 1) struct libdivide_u32_t { uint32_t magic; @@ -133,497 +122,446 @@ struct libdivide_s64_t { uint8_t more; }; +struct libdivide_u32_branchfree_t { + uint32_t magic; + uint8_t more; +}; +struct libdivide_s32_branchfree_t { + int32_t magic; + uint8_t more; +}; -#ifndef LIBDIVIDE_API - #ifdef __cplusplus - /* In C++, we don't want our public functions to be static, because they are arguments to templates and static functions can't do that. They get internal linkage through virtue of the anonymous namespace. In C, they should be static. */ - #define LIBDIVIDE_API - #else - #define LIBDIVIDE_API static - #endif -#endif +struct libdivide_u64_branchfree_t { + uint64_t magic; + uint8_t more; +}; -#ifdef __APPLE__ -typedef signed long Int64; -typedef unsigned long UInt64; -#endif +struct libdivide_s64_branchfree_t { + int64_t magic; + uint8_t more; +}; -LIBDIVIDE_API struct libdivide_s32_t libdivide_s32_gen(int32_t y); -LIBDIVIDE_API struct libdivide_u32_t libdivide_u32_gen(uint32_t y); -LIBDIVIDE_API struct libdivide_s64_t libdivide_s64_gen(int64_t y); -LIBDIVIDE_API struct libdivide_u64_t libdivide_u64_gen(uint64_t y); -#if defined(__APPLE__) && defined(__cplusplus) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -LIBDIVIDE_API struct libdivide_s64_t libdivide_s64_gen(Int64 y) { return libdivide_s64_gen(int64_t(y)); }; -LIBDIVIDE_API struct libdivide_u64_t libdivide_u64_gen(UInt64 y) { return libdivide_u64_gen(uint64_t(y)); }; -#pragma GCC diagnostic pop -#endif +#pragma pack(pop) -LIBDIVIDE_API int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom); -LIBDIVIDE_API uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom); -LIBDIVIDE_API int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom); -LIBDIVIDE_API uint64_t libdivide_u64_do(uint64_t y, const struct libdivide_u64_t *denom); -#if defined(__APPLE__) && defined(__cplusplus) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -LIBDIVIDE_API Int64 libdivide_s64_do(Int64 numer, const struct libdivide_s64_t *denom) { return Int64(libdivide_s64_do(int64_t(numer), denom)); }; -LIBDIVIDE_API UInt64 libdivide_u64_do(UInt64 y, const struct libdivide_u64_t *denom) { return UInt64(libdivide_u64_do(uint64_t(y), denom)); }; -#pragma GCC diagnostic pop -#endif +// Explanation of the "more" field: +// +// * Bits 0-5 is the shift value (for shift path or mult path). +// * Bit 6 is the add indicator for mult path. +// * Bit 7 is set if the divisor is negative. We use bit 7 as the negative +// divisor indicator so that we can efficiently use sign extension to +// create a bitmask with all bits set to 1 (if the divisor is negative) +// or 0 (if the divisor is positive). +// +// u32: [0-4] shift value +// [5] ignored +// [6] add indicator +// magic number of 0 indicates shift path +// +// s32: [0-4] shift value +// [5] ignored +// [6] add indicator +// [7] indicates negative divisor +// magic number of 0 indicates shift path +// +// u64: [0-5] shift value +// [6] add indicator +// magic number of 0 indicates shift path +// +// s64: [0-5] shift value +// [6] add indicator +// [7] indicates negative divisor +// magic number of 0 indicates shift path +// +// In s32 and s64 branchfree modes, the magic number is negated according to +// whether the divisor is negated. In branchfree strategy, it is not negated. -LIBDIVIDE_API int libdivide_u32_get_algorithm(const struct libdivide_u32_t *denom); -LIBDIVIDE_API uint32_t libdivide_u32_do_alg0(uint32_t numer, const struct libdivide_u32_t *denom); -LIBDIVIDE_API uint32_t libdivide_u32_do_alg1(uint32_t numer, const struct libdivide_u32_t *denom); -LIBDIVIDE_API uint32_t libdivide_u32_do_alg2(uint32_t numer, const struct libdivide_u32_t *denom); +enum { + LIBDIVIDE_32_SHIFT_MASK = 0x1F, + LIBDIVIDE_64_SHIFT_MASK = 0x3F, + LIBDIVIDE_ADD_MARKER = 0x40, + LIBDIVIDE_NEGATIVE_DIVISOR = 0x80 +}; -LIBDIVIDE_API int libdivide_u64_get_algorithm(const struct libdivide_u64_t *denom); -LIBDIVIDE_API uint64_t libdivide_u64_do_alg0(uint64_t numer, const struct libdivide_u64_t *denom); -LIBDIVIDE_API uint64_t libdivide_u64_do_alg1(uint64_t numer, const struct libdivide_u64_t *denom); -LIBDIVIDE_API uint64_t libdivide_u64_do_alg2(uint64_t numer, const struct libdivide_u64_t *denom); -#if defined(__APPLE__) && defined(__cplusplus) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -LIBDIVIDE_API UInt64 libdivide_u64_do_alg0(UInt64 numer, const struct libdivide_u64_t *denom) { return UInt64(libdivide_u64_do_alg0(uint64_t(numer), denom)); } -LIBDIVIDE_API UInt64 libdivide_u64_do_alg1(UInt64 numer, const struct libdivide_u64_t *denom) { return UInt64(libdivide_u64_do_alg1(uint64_t(numer), denom)); } -LIBDIVIDE_API UInt64 libdivide_u64_do_alg2(UInt64 numer, const struct libdivide_u64_t *denom) { return UInt64(libdivide_u64_do_alg2(uint64_t(numer), denom)); } -#pragma GCC diagnostic pop -#endif +static inline struct libdivide_s32_t libdivide_s32_gen(int32_t d); +static inline struct libdivide_u32_t libdivide_u32_gen(uint32_t d); +static inline struct libdivide_s64_t libdivide_s64_gen(int64_t d); +static inline struct libdivide_u64_t libdivide_u64_gen(uint64_t d); -LIBDIVIDE_API int libdivide_s32_get_algorithm(const struct libdivide_s32_t *denom); -LIBDIVIDE_API int32_t libdivide_s32_do_alg0(int32_t numer, const struct libdivide_s32_t *denom); -LIBDIVIDE_API int32_t libdivide_s32_do_alg1(int32_t numer, const struct libdivide_s32_t *denom); -LIBDIVIDE_API int32_t libdivide_s32_do_alg2(int32_t numer, const struct libdivide_s32_t *denom); -LIBDIVIDE_API int32_t libdivide_s32_do_alg3(int32_t numer, const struct libdivide_s32_t *denom); -LIBDIVIDE_API int32_t libdivide_s32_do_alg4(int32_t numer, const struct libdivide_s32_t *denom); +static inline struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d); +static inline struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d); +static inline struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d); +static inline struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d); -LIBDIVIDE_API int libdivide_s64_get_algorithm(const struct libdivide_s64_t *denom); -LIBDIVIDE_API int64_t libdivide_s64_do_alg0(int64_t numer, const struct libdivide_s64_t *denom); -LIBDIVIDE_API int64_t libdivide_s64_do_alg1(int64_t numer, const struct libdivide_s64_t *denom); -LIBDIVIDE_API int64_t libdivide_s64_do_alg2(int64_t numer, const struct libdivide_s64_t *denom); -LIBDIVIDE_API int64_t libdivide_s64_do_alg3(int64_t numer, const struct libdivide_s64_t *denom); -LIBDIVIDE_API int64_t libdivide_s64_do_alg4(int64_t numer, const struct libdivide_s64_t *denom); -#if defined(__APPLE__) && defined(__cplusplus) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-function" -LIBDIVIDE_API Int64 libdivide_s64_do_alg0(Int64 numer, const struct libdivide_s64_t *denom) { return Int64(libdivide_s64_do_alg0(int64_t(numer), denom)); } -LIBDIVIDE_API Int64 libdivide_s64_do_alg1(Int64 numer, const struct libdivide_s64_t *denom) { return Int64(libdivide_s64_do_alg1(int64_t(numer), denom)); } -LIBDIVIDE_API Int64 libdivide_s64_do_alg2(Int64 numer, const struct libdivide_s64_t *denom) { return Int64(libdivide_s64_do_alg2(int64_t(numer), denom)); } -LIBDIVIDE_API Int64 libdivide_s64_do_alg3(Int64 numer, const struct libdivide_s64_t *denom) { return Int64(libdivide_s64_do_alg3(int64_t(numer), denom)); } -LIBDIVIDE_API Int64 libdivide_s64_do_alg4(Int64 numer, const struct libdivide_s64_t *denom) { return Int64(libdivide_s64_do_alg4(int64_t(numer), denom)); } -#pragma GCC diagnostic pop -#endif +static inline int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom); +static inline uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom); +static inline int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom); +static inline uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom); +static inline int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom); +static inline uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom); +static inline int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom); +static inline uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom); -#if LIBDIVIDE_USE_SSE2 -LIBDIVIDE_API __m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t * denom); -LIBDIVIDE_API __m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t * denom); -LIBDIVIDE_API __m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t * denom); -LIBDIVIDE_API __m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t * denom); - -LIBDIVIDE_API __m128i libdivide_u32_do_vector_alg0(__m128i numers, const struct libdivide_u32_t * denom); -LIBDIVIDE_API __m128i libdivide_u32_do_vector_alg1(__m128i numers, const struct libdivide_u32_t * denom); -LIBDIVIDE_API __m128i libdivide_u32_do_vector_alg2(__m128i numers, const struct libdivide_u32_t * denom); - -LIBDIVIDE_API __m128i libdivide_s32_do_vector_alg0(__m128i numers, const struct libdivide_s32_t * denom); -LIBDIVIDE_API __m128i libdivide_s32_do_vector_alg1(__m128i numers, const struct libdivide_s32_t * denom); -LIBDIVIDE_API __m128i libdivide_s32_do_vector_alg2(__m128i numers, const struct libdivide_s32_t * denom); -LIBDIVIDE_API __m128i libdivide_s32_do_vector_alg3(__m128i numers, const struct libdivide_s32_t * denom); -LIBDIVIDE_API __m128i libdivide_s32_do_vector_alg4(__m128i numers, const struct libdivide_s32_t * denom); - -LIBDIVIDE_API __m128i libdivide_u64_do_vector_alg0(__m128i numers, const struct libdivide_u64_t * denom); -LIBDIVIDE_API __m128i libdivide_u64_do_vector_alg1(__m128i numers, const struct libdivide_u64_t * denom); -LIBDIVIDE_API __m128i libdivide_u64_do_vector_alg2(__m128i numers, const struct libdivide_u64_t * denom); - -LIBDIVIDE_API __m128i libdivide_s64_do_vector_alg0(__m128i numers, const struct libdivide_s64_t * denom); -LIBDIVIDE_API __m128i libdivide_s64_do_vector_alg1(__m128i numers, const struct libdivide_s64_t * denom); -LIBDIVIDE_API __m128i libdivide_s64_do_vector_alg2(__m128i numers, const struct libdivide_s64_t * denom); -LIBDIVIDE_API __m128i libdivide_s64_do_vector_alg3(__m128i numers, const struct libdivide_s64_t * denom); -LIBDIVIDE_API __m128i libdivide_s64_do_vector_alg4(__m128i numers, const struct libdivide_s64_t * denom); -#endif - +static inline int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom); +static inline uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom); +static inline int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom); +static inline uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom); +static inline int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom); +static inline uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom); +static inline int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom); +static inline uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom); //////// Internal Utility Functions -static inline uint32_t libdivide__mullhi_u32(uint32_t x, uint32_t y) { +static inline uint32_t libdivide_mullhi_u32(uint32_t x, uint32_t y) { uint64_t xl = x, yl = y; uint64_t rl = xl * yl; return (uint32_t)(rl >> 32); } -static uint64_t libdivide__mullhi_u64(uint64_t x, uint64_t y) { -#if HAS_INT128_T +static inline int32_t libdivide_mullhi_s32(int32_t x, int32_t y) { + int64_t xl = x, yl = y; + int64_t rl = xl * yl; + // needs to be arithmetic shift + return (int32_t)(rl >> 32); +} + +static inline uint64_t libdivide_mullhi_u64(uint64_t x, uint64_t y) { +#if defined(LIBDIVIDE_VC) && \ + defined(LIBDIVIDE_X86_64) + return __umulh(x, y); +#elif defined(HAS_INT128_T) __uint128_t xl = x, yl = y; __uint128_t rl = xl * yl; return (uint64_t)(rl >> 64); #else - //full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) - const uint32_t mask = 0xFFFFFFFF; - const uint32_t x0 = (uint32_t)(x & mask), x1 = (uint32_t)(x >> 32); - const uint32_t y0 = (uint32_t)(y & mask), y1 = (uint32_t)(y >> 32); - const uint32_t x0y0_hi = libdivide__mullhi_u32(x0, y0); - const uint64_t x0y1 = x0 * (uint64_t)y1; - const uint64_t x1y0 = x1 * (uint64_t)y0; - const uint64_t x1y1 = x1 * (uint64_t)y1; - + // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) + uint32_t mask = 0xFFFFFFFF; + uint32_t x0 = (uint32_t)(x & mask); + uint32_t x1 = (uint32_t)(x >> 32); + uint32_t y0 = (uint32_t)(y & mask); + uint32_t y1 = (uint32_t)(y >> 32); + uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0); + uint64_t x0y1 = x0 * (uint64_t)y1; + uint64_t x1y0 = x1 * (uint64_t)y0; + uint64_t x1y1 = x1 * (uint64_t)y1; uint64_t temp = x1y0 + x0y0_hi; - uint64_t temp_lo = temp & mask, temp_hi = temp >> 32; + uint64_t temp_lo = temp & mask; + uint64_t temp_hi = temp >> 32; + return x1y1 + temp_hi + ((temp_lo + x0y1) >> 32); #endif } -static inline int64_t libdivide__mullhi_s64(int64_t x, int64_t y) { -#if HAS_INT128_T +static inline int64_t libdivide_mullhi_s64(int64_t x, int64_t y) { +#if defined(LIBDIVIDE_VC) && \ + defined(LIBDIVIDE_X86_64) + return __mulh(x, y); +#elif defined(HAS_INT128_T) __int128_t xl = x, yl = y; __int128_t rl = xl * yl; return (int64_t)(rl >> 64); #else - //full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) - const uint32_t mask = 0xFFFFFFFF; - const uint32_t x0 = (uint32_t)(x & mask), y0 = (uint32_t)(y & mask); - const int32_t x1 = (int32_t)(x >> 32), y1 = (int32_t)(y >> 32); - const uint32_t x0y0_hi = libdivide__mullhi_u32(x0, y0); - const int64_t t = x1*(int64_t)y0 + x0y0_hi; - const int64_t w1 = x0*(int64_t)y1 + (t & mask); - return x1*(int64_t)y1 + (t >> 32) + (w1 >> 32); + // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) + uint32_t mask = 0xFFFFFFFF; + uint32_t x0 = (uint32_t)(x & mask); + uint32_t y0 = (uint32_t)(y & mask); + int32_t x1 = (int32_t)(x >> 32); + int32_t y1 = (int32_t)(y >> 32); + uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0); + int64_t t = x1 * (int64_t)y0 + x0y0_hi; + int64_t w1 = x0 * (int64_t)y1 + (t & mask); + + return x1 * (int64_t)y1 + (t >> 32) + (w1 >> 32); #endif } -#if LIBDIVIDE_USE_SSE2 - -static inline __m128i libdivide__u64_to_m128(uint64_t x) { -#if LIBDIVIDE_VC && ! _WIN64 - //64 bit windows doesn't seem to have an implementation of any of these load intrinsics, and 32 bit Visual C++ crashes - _declspec(align(16)) uint64_t temp[2] = {x, x}; - return _mm_load_si128((const __m128i*)temp); -#elif defined(__ICC) - uint64_t __attribute__((aligned(16))) temp[2] = {x,x}; - return _mm_load_si128((const __m128i*)temp); -#elif __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wc++11-narrowing" // narrowing from uint64_t (aka 'unsigned long') to 'long long' - // clang does not provide this intrinsic either - return (__m128i){x, x}; -#pragma clang diagnostic pop -#else - // everyone else gets it right - return _mm_set1_epi64x(x); -#endif -} - -static inline __m128i libdivide_get_FFFFFFFF00000000(void) { - //returns the same as _mm_set1_epi64(0xFFFFFFFF00000000ULL) without touching memory - __m128i result = _mm_set1_epi8(-1); //optimizes to pcmpeqd on OS X - return _mm_slli_epi64(result, 32); -} - -static inline __m128i libdivide_get_00000000FFFFFFFF(void) { - //returns the same as _mm_set1_epi64(0x00000000FFFFFFFFULL) without touching memory - __m128i result = _mm_set1_epi8(-1); //optimizes to pcmpeqd on OS X - result = _mm_srli_epi64(result, 32); - return result; -} - -#if __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wuninitialized" -#endif -static inline __m128i libdivide_get_0000FFFF(void) { - //returns the same as _mm_set1_epi32(0x0000FFFFULL) without touching memory - __m128i result; //we don't care what its contents are - result = _mm_cmpeq_epi8(result, result); //all 1s - result = _mm_srli_epi32(result, 16); - return result; -} -#if __clang__ -#pragma clang diagnostic pop -#endif - -/// This is a bug in gcc-8, _MM_SHUFFLE was forgotten, though in trunk it is ok https://github.com/gcc-mirror/gcc/blob/master/gcc/config/rs6000/xmmintrin.h#L61 -#if defined(__PPC__) -#ifndef _MM_SHUFFLE -#define _MM_SHUFFLE(w,x,y,z) (((w) << 6) | ((x) << 4) | ((y) << 2) | (z)) -#endif -#endif - -static inline __m128i libdivide_s64_signbits(__m128i v) { - //we want to compute v >> 63, that is, _mm_srai_epi64(v, 63). But there is no 64 bit shift right arithmetic instruction in SSE2. So we have to fake it by first duplicating the high 32 bit values, and then using a 32 bit shift. Another option would be to use _mm_srli_epi64(v, 63) and then subtract that from 0, but that approach appears to be substantially slower for unknown reasons - __m128i hiBitsDuped = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1)); - __m128i signBits = _mm_srai_epi32(hiBitsDuped, 31); - return signBits; -} - -/* Returns an __m128i whose low 32 bits are equal to amt and has zero elsewhere. */ -static inline __m128i libdivide_u32_to_m128i(uint32_t amt) { - return _mm_set_epi32(0, 0, 0, amt); -} - -static inline __m128i libdivide_s64_shift_right_vector(__m128i v, int amt) { - //implementation of _mm_sra_epi64. Here we have two 64 bit values which are shifted right to logically become (64 - amt) values, and are then sign extended from a (64 - amt) bit number. - const int b = 64 - amt; - __m128i m = libdivide__u64_to_m128(1ULL << (b - 1)); - __m128i x = _mm_srl_epi64(v, libdivide_u32_to_m128i(amt)); - __m128i result = _mm_sub_epi64(_mm_xor_si128(x, m), m); //result = x^m - m - return result; -} - -/* Here, b is assumed to contain one 32 bit value repeated four times. If it did not, the function would not work. */ -static inline __m128i libdivide__mullhi_u32_flat_vector(__m128i a, __m128i b) { - __m128i hi_product_0Z2Z = _mm_srli_epi64(_mm_mul_epu32(a, b), 32); - __m128i a1X3X = _mm_srli_epi64(a, 32); - __m128i hi_product_Z1Z3 = _mm_and_si128(_mm_mul_epu32(a1X3X, b), libdivide_get_FFFFFFFF00000000()); - return _mm_or_si128(hi_product_0Z2Z, hi_product_Z1Z3); // = hi_product_0123 -} - - -/* Here, y is assumed to contain one 64 bit value repeated twice. */ -static inline __m128i libdivide_mullhi_u64_flat_vector(__m128i x, __m128i y) { - //full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) - const __m128i mask = libdivide_get_00000000FFFFFFFF(); - const __m128i x0 = _mm_and_si128(x, mask), x1 = _mm_srli_epi64(x, 32); //x0 is low half of 2 64 bit values, x1 is high half in low slots - const __m128i y0 = _mm_and_si128(y, mask), y1 = _mm_srli_epi64(y, 32); - const __m128i x0y0_hi = _mm_srli_epi64(_mm_mul_epu32(x0, y0), 32); //x0 happens to have the low half of the two 64 bit values in 32 bit slots 0 and 2, so _mm_mul_epu32 computes their full product, and then we shift right by 32 to get just the high values - const __m128i x0y1 = _mm_mul_epu32(x0, y1); - const __m128i x1y0 = _mm_mul_epu32(x1, y0); - const __m128i x1y1 = _mm_mul_epu32(x1, y1); - - const __m128i temp = _mm_add_epi64(x1y0, x0y0_hi); - __m128i temp_lo = _mm_and_si128(temp, mask), temp_hi = _mm_srli_epi64(temp, 32); - temp_lo = _mm_srli_epi64(_mm_add_epi64(temp_lo, x0y1), 32); - temp_hi = _mm_add_epi64(x1y1, temp_hi); - - return _mm_add_epi64(temp_lo, temp_hi); -} - -/* y is one 64 bit value repeated twice */ -static inline __m128i libdivide_mullhi_s64_flat_vector(__m128i x, __m128i y) { - __m128i p = libdivide_mullhi_u64_flat_vector(x, y); - __m128i t1 = _mm_and_si128(libdivide_s64_signbits(x), y); - p = _mm_sub_epi64(p, t1); - __m128i t2 = _mm_and_si128(libdivide_s64_signbits(y), x); - p = _mm_sub_epi64(p, t2); - return p; -} - -#ifdef LIBDIVIDE_USE_SSE4_1 - -/* b is one 32 bit value repeated four times. */ -static inline __m128i libdivide_mullhi_s32_flat_vector(__m128i a, __m128i b) { - __m128i hi_product_0Z2Z = _mm_srli_epi64(_mm_mul_epi32(a, b), 32); - __m128i a1X3X = _mm_srli_epi64(a, 32); - __m128i hi_product_Z1Z3 = _mm_and_si128(_mm_mul_epi32(a1X3X, b), libdivide_get_FFFFFFFF00000000()); - return _mm_or_si128(hi_product_0Z2Z, hi_product_Z1Z3); // = hi_product_0123 -} - -#else - -/* SSE2 does not have a signed multiplication instruction, but we can convert unsigned to signed pretty efficiently. Again, b is just a 32 bit value repeated four times. */ -static inline __m128i libdivide_mullhi_s32_flat_vector(__m128i a, __m128i b) { - __m128i p = libdivide__mullhi_u32_flat_vector(a, b); - __m128i t1 = _mm_and_si128(_mm_srai_epi32(a, 31), b); //t1 = (a >> 31) & y, arithmetic shift - __m128i t2 = _mm_and_si128(_mm_srai_epi32(b, 31), a); - p = _mm_sub_epi32(p, t1); - p = _mm_sub_epi32(p, t2); - return p; -} -#endif -#endif - -static inline int32_t libdivide__count_trailing_zeros32(uint32_t val) { -#if __GNUC__ || __has_builtin(__builtin_ctz) - /* Fast way to count trailing zeros */ - return __builtin_ctz(val); -#elif LIBDIVIDE_VC - unsigned long result; - if (_BitScanForward(&result, val)) { - return result; - } - return 0; -#else - /* Dorky way to count trailing zeros. Note that this hangs for val = 0! */ - int32_t result = 0; - val = (val ^ (val - 1)) >> 1; // Set v's trailing 0s to 1s and zero rest - while (val) { - val >>= 1; - result++; - } - return result; -#endif -} - -static inline int32_t libdivide__count_trailing_zeros64(uint64_t val) { -#if __LP64__ && (__GNUC__ || __has_builtin(__builtin_ctzll)) - /* Fast way to count trailing zeros. Note that we disable this in 32 bit because gcc does something horrible - it calls through to a dynamically bound function. */ - return __builtin_ctzll(val); -#elif LIBDIVIDE_VC && _WIN64 - unsigned long result; - if (_BitScanForward64(&result, val)) { - return result; - } - return 0; -#else - /* Pretty good way to count trailing zeros. Note that this hangs for val = 0! */ - uint32_t lo = val & 0xFFFFFFFF; - if (lo != 0) return libdivide__count_trailing_zeros32(lo); - return 32 + libdivide__count_trailing_zeros32(val >> 32); -#endif -} - -static inline int32_t libdivide__count_leading_zeros32(uint32_t val) { -#if __GNUC__ || __has_builtin(__builtin_clzll) - /* Fast way to count leading zeros */ +static inline int32_t libdivide_count_leading_zeros32(uint32_t val) { +#if defined(__GNUC__) || \ + __has_builtin(__builtin_clz) + // Fast way to count leading zeros return __builtin_clz(val); -#elif LIBDIVIDE_VC +#elif defined(LIBDIVIDE_VC) unsigned long result; if (_BitScanReverse(&result, val)) { return 31 - result; } return 0; #else - /* Dorky way to count leading zeros. Note that this hangs for val = 0! */ int32_t result = 0; - while (! (val & (1U << 31))) { - val <<= 1; + uint32_t hi = 1U << 31; + for (; ~val & hi; hi >>= 1) { result++; } return result; #endif } -static inline int32_t libdivide__count_leading_zeros64(uint64_t val) { -#if __GNUC__ || __has_builtin(__builtin_clzll) - /* Fast way to count leading zeros */ +static inline int32_t libdivide_count_leading_zeros64(uint64_t val) { +#if defined(__GNUC__) || \ + __has_builtin(__builtin_clzll) + // Fast way to count leading zeros return __builtin_clzll(val); -#elif LIBDIVIDE_VC && _WIN64 +#elif defined(LIBDIVIDE_VC) && defined(_WIN64) unsigned long result; if (_BitScanReverse64(&result, val)) { return 63 - result; } return 0; #else - /* Dorky way to count leading zeros. Note that this hangs for val = 0! */ - int32_t result = 0; - while (! (val & (1ULL << 63))) { - val <<= 1; - result++; - } - return result; + uint32_t hi = val >> 32; + uint32_t lo = val & 0xFFFFFFFF; + if (hi != 0) return libdivide_count_leading_zeros32(hi); + return 32 + libdivide_count_leading_zeros32(lo); #endif } -//libdivide_64_div_32_to_32: divides a 64 bit uint {u1, u0} by a 32 bit uint {v}. The result must fit in 32 bits. Returns the quotient directly and the remainder in *r -#if (LIBDIVIDE_IS_i386 || LIBDIVIDE_IS_X86_64) && LIBDIVIDE_GCC_STYLE_ASM -static uint32_t libdivide_64_div_32_to_32(uint32_t u1, uint32_t u0, uint32_t v, uint32_t *r) { +// libdivide_64_div_32_to_32: divides a 64-bit uint {u1, u0} by a 32-bit +// uint {v}. The result must fit in 32 bits. +// Returns the quotient directly and the remainder in *r +static inline uint32_t libdivide_64_div_32_to_32(uint32_t u1, uint32_t u0, uint32_t v, uint32_t *r) { +#if (defined(LIBDIVIDE_i386) || defined(LIBDIVIDE_X86_64)) && \ + defined(LIBDIVIDE_GCC_STYLE_ASM) uint32_t result; __asm__("divl %[v]" : "=a"(result), "=d"(*r) : [v] "r"(v), "a"(u0), "d"(u1) ); return result; -} #else -static uint32_t libdivide_64_div_32_to_32(uint32_t u1, uint32_t u0, uint32_t v, uint32_t *r) { - uint64_t n = (((uint64_t)u1) << 32) | u0; + uint64_t n = ((uint64_t)u1 << 32) | u0; uint32_t result = (uint32_t)(n / v); *r = (uint32_t)(n - result * (uint64_t)v); return result; -} #endif +} -#if LIBDIVIDE_IS_X86_64 && LIBDIVIDE_GCC_STYLE_ASM +// libdivide_128_div_64_to_64: divides a 128-bit uint {u1, u0} by a 64-bit +// uint {v}. The result must fit in 64 bits. +// Returns the quotient directly and the remainder in *r static uint64_t libdivide_128_div_64_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t *r) { - //u0 -> rax - //u1 -> rdx - //divq +#if defined(LIBDIVIDE_X86_64) && \ + defined(LIBDIVIDE_GCC_STYLE_ASM) uint64_t result; __asm__("divq %[v]" : "=a"(result), "=d"(*r) : [v] "r"(v), "a"(u0), "d"(u1) ); return result; - -} +#elif defined(HAS_INT128_T) && \ + defined(HAS_INT128_DIV) + __uint128_t n = ((__uint128_t)u1 << 64) | u0; + uint64_t result = (uint64_t)(n / v); + *r = (uint64_t)(n - result * (__uint128_t)v); + return result; #else + // Code taken from Hacker's Delight: + // http://www.hackersdelight.org/HDcode/divlu.c. + // License permits inclusion here per: + // http://www.hackersdelight.org/permissions.htm -/* Code taken from Hacker's Delight, http://www.hackersdelight.org/HDcode/divlu.c . License permits inclusion here per http://www.hackersdelight.org/permissions.htm - */ -static uint64_t libdivide_128_div_64_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t *r) { - const uint64_t b = (1ULL << 32); // Number base (16 bits). - uint64_t un1, un0, // Norm. dividend LSD's. - vn1, vn0, // Norm. divisor digits. - q1, q0, // Quotient digits. - un64, un21, un10,// Dividend digit pairs. - rhat; // A remainder. - int s; // Shift amount for norm. + const uint64_t b = (1ULL << 32); // Number base (32 bits) + uint64_t un1, un0; // Norm. dividend LSD's + uint64_t vn1, vn0; // Norm. divisor digits + uint64_t q1, q0; // Quotient digits + uint64_t un64, un21, un10; // Dividend digit pairs + uint64_t rhat; // A remainder + int32_t s; // Shift amount for norm - if (u1 >= v) { // If overflow, set rem. - if (r != NULL) // to an impossible value, - *r = (uint64_t)(-1); // and return the largest - return (uint64_t)(-1);} // possible quotient. + // If overflow, set rem. to an impossible value, + // and return the largest possible quotient + if (u1 >= v) { + *r = (uint64_t) -1; + return (uint64_t) -1; + } - /* count leading zeros */ - s = libdivide__count_leading_zeros64(v); // 0 <= s <= 63. + // count leading zeros + s = libdivide_count_leading_zeros64(v); if (s > 0) { - v = v << s; // Normalize divisor. - un64 = (u1 << s) | ((u0 >> (64 - s)) & (-s >> 31)); - un10 = u0 << s; // Shift dividend left. + // Normalize divisor + v = v << s; + un64 = (u1 << s) | (u0 >> (64 - s)); + un10 = u0 << s; // Shift dividend left } else { - // Avoid undefined behavior. - un64 = u1 | u0; + // Avoid undefined behavior of (u0 >> 64). + // The behavior is undefined if the right operand is + // negative, or greater than or equal to the length + // in bits of the promoted left operand. + un64 = u1; un10 = u0; } - vn1 = v >> 32; // Break divisor up into - vn0 = v & 0xFFFFFFFF; // two 32-bit digits. + // Break divisor up into two 32-bit digits + vn1 = v >> 32; + vn0 = v & 0xFFFFFFFF; - un1 = un10 >> 32; // Break right half of - un0 = un10 & 0xFFFFFFFF; // dividend into two digits. + // Break right half of dividend into two digits + un1 = un10 >> 32; + un0 = un10 & 0xFFFFFFFF; - q1 = un64/vn1; // Compute the first - rhat = un64 - q1*vn1; // quotient digit, q1. -again1: - if (q1 >= b || q1*vn0 > b*rhat + un1) { + // Compute the first quotient digit, q1 + q1 = un64 / vn1; + rhat = un64 - q1 * vn1; + + while (q1 >= b || q1 * vn0 > b * rhat + un1) { q1 = q1 - 1; rhat = rhat + vn1; - if (rhat < b) goto again1;} + if (rhat >= b) + break; + } - un21 = un64*b + un1 - q1*v; // Multiply and subtract. + // Multiply and subtract + un21 = un64 * b + un1 - q1 * v; - q0 = un21/vn1; // Compute the second - rhat = un21 - q0*vn1; // quotient digit, q0. -again2: - if (q0 >= b || q0*vn0 > b*rhat + un0) { + // Compute the second quotient digit + q0 = un21 / vn1; + rhat = un21 - q0 * vn1; + + while (q0 >= b || q0 * vn0 > b * rhat + un0) { q0 = q0 - 1; rhat = rhat + vn1; - if (rhat < b) goto again2;} + if (rhat >= b) + break; + } - if (r != NULL) // If remainder is wanted, - *r = (un21*b + un0 - q0*v) >> s; // return it. - return q1*b + q0; + *r = (un21 * b + un0 - q0 * v) >> s; + return q1 * b + q0; +#endif } -#endif -#if LIBDIVIDE_ASSERTIONS_ON -#define LIBDIVIDE_ASSERT(x) do { if (! (x)) { fprintf(stderr, "Assertion failure on line %ld: %s\n", (long)__LINE__, #x); exit(-1); } } while (0) +// Bitshift a u128 in place, left (signed_shift > 0) or right (signed_shift < 0) +static inline void libdivide_u128_shift(uint64_t *u1, uint64_t *u0, int32_t signed_shift) { + if (signed_shift > 0) { + uint32_t shift = signed_shift; + *u1 <<= shift; + *u1 |= *u0 >> (64 - shift); + *u0 <<= shift; + } + else if (signed_shift < 0) { + uint32_t shift = -signed_shift; + *u0 >>= shift; + *u0 |= *u1 << (64 - shift); + *u1 >>= shift; + } +} + +// Computes a 128 / 128 -> 64 bit division, with a 128 bit remainder. +static uint64_t libdivide_128_div_128_to_64(uint64_t u_hi, uint64_t u_lo, uint64_t v_hi, uint64_t v_lo, uint64_t *r_hi, uint64_t *r_lo) { +#if defined(HAS_INT128_T) && \ + defined(HAS_INT128_DIV) + __uint128_t ufull = u_hi; + __uint128_t vfull = v_hi; + ufull = (ufull << 64) | u_lo; + vfull = (vfull << 64) | v_lo; + uint64_t res = (uint64_t)(ufull / vfull); + __uint128_t remainder = ufull - (vfull * res); + *r_lo = (uint64_t)remainder; + *r_hi = (uint64_t)(remainder >> 64); + return res; #else -#define LIBDIVIDE_ASSERT(x) -#endif + // Adapted from "Unsigned Doubleword Division" in Hacker's Delight + // We want to compute u / v + typedef struct { uint64_t hi; uint64_t lo; } u128_t; + u128_t u = {u_hi, u_lo}; + u128_t v = {v_hi, v_lo}; -#ifndef LIBDIVIDE_HEADER_ONLY + if (v.hi == 0) { + // divisor v is a 64 bit value, so we just need one 128/64 division + // Note that we are simpler than Hacker's Delight here, because we know + // the quotient fits in 64 bits whereas Hacker's Delight demands a full + // 128 bit quotient + *r_hi = 0; + return libdivide_128_div_64_to_64(u.hi, u.lo, v.lo, r_lo); + } + // Here v >= 2**64 + // We know that v.hi != 0, so count leading zeros is OK + // We have 0 <= n <= 63 + uint32_t n = libdivide_count_leading_zeros64(v.hi); + + // Normalize the divisor so its MSB is 1 + u128_t v1t = v; + libdivide_u128_shift(&v1t.hi, &v1t.lo, n); + uint64_t v1 = v1t.hi; // i.e. v1 = v1t >> 64 + + // To ensure no overflow + u128_t u1 = u; + libdivide_u128_shift(&u1.hi, &u1.lo, -1); + + // Get quotient from divide unsigned insn. + uint64_t rem_ignored; + uint64_t q1 = libdivide_128_div_64_to_64(u1.hi, u1.lo, v1, &rem_ignored); + + // Undo normalization and division of u by 2. + u128_t q0 = {0, q1}; + libdivide_u128_shift(&q0.hi, &q0.lo, n); + libdivide_u128_shift(&q0.hi, &q0.lo, -63); + + // Make q0 correct or too small by 1 + // Equivalent to `if (q0 != 0) q0 = q0 - 1;` + if (q0.hi != 0 || q0.lo != 0) { + q0.hi -= (q0.lo == 0); // borrow + q0.lo -= 1; + } + + // Now q0 is correct. + // Compute q0 * v as q0v + // = (q0.hi << 64 + q0.lo) * (v.hi << 64 + v.lo) + // = (q0.hi * v.hi << 128) + (q0.hi * v.lo << 64) + + // (q0.lo * v.hi << 64) + q0.lo * v.lo) + // Each term is 128 bit + // High half of full product (upper 128 bits!) are dropped + u128_t q0v = {0, 0}; + q0v.hi = q0.hi*v.lo + q0.lo*v.hi + libdivide_mullhi_u64(q0.lo, v.lo); + q0v.lo = q0.lo*v.lo; + + // Compute u - q0v as u_q0v + // This is the remainder + u128_t u_q0v = u; + u_q0v.hi -= q0v.hi + (u.lo < q0v.lo); // second term is borrow + u_q0v.lo -= q0v.lo; + + // Check if u_q0v >= v + // This checks if our remainder is larger than the divisor + if ((u_q0v.hi > v.hi) || + (u_q0v.hi == v.hi && u_q0v.lo >= v.lo)) { + // Increment q0 + q0.lo += 1; + q0.hi += (q0.lo == 0); // carry + + // Subtract v from remainder + u_q0v.hi -= v.hi + (u_q0v.lo < v.lo); + u_q0v.lo -= v.lo; + } + + *r_hi = u_q0v.hi; + *r_lo = u_q0v.lo; + + LIBDIVIDE_ASSERT(q0.hi == 0); + return q0.lo; +#endif +} ////////// UINT32 -struct libdivide_u32_t libdivide_u32_gen(uint32_t d) { - struct libdivide_u32_t result; - if ((d & (d - 1)) == 0) { - result.magic = 0; - result.more = libdivide__count_trailing_zeros32(d) | LIBDIVIDE_U32_SHIFT_PATH; +static inline struct libdivide_u32_t libdivide_internal_u32_gen(uint32_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); } - else { - const uint32_t floor_log_2_d = 31 - libdivide__count_leading_zeros32(d); + struct libdivide_u32_t result; + uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(d); + + // Power of 2 + if ((d & (d - 1)) == 0) { + // We need to subtract 1 from the shift value in case of an unsigned + // branchfree divider because there is a hardcoded right shift by 1 + // in its division algorithm. Because of this we also need to add back + // 1 in its recovery algorithm. + result.magic = 0; + result.more = (uint8_t)(floor_log_2_d - (branchfree != 0)); + } else { uint8_t more; uint32_t rem, proposed_m; proposed_m = libdivide_64_div_32_to_32(1U << floor_log_2_d, 0, d, &rem); @@ -631,570 +569,1358 @@ struct libdivide_u32_t libdivide_u32_gen(uint32_t d) { LIBDIVIDE_ASSERT(rem > 0 && rem < d); const uint32_t e = d - rem; - /* This power works if e < 2**floor_log_2_d. */ - if (e < (1U << floor_log_2_d)) { - /* This power works */ + // This power works if e < 2**floor_log_2_d. + if (!branchfree && (e < (1U << floor_log_2_d))) { + // This power works more = floor_log_2_d; - } - else { - /* We have to use the general 33-bit algorithm. We need to compute (2**power) / d. However, we already have (2**(power-1))/d and its remainder. By doubling both, and then correcting the remainder, we can compute the larger division. */ - proposed_m += proposed_m; //don't care about overflow here - in fact, we expect it + } else { + // We have to use the general 33-bit algorithm. We need to compute + // (2**power) / d. However, we already have (2**(power-1))/d and + // its remainder. By doubling both, and then correcting the + // remainder, we can compute the larger division. + // don't care about overflow here - in fact, we expect it + proposed_m += proposed_m; const uint32_t twice_rem = rem + rem; if (twice_rem >= d || twice_rem < rem) proposed_m += 1; more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; } result.magic = 1 + proposed_m; result.more = more; - //result.more's shift should in general be ceil_log_2_d. But if we used the smaller power, we subtract one from the shift because we're using the smaller power. If we're using the larger power, we subtract one from the shift because it's taken care of by the add indicator. So floor_log_2_d happens to be correct in both cases. - + // result.more's shift should in general be ceil_log_2_d. But if we + // used the smaller power, we subtract one from the shift because we're + // using the smaller power. If we're using the larger power, we + // subtract one from the shift because it's taken care of by the add + // indicator. So floor_log_2_d happens to be correct in both cases. } return result; } +struct libdivide_u32_t libdivide_u32_gen(uint32_t d) { + return libdivide_internal_u32_gen(d, 0); +} + +struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d) { + if (d == 1) { + LIBDIVIDE_ERROR("branchfree divider must be != 1"); + } + struct libdivide_u32_t tmp = libdivide_internal_u32_gen(d, 1); + struct libdivide_u32_branchfree_t ret = {tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_32_SHIFT_MASK)}; + return ret; +} + uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom) { uint8_t more = denom->more; - if (more & LIBDIVIDE_U32_SHIFT_PATH) { - return numer >> (more & LIBDIVIDE_32_SHIFT_MASK); + if (!denom->magic) { + return numer >> more; } else { - uint32_t q = libdivide__mullhi_u32(denom->magic, numer); + uint32_t q = libdivide_mullhi_u32(denom->magic, numer); if (more & LIBDIVIDE_ADD_MARKER) { uint32_t t = ((numer - q) >> 1) + q; return t >> (more & LIBDIVIDE_32_SHIFT_MASK); } else { - return q >> more; //all upper bits are 0 - don't need to mask them off + // All upper bits are 0, + // don't need to mask them off. + return q >> more; } } } - -int libdivide_u32_get_algorithm(const struct libdivide_u32_t *denom) { - uint8_t more = denom->more; - if (more & LIBDIVIDE_U32_SHIFT_PATH) return 0; - else if (! (more & LIBDIVIDE_ADD_MARKER)) return 1; - else return 2; -} - -uint32_t libdivide_u32_do_alg0(uint32_t numer, const struct libdivide_u32_t *denom) { - return numer >> (denom->more & LIBDIVIDE_32_SHIFT_MASK); -} - -uint32_t libdivide_u32_do_alg1(uint32_t numer, const struct libdivide_u32_t *denom) { - uint32_t q = libdivide__mullhi_u32(denom->magic, numer); - return q >> denom->more; -} - -uint32_t libdivide_u32_do_alg2(uint32_t numer, const struct libdivide_u32_t *denom) { - // denom->add != 0 - uint32_t q = libdivide__mullhi_u32(denom->magic, numer); +uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom) { + uint32_t q = libdivide_mullhi_u32(denom->magic, numer); uint32_t t = ((numer - q) >> 1) + q; - return t >> (denom->more & LIBDIVIDE_32_SHIFT_MASK); + return t >> denom->more; } - - - -#if LIBDIVIDE_USE_SSE2 -__m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom) { +uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom) { uint8_t more = denom->more; - if (more & LIBDIVIDE_U32_SHIFT_PATH) { - return _mm_srl_epi32(numers, libdivide_u32_to_m128i(more & LIBDIVIDE_32_SHIFT_MASK)); - } - else { - __m128i q = libdivide__mullhi_u32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - if (more & LIBDIVIDE_ADD_MARKER) { - //uint32_t t = ((numer - q) >> 1) + q; - //return t >> denom->shift; - __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q); - return _mm_srl_epi32(t, libdivide_u32_to_m128i(more & LIBDIVIDE_32_SHIFT_MASK)); + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; - } - else { - //q >> denom->shift - return _mm_srl_epi32(q, libdivide_u32_to_m128i(more)); - } + if (!denom->magic) { + return 1U << shift; + } else if (!(more & LIBDIVIDE_ADD_MARKER)) { + // We compute q = n/d = n*m / 2^(32 + shift) + // Therefore we have d = 2^(32 + shift) / m + // We need to ceil it. + // We know d is not a power of 2, so m is not a power of 2, + // so we can just add 1 to the floor + uint32_t hi_dividend = 1U << shift; + uint32_t rem_ignored; + return 1 + libdivide_64_div_32_to_32(hi_dividend, 0, denom->magic, &rem_ignored); + } else { + // Here we wish to compute d = 2^(32+shift+1)/(m+2^32). + // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now + // Also note that shift may be as high as 31, so shift + 1 will + // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and + // then double the quotient and remainder. + uint64_t half_n = 1ULL << (32 + shift); + uint64_t d = (1ULL << 32) | denom->magic; + // Note that the quotient is guaranteed <= 32 bits, but the remainder + // may need 33! + uint32_t half_q = (uint32_t)(half_n / d); + uint64_t rem = half_n % d; + // We computed 2^(32+shift)/(m+2^32) + // Need to double it, and then add 1 to the quotient if doubling th + // remainder would increase the quotient. + // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits + uint32_t full_q = half_q + half_q + ((rem<<1) >= d); + + // We rounded down in gen (hence +1) + return full_q + 1; } } -__m128i libdivide_u32_do_vector_alg0(__m128i numers, const struct libdivide_u32_t *denom) { - return _mm_srl_epi32(numers, libdivide_u32_to_m128i(denom->more & LIBDIVIDE_32_SHIFT_MASK)); -} +uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; -__m128i libdivide_u32_do_vector_alg1(__m128i numers, const struct libdivide_u32_t *denom) { - __m128i q = libdivide__mullhi_u32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - return _mm_srl_epi32(q, libdivide_u32_to_m128i(denom->more)); -} + if (!denom->magic) { + return 1U << (shift + 1); + } else { + // Here we wish to compute d = 2^(32+shift+1)/(m+2^32). + // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now + // Also note that shift may be as high as 31, so shift + 1 will + // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and + // then double the quotient and remainder. + uint64_t half_n = 1ULL << (32 + shift); + uint64_t d = (1ULL << 32) | denom->magic; + // Note that the quotient is guaranteed <= 32 bits, but the remainder + // may need 33! + uint32_t half_q = (uint32_t)(half_n / d); + uint64_t rem = half_n % d; + // We computed 2^(32+shift)/(m+2^32) + // Need to double it, and then add 1 to the quotient if doubling th + // remainder would increase the quotient. + // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits + uint32_t full_q = half_q + half_q + ((rem<<1) >= d); -__m128i libdivide_u32_do_vector_alg2(__m128i numers, const struct libdivide_u32_t *denom) { - __m128i q = libdivide__mullhi_u32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q); - return _mm_srl_epi32(t, libdivide_u32_to_m128i(denom->more & LIBDIVIDE_32_SHIFT_MASK)); + // We rounded down in gen (hence +1) + return full_q + 1; + } } -#endif - /////////// UINT64 -struct libdivide_u64_t libdivide_u64_gen(uint64_t d) { - struct libdivide_u64_t result; - if ((d & (d - 1)) == 0) { - result.more = libdivide__count_trailing_zeros64(d) | LIBDIVIDE_U64_SHIFT_PATH; - result.magic = 0; +static inline struct libdivide_u64_t libdivide_internal_u64_gen(uint64_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); } - else { - const uint32_t floor_log_2_d = 63 - libdivide__count_leading_zeros64(d); + struct libdivide_u64_t result; + uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(d); + + // Power of 2 + if ((d & (d - 1)) == 0) { + // We need to subtract 1 from the shift value in case of an unsigned + // branchfree divider because there is a hardcoded right shift by 1 + // in its division algorithm. Because of this we also need to add back + // 1 in its recovery algorithm. + result.magic = 0; + result.more = (uint8_t)(floor_log_2_d - (branchfree != 0)); + } else { uint64_t proposed_m, rem; uint8_t more; - proposed_m = libdivide_128_div_64_to_64(1ULL << floor_log_2_d, 0, d, &rem); //== (1 << (64 + floor_log_2_d)) / d + // (1 << (64 + floor_log_2_d)) / d + proposed_m = libdivide_128_div_64_to_64(1ULL << floor_log_2_d, 0, d, &rem); LIBDIVIDE_ASSERT(rem > 0 && rem < d); const uint64_t e = d - rem; - /* This power works if e < 2**floor_log_2_d. */ - if (e < (1ULL << floor_log_2_d)) { - /* This power works */ + // This power works if e < 2**floor_log_2_d. + if (!branchfree && e < (1ULL << floor_log_2_d)) { + // This power works more = floor_log_2_d; - } - else { - /* We have to use the general 65-bit algorithm. We need to compute (2**power) / d. However, we already have (2**(power-1))/d and its remainder. By doubling both, and then correcting the remainder, we can compute the larger division. */ - proposed_m += proposed_m; //don't care about overflow here - in fact, we expect it + } else { + // We have to use the general 65-bit algorithm. We need to compute + // (2**power) / d. However, we already have (2**(power-1))/d and + // its remainder. By doubling both, and then correcting the + // remainder, we can compute the larger division. + // don't care about overflow here - in fact, we expect it + proposed_m += proposed_m; const uint64_t twice_rem = rem + rem; if (twice_rem >= d || twice_rem < rem) proposed_m += 1; - more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; } result.magic = 1 + proposed_m; result.more = more; - //result.more's shift should in general be ceil_log_2_d. But if we used the smaller power, we subtract one from the shift because we're using the smaller power. If we're using the larger power, we subtract one from the shift because it's taken care of by the add indicator. So floor_log_2_d happens to be correct in both cases, which is why we do it outside of the if statement. + // result.more's shift should in general be ceil_log_2_d. But if we + // used the smaller power, we subtract one from the shift because we're + // using the smaller power. If we're using the larger power, we + // subtract one from the shift because it's taken care of by the add + // indicator. So floor_log_2_d happens to be correct in both cases, + // which is why we do it outside of the if statement. } return result; } +struct libdivide_u64_t libdivide_u64_gen(uint64_t d) { + return libdivide_internal_u64_gen(d, 0); +} + +struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d) { + if (d == 1) { + LIBDIVIDE_ERROR("branchfree divider must be != 1"); + } + struct libdivide_u64_t tmp = libdivide_internal_u64_gen(d, 1); + struct libdivide_u64_branchfree_t ret = {tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_64_SHIFT_MASK)}; + return ret; +} + uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom) { uint8_t more = denom->more; - if (more & LIBDIVIDE_U64_SHIFT_PATH) { - return numer >> (more & LIBDIVIDE_64_SHIFT_MASK); + if (!denom->magic) { + return numer >> more; } else { - uint64_t q = libdivide__mullhi_u64(denom->magic, numer); + uint64_t q = libdivide_mullhi_u64(denom->magic, numer); if (more & LIBDIVIDE_ADD_MARKER) { uint64_t t = ((numer - q) >> 1) + q; return t >> (more & LIBDIVIDE_64_SHIFT_MASK); } else { - return q >> more; //all upper bits are 0 - don't need to mask them off + // All upper bits are 0, + // don't need to mask them off. + return q >> more; } } } - -int libdivide_u64_get_algorithm(const struct libdivide_u64_t *denom) { - uint8_t more = denom->more; - if (more & LIBDIVIDE_U64_SHIFT_PATH) return 0; - else if (! (more & LIBDIVIDE_ADD_MARKER)) return 1; - else return 2; -} - -uint64_t libdivide_u64_do_alg0(uint64_t numer, const struct libdivide_u64_t *denom) { - return numer >> (denom->more & LIBDIVIDE_64_SHIFT_MASK); -} - -uint64_t libdivide_u64_do_alg1(uint64_t numer, const struct libdivide_u64_t *denom) { - uint64_t q = libdivide__mullhi_u64(denom->magic, numer); - return q >> denom->more; -} - -uint64_t libdivide_u64_do_alg2(uint64_t numer, const struct libdivide_u64_t *denom) { - uint64_t q = libdivide__mullhi_u64(denom->magic, numer); +uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom) { + uint64_t q = libdivide_mullhi_u64(denom->magic, numer); uint64_t t = ((numer - q) >> 1) + q; - return t >> (denom->more & LIBDIVIDE_64_SHIFT_MASK); + return t >> denom->more; } -#if LIBDIVIDE_USE_SSE2 -__m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t * denom) { +uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom) { uint8_t more = denom->more; - if (more & LIBDIVIDE_U64_SHIFT_PATH) { - return _mm_srl_epi64(numers, libdivide_u32_to_m128i(more & LIBDIVIDE_64_SHIFT_MASK)); - } - else { - __m128i q = libdivide_mullhi_u64_flat_vector(numers, libdivide__u64_to_m128(denom->magic)); - if (more & LIBDIVIDE_ADD_MARKER) { - //uint32_t t = ((numer - q) >> 1) + q; - //return t >> denom->shift; - __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q); - return _mm_srl_epi64(t, libdivide_u32_to_m128i(more & LIBDIVIDE_64_SHIFT_MASK)); - } - else { - //q >> denom->shift - return _mm_srl_epi64(q, libdivide_u32_to_m128i(more)); - } + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + + if (!denom->magic) { + return 1ULL << shift; + } else if (!(more & LIBDIVIDE_ADD_MARKER)) { + // We compute q = n/d = n*m / 2^(64 + shift) + // Therefore we have d = 2^(64 + shift) / m + // We need to ceil it. + // We know d is not a power of 2, so m is not a power of 2, + // so we can just add 1 to the floor + uint64_t hi_dividend = 1ULL << shift; + uint64_t rem_ignored; + return 1 + libdivide_128_div_64_to_64(hi_dividend, 0, denom->magic, &rem_ignored); + } else { + // Here we wish to compute d = 2^(64+shift+1)/(m+2^64). + // Notice (m + 2^64) is a 65 bit number. This gets hairy. See + // libdivide_u32_recover for more on what we do here. + // TODO: do something better than 128 bit math + + // Full n is a (potentially) 129 bit value + // half_n is a 128 bit value + // Compute the hi half of half_n. Low half is 0. + uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0; + // d is a 65 bit value. The high bit is always set to 1. + const uint64_t d_hi = 1, d_lo = denom->magic; + // Note that the quotient is guaranteed <= 64 bits, + // but the remainder may need 65! + uint64_t r_hi, r_lo; + uint64_t half_q = libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo); + // We computed 2^(64+shift)/(m+2^64) + // Double the remainder ('dr') and check if that is larger than d + // Note that d is a 65 bit value, so r1 is small and so r1 + r1 + // cannot overflow + uint64_t dr_lo = r_lo + r_lo; + uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry + int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo); + uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0); + return full_q + 1; } } -__m128i libdivide_u64_do_vector_alg0(__m128i numers, const struct libdivide_u64_t *denom) { - return _mm_srl_epi64(numers, libdivide_u32_to_m128i(denom->more & LIBDIVIDE_64_SHIFT_MASK)); +uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + + if (!denom->magic) { + return 1ULL << (shift + 1); + } else { + // Here we wish to compute d = 2^(64+shift+1)/(m+2^64). + // Notice (m + 2^64) is a 65 bit number. This gets hairy. See + // libdivide_u32_recover for more on what we do here. + // TODO: do something better than 128 bit math + + // Full n is a (potentially) 129 bit value + // half_n is a 128 bit value + // Compute the hi half of half_n. Low half is 0. + uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0; + // d is a 65 bit value. The high bit is always set to 1. + const uint64_t d_hi = 1, d_lo = denom->magic; + // Note that the quotient is guaranteed <= 64 bits, + // but the remainder may need 65! + uint64_t r_hi, r_lo; + uint64_t half_q = libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo); + // We computed 2^(64+shift)/(m+2^64) + // Double the remainder ('dr') and check if that is larger than d + // Note that d is a 65 bit value, so r1 is small and so r1 + r1 + // cannot overflow + uint64_t dr_lo = r_lo + r_lo; + uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry + int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo); + uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0); + return full_q + 1; + } } -__m128i libdivide_u64_do_vector_alg1(__m128i numers, const struct libdivide_u64_t *denom) { - __m128i q = libdivide_mullhi_u64_flat_vector(numers, libdivide__u64_to_m128(denom->magic)); - return _mm_srl_epi64(q, libdivide_u32_to_m128i(denom->more)); -} - -__m128i libdivide_u64_do_vector_alg2(__m128i numers, const struct libdivide_u64_t *denom) { - __m128i q = libdivide_mullhi_u64_flat_vector(numers, libdivide__u64_to_m128(denom->magic)); - __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q); - return _mm_srl_epi64(t, libdivide_u32_to_m128i(denom->more & LIBDIVIDE_64_SHIFT_MASK)); -} - - -#endif - /////////// SINT32 +static inline struct libdivide_s32_t libdivide_internal_s32_gen(int32_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); + } -static inline int32_t libdivide__mullhi_s32(int32_t x, int32_t y) { - int64_t xl = x, yl = y; - int64_t rl = xl * yl; - return (int32_t)(rl >> 32); //needs to be arithmetic shift -} - -struct libdivide_s32_t libdivide_s32_gen(int32_t d) { struct libdivide_s32_t result; - /* If d is a power of 2, or negative a power of 2, we have to use a shift. This is especially important because the magic algorithm fails for -1. To check if d is a power of 2 or its inverse, it suffices to check whether its absolute value has exactly one bit set. This works even for INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set and is a power of 2. */ - uint32_t absD = (uint32_t)(d < 0 ? -d : d); //gcc optimizes this to the fast abs trick - if ((absD & (absD - 1)) == 0) { //check if exactly one bit is set, don't care if absD is 0 since that's divide by zero + // If d is a power of 2, or negative a power of 2, we have to use a shift. + // This is especially important because the magic algorithm fails for -1. + // To check if d is a power of 2 or its inverse, it suffices to check + // whether its absolute value has exactly one bit set. This works even for + // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set + // and is a power of 2. + uint32_t ud = (uint32_t)d; + uint32_t absD = (d < 0) ? -ud : ud; + uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(absD); + // check if exactly one bit is set, + // don't care if absD is 0 since that's divide by zero + if ((absD & (absD - 1)) == 0) { + // Branchfree and normal paths are exactly the same result.magic = 0; - result.more = libdivide__count_trailing_zeros32(absD) | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0) | LIBDIVIDE_S32_SHIFT_PATH; - } - else { - const uint32_t floor_log_2_d = 31 - libdivide__count_leading_zeros32(absD); + result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); + } else { LIBDIVIDE_ASSERT(floor_log_2_d >= 1); uint8_t more; - //the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word is 0 and the high word is floor_log_2_d - 1 + // the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word + // is 0 and the high word is floor_log_2_d - 1 uint32_t rem, proposed_m; proposed_m = libdivide_64_div_32_to_32(1U << (floor_log_2_d - 1), 0, absD, &rem); const uint32_t e = absD - rem; - /* We are going to start with a power of floor_log_2_d - 1. This works if works if e < 2**floor_log_2_d. */ - if (e < (1U << floor_log_2_d)) { - /* This power works */ + // We are going to start with a power of floor_log_2_d - 1. + // This works if works if e < 2**floor_log_2_d. + if (!branchfree && e < (1U << floor_log_2_d)) { + // This power works more = floor_log_2_d - 1; - } - else { - /* We need to go one higher. This should not make proposed_m overflow, but it will make it negative when interpreted as an int32_t. */ + } else { + // We need to go one higher. This should not make proposed_m + // overflow, but it will make it negative when interpreted as an + // int32_t. proposed_m += proposed_m; const uint32_t twice_rem = rem + rem; if (twice_rem >= absD || twice_rem < rem) proposed_m += 1; - more = floor_log_2_d | LIBDIVIDE_ADD_MARKER | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); //use the general algorithm + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; } - proposed_m += 1; - result.magic = (d < 0 ? -(int32_t)proposed_m : (int32_t)proposed_m); - result.more = more; + proposed_m += 1; + int32_t magic = (int32_t)proposed_m; + + // Mark if we are negative. Note we only negate the magic number in the + // branchfull case. + if (d < 0) { + more |= LIBDIVIDE_NEGATIVE_DIVISOR; + if (!branchfree) { + magic = -magic; + } + } + + result.more = more; + result.magic = magic; } return result; } +struct libdivide_s32_t libdivide_s32_gen(int32_t d) { + return libdivide_internal_s32_gen(d, 0); +} + +struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d) { + struct libdivide_s32_t tmp = libdivide_internal_s32_gen(d, 1); + struct libdivide_s32_branchfree_t result = {tmp.magic, tmp.more}; + return result; +} + int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom) { uint8_t more = denom->more; - if (more & LIBDIVIDE_S32_SHIFT_PATH) { - uint8_t shifter = more & LIBDIVIDE_32_SHIFT_MASK; - int32_t q = numer + ((numer >> 31) & ((1 << shifter) - 1)); - q = q >> shifter; - int32_t shiftMask = (int8_t)more >> 7; //must be arithmetic shift and then sign-extend - q = (q ^ shiftMask) - shiftMask; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + + if (!denom->magic) { + uint32_t sign = (int8_t)more >> 7; + uint32_t mask = (1U << shift) - 1; + uint32_t uq = numer + ((numer >> 31) & mask); + int32_t q = (int32_t)uq; + q >>= shift; + q = (q ^ sign) - sign; return q; - } - else { - int32_t q = libdivide__mullhi_s32(denom->magic, numer); + } else { + uint32_t uq = (uint32_t)libdivide_mullhi_s32(denom->magic, numer); if (more & LIBDIVIDE_ADD_MARKER) { - int32_t sign = (int8_t)more >> 7; //must be arithmetic shift and then sign extend - q += ((numer ^ sign) - sign); + // must be arithmetic shift and then sign extend + int32_t sign = (int8_t)more >> 7; + // q += (more < 0 ? -numer : numer) + // cast required to avoid UB + uq += ((uint32_t)numer ^ sign) - sign; } - q >>= more & LIBDIVIDE_32_SHIFT_MASK; + int32_t q = (int32_t)uq; + q >>= shift; q += (q < 0); return q; } } -int libdivide_s32_get_algorithm(const struct libdivide_s32_t *denom) { +int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom) { uint8_t more = denom->more; - int positiveDivisor = ! (more & LIBDIVIDE_NEGATIVE_DIVISOR); - if (more & LIBDIVIDE_S32_SHIFT_PATH) return (positiveDivisor ? 0 : 1); - else if (more & LIBDIVIDE_ADD_MARKER) return (positiveDivisor ? 2 : 3); - else return 4; -} - -int32_t libdivide_s32_do_alg0(int32_t numer, const struct libdivide_s32_t *denom) { - uint8_t shifter = denom->more & LIBDIVIDE_32_SHIFT_MASK; - int32_t q = numer + ((numer >> 31) & ((1 << shifter) - 1)); - return q >> shifter; -} - -int32_t libdivide_s32_do_alg1(int32_t numer, const struct libdivide_s32_t *denom) { - uint8_t shifter = denom->more & LIBDIVIDE_32_SHIFT_MASK; - int32_t q = numer + ((numer >> 31) & ((1 << shifter) - 1)); - return - (q >> shifter); -} - -int32_t libdivide_s32_do_alg2(int32_t numer, const struct libdivide_s32_t *denom) { - int32_t q = libdivide__mullhi_s32(denom->magic, numer); + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift and then sign extend + int32_t sign = (int8_t)more >> 7; + int32_t magic = denom->magic; + int32_t q = libdivide_mullhi_s32(magic, numer); q += numer; - q >>= denom->more & LIBDIVIDE_32_SHIFT_MASK; - q += (q < 0); + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is a power of + // 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + uint32_t q_sign = (uint32_t)(q >> 31); + q += q_sign & ((1U << shift) - is_power_of_2); + + // Now arithmetic right shift + q >>= shift; + // Negate if needed + q = (q ^ sign) - sign; + return q; } -int32_t libdivide_s32_do_alg3(int32_t numer, const struct libdivide_s32_t *denom) { - int32_t q = libdivide__mullhi_s32(denom->magic, numer); - q -= numer; - q >>= denom->more & LIBDIVIDE_32_SHIFT_MASK; - q += (q < 0); - return q; -} - -int32_t libdivide_s32_do_alg4(int32_t numer, const struct libdivide_s32_t *denom) { - int32_t q = libdivide__mullhi_s32(denom->magic, numer); - q >>= denom->more & LIBDIVIDE_32_SHIFT_MASK; - q += (q < 0); - return q; -} - -#if LIBDIVIDE_USE_SSE2 -__m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t * denom) { +int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom) { uint8_t more = denom->more; - if (more & LIBDIVIDE_S32_SHIFT_PATH) { - uint32_t shifter = more & LIBDIVIDE_32_SHIFT_MASK; - __m128i roundToZeroTweak = _mm_set1_epi32((1 << shifter) - 1); //could use _mm_srli_epi32 with an all -1 register - __m128i q = _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak)); //q = numer + ((numer >> 31) & roundToZeroTweak); - q = _mm_sra_epi32(q, libdivide_u32_to_m128i(shifter)); // q = q >> shifter - __m128i shiftMask = _mm_set1_epi32((int32_t)((int8_t)more >> 7)); //set all bits of shift mask = to the sign bit of more - q = _mm_sub_epi32(_mm_xor_si128(q, shiftMask), shiftMask); //q = (q ^ shiftMask) - shiftMask; - return q; - } - else { - __m128i q = libdivide_mullhi_s32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - if (more & LIBDIVIDE_ADD_MARKER) { - __m128i sign = _mm_set1_epi32((int32_t)(int8_t)more >> 7); //must be arithmetic shift - q = _mm_add_epi32(q, _mm_sub_epi32(_mm_xor_si128(numers, sign), sign)); // q += ((numer ^ sign) - sign); + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + if (!denom->magic) { + uint32_t absD = 1U << shift; + if (more & LIBDIVIDE_NEGATIVE_DIVISOR) { + absD = -absD; } - q = _mm_sra_epi32(q, libdivide_u32_to_m128i(more & LIBDIVIDE_32_SHIFT_MASK)); //q >>= shift - q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); // q += (q < 0) - return q; + return (int32_t)absD; + } else { + // Unsigned math is much easier + // We negate the magic number only in the branchfull case, and we don't + // know which case we're in. However we have enough information to + // determine the correct sign of the magic number. The divisor was + // negative if LIBDIVIDE_NEGATIVE_DIVISOR is set. If ADD_MARKER is set, + // the magic number's sign is opposite that of the divisor. + // We want to compute the positive magic number. + int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR); + int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER) + ? denom->magic > 0 : denom->magic < 0; + + // Handle the power of 2 case (including branchfree) + if (denom->magic == 0) { + int32_t result = 1U << shift; + return negative_divisor ? -result : result; + } + + uint32_t d = (uint32_t)(magic_was_negated ? -denom->magic : denom->magic); + uint64_t n = 1ULL << (32 + shift); // this shift cannot exceed 30 + uint32_t q = (uint32_t)(n / d); + int32_t result = (int32_t)q; + result += 1; + return negative_divisor ? -result : result; } } -__m128i libdivide_s32_do_vector_alg0(__m128i numers, const struct libdivide_s32_t *denom) { - uint8_t shifter = denom->more & LIBDIVIDE_32_SHIFT_MASK; - __m128i roundToZeroTweak = _mm_set1_epi32((1 << shifter) - 1); - __m128i q = _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak)); - return _mm_sra_epi32(q, libdivide_u32_to_m128i(shifter)); +int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom) { + return libdivide_s32_recover((const struct libdivide_s32_t *)denom); } -__m128i libdivide_s32_do_vector_alg1(__m128i numers, const struct libdivide_s32_t *denom) { - uint8_t shifter = denom->more & LIBDIVIDE_32_SHIFT_MASK; - __m128i roundToZeroTweak = _mm_set1_epi32((1 << shifter) - 1); - __m128i q = _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak)); - return _mm_sub_epi32(_mm_setzero_si128(), _mm_sra_epi32(q, libdivide_u32_to_m128i(shifter))); -} - -__m128i libdivide_s32_do_vector_alg2(__m128i numers, const struct libdivide_s32_t *denom) { - __m128i q = libdivide_mullhi_s32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - q = _mm_add_epi32(q, numers); - q = _mm_sra_epi32(q, libdivide_u32_to_m128i(denom->more & LIBDIVIDE_32_SHIFT_MASK)); - q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); - return q; -} - -__m128i libdivide_s32_do_vector_alg3(__m128i numers, const struct libdivide_s32_t *denom) { - __m128i q = libdivide_mullhi_s32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - q = _mm_sub_epi32(q, numers); - q = _mm_sra_epi32(q, libdivide_u32_to_m128i(denom->more & LIBDIVIDE_32_SHIFT_MASK)); - q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); - return q; -} - -__m128i libdivide_s32_do_vector_alg4(__m128i numers, const struct libdivide_s32_t *denom) { - __m128i q = libdivide_mullhi_s32_flat_vector(numers, _mm_set1_epi32(denom->magic)); - q = _mm_sra_epi32(q, libdivide_u32_to_m128i(denom->more)); //q >>= shift - q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); // q += (q < 0) - return q; -} -#endif - ///////////// SINT64 +static inline struct libdivide_s64_t libdivide_internal_s64_gen(int64_t d, int branchfree) { + if (d == 0) { + LIBDIVIDE_ERROR("divider must be != 0"); + } -struct libdivide_s64_t libdivide_s64_gen(int64_t d) { struct libdivide_s64_t result; - /* If d is a power of 2, or negative a power of 2, we have to use a shift. This is especially important because the magic algorithm fails for -1. To check if d is a power of 2 or its inverse, it suffices to check whether its absolute value has exactly one bit set. This works even for INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set and is a power of 2. */ - const uint64_t absD = (uint64_t)(d < 0 ? -d : d); //gcc optimizes this to the fast abs trick - if ((absD & (absD - 1)) == 0) { //check if exactly one bit is set, don't care if absD is 0 since that's divide by zero - result.more = libdivide__count_trailing_zeros64(absD) | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); + // If d is a power of 2, or negative a power of 2, we have to use a shift. + // This is especially important because the magic algorithm fails for -1. + // To check if d is a power of 2 or its inverse, it suffices to check + // whether its absolute value has exactly one bit set. This works even for + // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set + // and is a power of 2. + uint64_t ud = (uint64_t)d; + uint64_t absD = (d < 0) ? -ud : ud; + uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(absD); + // check if exactly one bit is set, + // don't care if absD is 0 since that's divide by zero + if ((absD & (absD - 1)) == 0) { + // Branchfree and non-branchfree cases are the same result.magic = 0; - } - else { - const uint32_t floor_log_2_d = 63 - libdivide__count_leading_zeros64(absD); - - //the dividend here is 2**(floor_log_2_d + 63), so the low 64 bit word is 0 and the high word is floor_log_2_d - 1 + result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); + } else { + // the dividend here is 2**(floor_log_2_d + 63), so the low 64 bit word + // is 0 and the high word is floor_log_2_d - 1 uint8_t more; uint64_t rem, proposed_m; proposed_m = libdivide_128_div_64_to_64(1ULL << (floor_log_2_d - 1), 0, absD, &rem); const uint64_t e = absD - rem; - /* We are going to start with a power of floor_log_2_d - 1. This works if works if e < 2**floor_log_2_d. */ - if (e < (1ULL << floor_log_2_d)) { - /* This power works */ + // We are going to start with a power of floor_log_2_d - 1. + // This works if works if e < 2**floor_log_2_d. + if (!branchfree && e < (1ULL << floor_log_2_d)) { + // This power works more = floor_log_2_d - 1; - } - else { - /* We need to go one higher. This should not make proposed_m overflow, but it will make it negative when interpreted as an int32_t. */ + } else { + // We need to go one higher. This should not make proposed_m + // overflow, but it will make it negative when interpreted as an + // int32_t. proposed_m += proposed_m; const uint64_t twice_rem = rem + rem; if (twice_rem >= absD || twice_rem < rem) proposed_m += 1; - more = floor_log_2_d | LIBDIVIDE_ADD_MARKER | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0); + // note that we only set the LIBDIVIDE_NEGATIVE_DIVISOR bit if we + // also set ADD_MARKER this is an annoying optimization that + // enables algorithm #4 to avoid the mask. However we always set it + // in the branchfree case + more = floor_log_2_d | LIBDIVIDE_ADD_MARKER; } proposed_m += 1; + int64_t magic = (int64_t)proposed_m; + + // Mark if we are negative + if (d < 0) { + more |= LIBDIVIDE_NEGATIVE_DIVISOR; + if (!branchfree) { + magic = -magic; + } + } + result.more = more; - result.magic = (d < 0 ? -(int64_t)proposed_m : (int64_t)proposed_m); + result.magic = magic; } return result; } +struct libdivide_s64_t libdivide_s64_gen(int64_t d) { + return libdivide_internal_s64_gen(d, 0); +} + +struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d) { + struct libdivide_s64_t tmp = libdivide_internal_s64_gen(d, 1); + struct libdivide_s64_branchfree_t ret = {tmp.magic, tmp.more}; + return ret; +} + int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom) { uint8_t more = denom->more; - int64_t magic = denom->magic; - if (magic == 0) { //shift path - uint32_t shifter = more & LIBDIVIDE_64_SHIFT_MASK; - int64_t q = numer + ((numer >> 63) & ((1LL << shifter) - 1)); - q = q >> shifter; - int64_t shiftMask = (int8_t)more >> 7; //must be arithmetic shift and then sign-extend - q = (q ^ shiftMask) - shiftMask; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + + if (!denom->magic) { // shift path + uint64_t mask = (1ULL << shift) - 1; + uint64_t uq = numer + ((numer >> 63) & mask); + int64_t q = (int64_t)uq; + q >>= shift; + // must be arithmetic shift and then sign-extend + int64_t sign = (int8_t)more >> 7; + q = (q ^ sign) - sign; return q; - } - else { - int64_t q = libdivide__mullhi_s64(magic, numer); + } else { + uint64_t uq = (uint64_t)libdivide_mullhi_s64(denom->magic, numer); if (more & LIBDIVIDE_ADD_MARKER) { - int64_t sign = (int8_t)more >> 7; //must be arithmetic shift and then sign extend - q += ((numer ^ sign) - sign); + // must be arithmetic shift and then sign extend + int64_t sign = (int8_t)more >> 7; + // q += (more < 0 ? -numer : numer) + // cast required to avoid UB + uq += ((uint64_t)numer ^ sign) - sign; } - q >>= more & LIBDIVIDE_64_SHIFT_MASK; + int64_t q = (int64_t)uq; + q >>= shift; q += (q < 0); return q; } } - -int libdivide_s64_get_algorithm(const struct libdivide_s64_t *denom) { - uint8_t more = denom->more; - int positiveDivisor = ! (more & LIBDIVIDE_NEGATIVE_DIVISOR); - if (denom->magic == 0) return (positiveDivisor ? 0 : 1); //shift path - else if (more & LIBDIVIDE_ADD_MARKER) return (positiveDivisor ? 2 : 3); - else return 4; -} - -int64_t libdivide_s64_do_alg0(int64_t numer, const struct libdivide_s64_t *denom) { - uint32_t shifter = denom->more & LIBDIVIDE_64_SHIFT_MASK; - int64_t q = numer + ((numer >> 63) & ((1LL << shifter) - 1)); - return q >> shifter; -} - -int64_t libdivide_s64_do_alg1(int64_t numer, const struct libdivide_s64_t *denom) { - //denom->shifter != -1 && demo->shiftMask != 0 - uint32_t shifter = denom->more & LIBDIVIDE_64_SHIFT_MASK; - int64_t q = numer + ((numer >> 63) & ((1LL << shifter) - 1)); - return - (q >> shifter); -} - -int64_t libdivide_s64_do_alg2(int64_t numer, const struct libdivide_s64_t *denom) { - int64_t q = libdivide__mullhi_s64(denom->magic, numer); - q += numer; - q >>= denom->more & LIBDIVIDE_64_SHIFT_MASK; - q += (q < 0); - return q; -} - -int64_t libdivide_s64_do_alg3(int64_t numer, const struct libdivide_s64_t *denom) { - int64_t q = libdivide__mullhi_s64(denom->magic, numer); - q -= numer; - q >>= denom->more & LIBDIVIDE_64_SHIFT_MASK; - q += (q < 0); - return q; -} - -int64_t libdivide_s64_do_alg4(int64_t numer, const struct libdivide_s64_t *denom) { - int64_t q = libdivide__mullhi_s64(denom->magic, numer); - q >>= denom->more; - q += (q < 0); - return q; -} - - -#if LIBDIVIDE_USE_SSE2 -__m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t * denom) { +int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom) { uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift and then sign extend + int64_t sign = (int8_t)more >> 7; int64_t magic = denom->magic; - if (magic == 0) { //shift path - uint32_t shifter = more & LIBDIVIDE_64_SHIFT_MASK; - __m128i roundToZeroTweak = libdivide__u64_to_m128((1LL << shifter) - 1); - __m128i q = _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak)); //q = numer + ((numer >> 63) & roundToZeroTweak); - q = libdivide_s64_shift_right_vector(q, shifter); // q = q >> shifter - __m128i shiftMask = _mm_set1_epi32((int32_t)((int8_t)more >> 7)); - q = _mm_sub_epi64(_mm_xor_si128(q, shiftMask), shiftMask); //q = (q ^ shiftMask) - shiftMask; + int64_t q = libdivide_mullhi_s64(magic, numer); + q += numer; + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is a power of + // 2, or (2**shift) if it is not a power of 2. + uint64_t is_power_of_2 = (magic == 0); + uint64_t q_sign = (uint64_t)(q >> 63); + q += q_sign & ((1ULL << shift) - is_power_of_2); + + // Arithmetic right shift + q >>= shift; + // Negate if needed + q = (q ^ sign) - sign; + + return q; +} + +int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + if (denom->magic == 0) { // shift path + uint64_t absD = 1ULL << shift; + if (more & LIBDIVIDE_NEGATIVE_DIVISOR) { + absD = -absD; + } + return (int64_t)absD; + } else { + // Unsigned math is much easier + int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR); + int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER) + ? denom->magic > 0 : denom->magic < 0; + + uint64_t d = (uint64_t)(magic_was_negated ? -denom->magic : denom->magic); + uint64_t n_hi = 1ULL << shift, n_lo = 0; + uint64_t rem_ignored; + uint64_t q = libdivide_128_div_64_to_64(n_hi, n_lo, d, &rem_ignored); + int64_t result = (int64_t)(q + 1); + if (negative_divisor) { + result = -result; + } + return result; + } +} + +int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom) { + return libdivide_s64_recover((const struct libdivide_s64_t *)denom); +} + +#if defined(LIBDIVIDE_AVX512) + +static inline __m512i libdivide_u32_do_vector(__m512i numers, const struct libdivide_u32_t *denom); +static inline __m512i libdivide_s32_do_vector(__m512i numers, const struct libdivide_s32_t *denom); +static inline __m512i libdivide_u64_do_vector(__m512i numers, const struct libdivide_u64_t *denom); +static inline __m512i libdivide_s64_do_vector(__m512i numers, const struct libdivide_s64_t *denom); + +static inline __m512i libdivide_u32_branchfree_do_vector(__m512i numers, const struct libdivide_u32_branchfree_t *denom); +static inline __m512i libdivide_s32_branchfree_do_vector(__m512i numers, const struct libdivide_s32_branchfree_t *denom); +static inline __m512i libdivide_u64_branchfree_do_vector(__m512i numers, const struct libdivide_u64_branchfree_t *denom); +static inline __m512i libdivide_s64_branchfree_do_vector(__m512i numers, const struct libdivide_s64_branchfree_t *denom); + +//////// Internal Utility Functions + +static inline __m512i libdivide_s64_signbits(__m512i v) {; + return _mm512_srai_epi64(v, 63); +} + +static inline __m512i libdivide_s64_shift_right_vector(__m512i v, int amt) { + return _mm512_srai_epi64(v, amt); +} + +// Here, b is assumed to contain one 32-bit value repeated. +static inline __m512i libdivide_mullhi_u32_vector(__m512i a, __m512i b) { + __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epu32(a, b), 32); + __m512i a1X3X = _mm512_srli_epi64(a, 32); + __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0); + __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epu32(a1X3X, b), mask); + return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// b is one 32-bit value repeated. +static inline __m512i libdivide_mullhi_s32_vector(__m512i a, __m512i b) { + __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epi32(a, b), 32); + __m512i a1X3X = _mm512_srli_epi64(a, 32); + __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0); + __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epi32(a1X3X, b), mask); + return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// Here, y is assumed to contain one 64-bit value repeated. +// https://stackoverflow.com/a/28827013 +static inline __m512i libdivide_mullhi_u64_vector(__m512i x, __m512i y) { + __m512i lomask = _mm512_set1_epi64(0xffffffff); + __m512i xh = _mm512_shuffle_epi32(x, (_MM_PERM_ENUM) 0xB1); + __m512i yh = _mm512_shuffle_epi32(y, (_MM_PERM_ENUM) 0xB1); + __m512i w0 = _mm512_mul_epu32(x, y); + __m512i w1 = _mm512_mul_epu32(x, yh); + __m512i w2 = _mm512_mul_epu32(xh, y); + __m512i w3 = _mm512_mul_epu32(xh, yh); + __m512i w0h = _mm512_srli_epi64(w0, 32); + __m512i s1 = _mm512_add_epi64(w1, w0h); + __m512i s1l = _mm512_and_si512(s1, lomask); + __m512i s1h = _mm512_srli_epi64(s1, 32); + __m512i s2 = _mm512_add_epi64(w2, s1l); + __m512i s2h = _mm512_srli_epi64(s2, 32); + __m512i hi = _mm512_add_epi64(w3, s1h); + hi = _mm512_add_epi64(hi, s2h); + + return hi; +} + +// y is one 64-bit value repeated. +static inline __m512i libdivide_mullhi_s64_vector(__m512i x, __m512i y) { + __m512i p = libdivide_mullhi_u64_vector(x, y); + __m512i t1 = _mm512_and_si512(libdivide_s64_signbits(x), y); + __m512i t2 = _mm512_and_si512(libdivide_s64_signbits(y), x); + p = _mm512_sub_epi64(p, t1); + p = _mm512_sub_epi64(p, t2); + return p; +} + +////////// UINT32 + +__m512i libdivide_u32_do_vector(__m512i numers, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm512_srli_epi32(numers, more); + } + else { + __m512i q = libdivide_mullhi_u32_vector(numers, _mm512_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q); + return _mm512_srli_epi32(t, shift); + } + else { + return _mm512_srli_epi32(q, more); + } + } +} + +__m512i libdivide_u32_branchfree_do_vector(__m512i numers, const struct libdivide_u32_branchfree_t *denom) { + __m512i q = libdivide_mullhi_u32_vector(numers, _mm512_set1_epi32(denom->magic)); + __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q); + return _mm512_srli_epi32(t, denom->more); +} + +////////// UINT64 + +__m512i libdivide_u64_do_vector(__m512i numers, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm512_srli_epi64(numers, more); + } + else { + __m512i q = libdivide_mullhi_u64_vector(numers, _mm512_set1_epi64(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q); + return _mm512_srli_epi64(t, shift); + } + else { + return _mm512_srli_epi64(q, more); + } + } +} + +__m512i libdivide_u64_branchfree_do_vector(__m512i numers, const struct libdivide_u64_branchfree_t *denom) { + __m512i q = libdivide_mullhi_u64_vector(numers, _mm512_set1_epi64(denom->magic)); + __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q); + return _mm512_srli_epi64(t, denom->more); +} + +////////// SINT32 + +__m512i libdivide_s32_do_vector(__m512i numers, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + uint32_t mask = (1U << shift) - 1; + __m512i roundToZeroTweak = _mm512_set1_epi32(mask); + // q = numer + ((numer >> 31) & roundToZeroTweak); + __m512i q = _mm512_add_epi32(numers, _mm512_and_si512(_mm512_srai_epi32(numers, 31), roundToZeroTweak)); + q = _mm512_srai_epi32(q, shift); + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign); return q; } else { - __m128i q = libdivide_mullhi_s64_flat_vector(numers, libdivide__u64_to_m128(magic)); + __m512i q = libdivide_mullhi_s32_vector(numers, _mm512_set1_epi32(denom->magic)); if (more & LIBDIVIDE_ADD_MARKER) { - __m128i sign = _mm_set1_epi32((int32_t)((int8_t)more >> 7)); //must be arithmetic shift - q = _mm_add_epi64(q, _mm_sub_epi64(_mm_xor_si128(numers, sign), sign)); // q += ((numer ^ sign) - sign); + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm512_add_epi32(q, _mm512_sub_epi32(_mm512_xor_si512(numers, sign), sign)); } - q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); //q >>= denom->mult_path.shift + // q >>= shift + q = _mm512_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK); + q = _mm512_add_epi32(q, _mm512_srli_epi32(q, 31)); // q += (q < 0) + return q; + } +} + +__m512i libdivide_s32_branchfree_do_vector(__m512i numers, const struct libdivide_s32_branchfree_t *denom) { + int32_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + __m512i q = libdivide_mullhi_s32_vector(numers, _mm512_set1_epi32(magic)); + q = _mm512_add_epi32(q, numers); // q += numers + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + __m512i q_sign = _mm512_srai_epi32(q, 31); // q_sign = q >> 31 + __m512i mask = _mm512_set1_epi32((1U << shift) - is_power_of_2); + q = _mm512_add_epi32(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask) + q = _mm512_srai_epi32(q, shift); // q >>= shift + q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +////////// SINT64 + +__m512i libdivide_s64_do_vector(__m512i numers, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + int64_t magic = denom->magic; + if (magic == 0) { // shift path + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + uint64_t mask = (1ULL << shift) - 1; + __m512i roundToZeroTweak = _mm512_set1_epi64(mask); + // q = numer + ((numer >> 63) & roundToZeroTweak); + __m512i q = _mm512_add_epi64(numers, _mm512_and_si512(libdivide_s64_signbits(numers), roundToZeroTweak)); + q = libdivide_s64_shift_right_vector(q, shift); + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign); + return q; + } + else { + __m512i q = libdivide_mullhi_s64_vector(numers, _mm512_set1_epi64(magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm512_add_epi64(q, _mm512_sub_epi64(_mm512_xor_si512(numers, sign), sign)); + } + // q >>= denom->mult_path.shift + q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); + q = _mm512_add_epi64(q, _mm512_srli_epi64(q, 63)); // q += (q < 0) + return q; + } +} + +__m512i libdivide_s64_branchfree_do_vector(__m512i numers, const struct libdivide_s64_branchfree_t *denom) { + int64_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift + __m512i sign = _mm512_set1_epi32((int8_t)more >> 7); + + // libdivide_mullhi_s64(numers, magic); + __m512i q = libdivide_mullhi_s64_vector(numers, _mm512_set1_epi64(magic)); + q = _mm512_add_epi64(q, numers); // q += numers + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2. + uint32_t is_power_of_2 = (magic == 0); + __m512i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63 + __m512i mask = _mm512_set1_epi64((1ULL << shift) - is_power_of_2); + q = _mm512_add_epi64(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask) + q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift + q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +#elif defined(LIBDIVIDE_AVX2) + +static inline __m256i libdivide_u32_do_vector(__m256i numers, const struct libdivide_u32_t *denom); +static inline __m256i libdivide_s32_do_vector(__m256i numers, const struct libdivide_s32_t *denom); +static inline __m256i libdivide_u64_do_vector(__m256i numers, const struct libdivide_u64_t *denom); +static inline __m256i libdivide_s64_do_vector(__m256i numers, const struct libdivide_s64_t *denom); + +static inline __m256i libdivide_u32_branchfree_do_vector(__m256i numers, const struct libdivide_u32_branchfree_t *denom); +static inline __m256i libdivide_s32_branchfree_do_vector(__m256i numers, const struct libdivide_s32_branchfree_t *denom); +static inline __m256i libdivide_u64_branchfree_do_vector(__m256i numers, const struct libdivide_u64_branchfree_t *denom); +static inline __m256i libdivide_s64_branchfree_do_vector(__m256i numers, const struct libdivide_s64_branchfree_t *denom); + +//////// Internal Utility Functions + +// Implementation of _mm256_srai_epi64(v, 63) (from AVX512). +static inline __m256i libdivide_s64_signbits(__m256i v) { + __m256i hiBitsDuped = _mm256_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1)); + __m256i signBits = _mm256_srai_epi32(hiBitsDuped, 31); + return signBits; +} + +// Implementation of _mm256_srai_epi64 (from AVX512). +static inline __m256i libdivide_s64_shift_right_vector(__m256i v, int amt) { + const int b = 64 - amt; + __m256i m = _mm256_set1_epi64x(1ULL << (b - 1)); + __m256i x = _mm256_srli_epi64(v, amt); + __m256i result = _mm256_sub_epi64(_mm256_xor_si256(x, m), m); + return result; +} + +// Here, b is assumed to contain one 32-bit value repeated. +static inline __m256i libdivide_mullhi_u32_vector(__m256i a, __m256i b) { + __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epu32(a, b), 32); + __m256i a1X3X = _mm256_srli_epi64(a, 32); + __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0); + __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epu32(a1X3X, b), mask); + return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// b is one 32-bit value repeated. +static inline __m256i libdivide_mullhi_s32_vector(__m256i a, __m256i b) { + __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epi32(a, b), 32); + __m256i a1X3X = _mm256_srli_epi64(a, 32); + __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0); + __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epi32(a1X3X, b), mask); + return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// Here, y is assumed to contain one 64-bit value repeated. +// https://stackoverflow.com/a/28827013 +static inline __m256i libdivide_mullhi_u64_vector(__m256i x, __m256i y) { + __m256i lomask = _mm256_set1_epi64x(0xffffffff); + __m256i xh = _mm256_shuffle_epi32(x, 0xB1); // x0l, x0h, x1l, x1h + __m256i yh = _mm256_shuffle_epi32(y, 0xB1); // y0l, y0h, y1l, y1h + __m256i w0 = _mm256_mul_epu32(x, y); // x0l*y0l, x1l*y1l + __m256i w1 = _mm256_mul_epu32(x, yh); // x0l*y0h, x1l*y1h + __m256i w2 = _mm256_mul_epu32(xh, y); // x0h*y0l, x1h*y0l + __m256i w3 = _mm256_mul_epu32(xh, yh); // x0h*y0h, x1h*y1h + __m256i w0h = _mm256_srli_epi64(w0, 32); + __m256i s1 = _mm256_add_epi64(w1, w0h); + __m256i s1l = _mm256_and_si256(s1, lomask); + __m256i s1h = _mm256_srli_epi64(s1, 32); + __m256i s2 = _mm256_add_epi64(w2, s1l); + __m256i s2h = _mm256_srli_epi64(s2, 32); + __m256i hi = _mm256_add_epi64(w3, s1h); + hi = _mm256_add_epi64(hi, s2h); + + return hi; +} + +// y is one 64-bit value repeated. +static inline __m256i libdivide_mullhi_s64_vector(__m256i x, __m256i y) { + __m256i p = libdivide_mullhi_u64_vector(x, y); + __m256i t1 = _mm256_and_si256(libdivide_s64_signbits(x), y); + __m256i t2 = _mm256_and_si256(libdivide_s64_signbits(y), x); + p = _mm256_sub_epi64(p, t1); + p = _mm256_sub_epi64(p, t2); + return p; +} + +////////// UINT32 + +__m256i libdivide_u32_do_vector(__m256i numers, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm256_srli_epi32(numers, more); + } + else { + __m256i q = libdivide_mullhi_u32_vector(numers, _mm256_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q); + return _mm256_srli_epi32(t, shift); + } + else { + return _mm256_srli_epi32(q, more); + } + } +} + +__m256i libdivide_u32_branchfree_do_vector(__m256i numers, const struct libdivide_u32_branchfree_t *denom) { + __m256i q = libdivide_mullhi_u32_vector(numers, _mm256_set1_epi32(denom->magic)); + __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q); + return _mm256_srli_epi32(t, denom->more); +} + +////////// UINT64 + +__m256i libdivide_u64_do_vector(__m256i numers, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm256_srli_epi64(numers, more); + } + else { + __m256i q = libdivide_mullhi_u64_vector(numers, _mm256_set1_epi64x(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q); + return _mm256_srli_epi64(t, shift); + } + else { + return _mm256_srli_epi64(q, more); + } + } +} + +__m256i libdivide_u64_branchfree_do_vector(__m256i numers, const struct libdivide_u64_branchfree_t *denom) { + __m256i q = libdivide_mullhi_u64_vector(numers, _mm256_set1_epi64x(denom->magic)); + __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q); + return _mm256_srli_epi64(t, denom->more); +} + +////////// SINT32 + +__m256i libdivide_s32_do_vector(__m256i numers, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + uint32_t mask = (1U << shift) - 1; + __m256i roundToZeroTweak = _mm256_set1_epi32(mask); + // q = numer + ((numer >> 31) & roundToZeroTweak); + __m256i q = _mm256_add_epi32(numers, _mm256_and_si256(_mm256_srai_epi32(numers, 31), roundToZeroTweak)); + q = _mm256_srai_epi32(q, shift); + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign); + return q; + } + else { + __m256i q = libdivide_mullhi_s32_vector(numers, _mm256_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm256_add_epi32(q, _mm256_sub_epi32(_mm256_xor_si256(numers, sign), sign)); + } + // q >>= shift + q = _mm256_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK); + q = _mm256_add_epi32(q, _mm256_srli_epi32(q, 31)); // q += (q < 0) + return q; + } +} + +__m256i libdivide_s32_branchfree_do_vector(__m256i numers, const struct libdivide_s32_branchfree_t *denom) { + int32_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + __m256i q = libdivide_mullhi_s32_vector(numers, _mm256_set1_epi32(magic)); + q = _mm256_add_epi32(q, numers); // q += numers + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + __m256i q_sign = _mm256_srai_epi32(q, 31); // q_sign = q >> 31 + __m256i mask = _mm256_set1_epi32((1U << shift) - is_power_of_2); + q = _mm256_add_epi32(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask) + q = _mm256_srai_epi32(q, shift); // q >>= shift + q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +////////// SINT64 + +__m256i libdivide_s64_do_vector(__m256i numers, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + int64_t magic = denom->magic; + if (magic == 0) { // shift path + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + uint64_t mask = (1ULL << shift) - 1; + __m256i roundToZeroTweak = _mm256_set1_epi64x(mask); + // q = numer + ((numer >> 63) & roundToZeroTweak); + __m256i q = _mm256_add_epi64(numers, _mm256_and_si256(libdivide_s64_signbits(numers), roundToZeroTweak)); + q = libdivide_s64_shift_right_vector(q, shift); + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign); + return q; + } + else { + __m256i q = libdivide_mullhi_s64_vector(numers, _mm256_set1_epi64x(magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm256_add_epi64(q, _mm256_sub_epi64(_mm256_xor_si256(numers, sign), sign)); + } + // q >>= denom->mult_path.shift + q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); + q = _mm256_add_epi64(q, _mm256_srli_epi64(q, 63)); // q += (q < 0) + return q; + } +} + +__m256i libdivide_s64_branchfree_do_vector(__m256i numers, const struct libdivide_s64_branchfree_t *denom) { + int64_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift + __m256i sign = _mm256_set1_epi32((int8_t)more >> 7); + + // libdivide_mullhi_s64(numers, magic); + __m256i q = libdivide_mullhi_s64_vector(numers, _mm256_set1_epi64x(magic)); + q = _mm256_add_epi64(q, numers); // q += numers + + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2. + uint32_t is_power_of_2 = (magic == 0); + __m256i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63 + __m256i mask = _mm256_set1_epi64x((1ULL << shift) - is_power_of_2); + q = _mm256_add_epi64(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask) + q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift + q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +#elif defined(LIBDIVIDE_SSE2) + +static inline __m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom); +static inline __m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t *denom); +static inline __m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t *denom); +static inline __m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t *denom); + +static inline __m128i libdivide_u32_branchfree_do_vector(__m128i numers, const struct libdivide_u32_branchfree_t *denom); +static inline __m128i libdivide_s32_branchfree_do_vector(__m128i numers, const struct libdivide_s32_branchfree_t *denom); +static inline __m128i libdivide_u64_branchfree_do_vector(__m128i numers, const struct libdivide_u64_branchfree_t *denom); +static inline __m128i libdivide_s64_branchfree_do_vector(__m128i numers, const struct libdivide_s64_branchfree_t *denom); + +//////// Internal Utility Functions + +// Implementation of _mm_srai_epi64(v, 63) (from AVX512). +static inline __m128i libdivide_s64_signbits(__m128i v) { + __m128i hiBitsDuped = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1)); + __m128i signBits = _mm_srai_epi32(hiBitsDuped, 31); + return signBits; +} + +// Implementation of _mm_srai_epi64 (from AVX512). +static inline __m128i libdivide_s64_shift_right_vector(__m128i v, int amt) { + const int b = 64 - amt; + __m128i m = _mm_set1_epi64x(1ULL << (b - 1)); + __m128i x = _mm_srli_epi64(v, amt); + __m128i result = _mm_sub_epi64(_mm_xor_si128(x, m), m); + return result; +} + +// Here, b is assumed to contain one 32-bit value repeated. +static inline __m128i libdivide_mullhi_u32_vector(__m128i a, __m128i b) { + __m128i hi_product_0Z2Z = _mm_srli_epi64(_mm_mul_epu32(a, b), 32); + __m128i a1X3X = _mm_srli_epi64(a, 32); + __m128i mask = _mm_set_epi32(-1, 0, -1, 0); + __m128i hi_product_Z1Z3 = _mm_and_si128(_mm_mul_epu32(a1X3X, b), mask); + return _mm_or_si128(hi_product_0Z2Z, hi_product_Z1Z3); +} + +// SSE2 does not have a signed multiplication instruction, but we can convert +// unsigned to signed pretty efficiently. Again, b is just a 32 bit value +// repeated four times. +static inline __m128i libdivide_mullhi_s32_vector(__m128i a, __m128i b) { + __m128i p = libdivide_mullhi_u32_vector(a, b); + // t1 = (a >> 31) & y, arithmetic shift + __m128i t1 = _mm_and_si128(_mm_srai_epi32(a, 31), b); + __m128i t2 = _mm_and_si128(_mm_srai_epi32(b, 31), a); + p = _mm_sub_epi32(p, t1); + p = _mm_sub_epi32(p, t2); + return p; +} + +// Here, y is assumed to contain one 64-bit value repeated. +// https://stackoverflow.com/a/28827013 +static inline __m128i libdivide_mullhi_u64_vector(__m128i x, __m128i y) { + __m128i lomask = _mm_set1_epi64x(0xffffffff); + __m128i xh = _mm_shuffle_epi32(x, 0xB1); // x0l, x0h, x1l, x1h + __m128i yh = _mm_shuffle_epi32(y, 0xB1); // y0l, y0h, y1l, y1h + __m128i w0 = _mm_mul_epu32(x, y); // x0l*y0l, x1l*y1l + __m128i w1 = _mm_mul_epu32(x, yh); // x0l*y0h, x1l*y1h + __m128i w2 = _mm_mul_epu32(xh, y); // x0h*y0l, x1h*y0l + __m128i w3 = _mm_mul_epu32(xh, yh); // x0h*y0h, x1h*y1h + __m128i w0h = _mm_srli_epi64(w0, 32); + __m128i s1 = _mm_add_epi64(w1, w0h); + __m128i s1l = _mm_and_si128(s1, lomask); + __m128i s1h = _mm_srli_epi64(s1, 32); + __m128i s2 = _mm_add_epi64(w2, s1l); + __m128i s2h = _mm_srli_epi64(s2, 32); + __m128i hi = _mm_add_epi64(w3, s1h); + hi = _mm_add_epi64(hi, s2h); + + return hi; +} + +// y is one 64-bit value repeated. +static inline __m128i libdivide_mullhi_s64_vector(__m128i x, __m128i y) { + __m128i p = libdivide_mullhi_u64_vector(x, y); + __m128i t1 = _mm_and_si128(libdivide_s64_signbits(x), y); + __m128i t2 = _mm_and_si128(libdivide_s64_signbits(y), x); + p = _mm_sub_epi64(p, t1); + p = _mm_sub_epi64(p, t2); + return p; +} + +////////// UINT32 + +__m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm_srli_epi32(numers, more); + } + else { + __m128i q = libdivide_mullhi_u32_vector(numers, _mm_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q); + return _mm_srli_epi32(t, shift); + } + else { + return _mm_srli_epi32(q, more); + } + } +} + +__m128i libdivide_u32_branchfree_do_vector(__m128i numers, const struct libdivide_u32_branchfree_t *denom) { + __m128i q = libdivide_mullhi_u32_vector(numers, _mm_set1_epi32(denom->magic)); + __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q); + return _mm_srli_epi32(t, denom->more); +} + +////////// UINT64 + +__m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + return _mm_srli_epi64(numers, more); + } + else { + __m128i q = libdivide_mullhi_u64_vector(numers, _mm_set1_epi64x(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // uint32_t t = ((numer - q) >> 1) + q; + // return t >> denom->shift; + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q); + return _mm_srli_epi64(t, shift); + } + else { + return _mm_srli_epi64(q, more); + } + } +} + +__m128i libdivide_u64_branchfree_do_vector(__m128i numers, const struct libdivide_u64_branchfree_t *denom) { + __m128i q = libdivide_mullhi_u64_vector(numers, _mm_set1_epi64x(denom->magic)); + __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q); + return _mm_srli_epi64(t, denom->more); +} + +////////// SINT32 + +__m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t *denom) { + uint8_t more = denom->more; + if (!denom->magic) { + uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + uint32_t mask = (1U << shift) - 1; + __m128i roundToZeroTweak = _mm_set1_epi32(mask); + // q = numer + ((numer >> 31) & roundToZeroTweak); + __m128i q = _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak)); + q = _mm_srai_epi32(q, shift); + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign); + return q; + } + else { + __m128i q = libdivide_mullhi_s32_vector(numers, _mm_set1_epi32(denom->magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm_add_epi32(q, _mm_sub_epi32(_mm_xor_si128(numers, sign), sign)); + } + // q >>= shift + q = _mm_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK); + q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); // q += (q < 0) + return q; + } +} + +__m128i libdivide_s32_branchfree_do_vector(__m128i numers, const struct libdivide_s32_branchfree_t *denom) { + int32_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK; + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + __m128i q = libdivide_mullhi_s32_vector(numers, _mm_set1_epi32(magic)); + q = _mm_add_epi32(q, numers); // q += numers + + // If q is non-negative, we have nothing to do + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2 + uint32_t is_power_of_2 = (magic == 0); + __m128i q_sign = _mm_srai_epi32(q, 31); // q_sign = q >> 31 + __m128i mask = _mm_set1_epi32((1U << shift) - is_power_of_2); + q = _mm_add_epi32(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask) + q = _mm_srai_epi32(q, shift); // q >>= shift + q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign + return q; +} + +////////// SINT64 + +__m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t *denom) { + uint8_t more = denom->more; + int64_t magic = denom->magic; + if (magic == 0) { // shift path + uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + uint64_t mask = (1ULL << shift) - 1; + __m128i roundToZeroTweak = _mm_set1_epi64x(mask); + // q = numer + ((numer >> 63) & roundToZeroTweak); + __m128i q = _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak)); + q = libdivide_s64_shift_right_vector(q, shift); + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q = (q ^ sign) - sign; + q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign); + return q; + } + else { + __m128i q = libdivide_mullhi_s64_vector(numers, _mm_set1_epi64x(magic)); + if (more & LIBDIVIDE_ADD_MARKER) { + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); + // q += ((numer ^ sign) - sign); + q = _mm_add_epi64(q, _mm_sub_epi64(_mm_xor_si128(numers, sign), sign)); + } + // q >>= denom->mult_path.shift + q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK); q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); // q += (q < 0) return q; } } -__m128i libdivide_s64_do_vector_alg0(__m128i numers, const struct libdivide_s64_t *denom) { - uint32_t shifter = denom->more & LIBDIVIDE_64_SHIFT_MASK; - __m128i roundToZeroTweak = libdivide__u64_to_m128((1LL << shifter) - 1); - __m128i q = _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak)); - q = libdivide_s64_shift_right_vector(q, shifter); - return q; -} +__m128i libdivide_s64_branchfree_do_vector(__m128i numers, const struct libdivide_s64_branchfree_t *denom) { + int64_t magic = denom->magic; + uint8_t more = denom->more; + uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK; + // must be arithmetic shift + __m128i sign = _mm_set1_epi32((int8_t)more >> 7); -__m128i libdivide_s64_do_vector_alg1(__m128i numers, const struct libdivide_s64_t *denom) { - uint32_t shifter = denom->more & LIBDIVIDE_64_SHIFT_MASK; - __m128i roundToZeroTweak = libdivide__u64_to_m128((1LL << shifter) - 1); - __m128i q = _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak)); - q = libdivide_s64_shift_right_vector(q, shifter); - return _mm_sub_epi64(_mm_setzero_si128(), q); -} + // libdivide_mullhi_s64(numers, magic); + __m128i q = libdivide_mullhi_s64_vector(numers, _mm_set1_epi64x(magic)); + q = _mm_add_epi64(q, numers); // q += numers -__m128i libdivide_s64_do_vector_alg2(__m128i numers, const struct libdivide_s64_t *denom) { - __m128i q = libdivide_mullhi_s64_flat_vector(numers, libdivide__u64_to_m128(denom->magic)); - q = _mm_add_epi64(q, numers); - q = libdivide_s64_shift_right_vector(q, denom->more & LIBDIVIDE_64_SHIFT_MASK); - q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); // q += (q < 0) - return q; -} - -__m128i libdivide_s64_do_vector_alg3(__m128i numers, const struct libdivide_s64_t *denom) { - __m128i q = libdivide_mullhi_s64_flat_vector(numers, libdivide__u64_to_m128(denom->magic)); - q = _mm_sub_epi64(q, numers); - q = libdivide_s64_shift_right_vector(q, denom->more & LIBDIVIDE_64_SHIFT_MASK); - q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); // q += (q < 0) - return q; -} - -__m128i libdivide_s64_do_vector_alg4(__m128i numers, const struct libdivide_s64_t *denom) { - __m128i q = libdivide_mullhi_s64_flat_vector(numers, libdivide__u64_to_m128(denom->magic)); - q = libdivide_s64_shift_right_vector(q, denom->more); - q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); + // If q is non-negative, we have nothing to do. + // If q is negative, we want to add either (2**shift)-1 if d is + // a power of 2, or (2**shift) if it is not a power of 2. + uint32_t is_power_of_2 = (magic == 0); + __m128i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63 + __m128i mask = _mm_set1_epi64x((1ULL << shift) - is_power_of_2); + q = _mm_add_epi64(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask) + q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift + q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign return q; } @@ -1204,228 +1930,143 @@ __m128i libdivide_s64_do_vector_alg4(__m128i numers, const struct libdivide_s64_ #ifdef __cplusplus -/* The C++ template design here is a total mess. This needs to be fixed by someone better at templates than I. The current design is: - -- The base is a template divider_base that takes the integer type, the libdivide struct, a generating function, a get algorithm function, a do function, and either a do vector function or a dummy int. -- The base has storage for the libdivide struct. This is the only storage (so the C++ class should be no larger than the libdivide struct). - -- Above that, there's divider_mid. This is an empty struct by default, but it is specialized against our four int types. divider_mid contains a template struct algo, that contains a typedef for a specialization of divider_base. struct algo is specialized to take an "algorithm number," where -1 means to use the general algorithm. - -- Publicly we have class divider, which inherits from divider_mid::algo. This also take an algorithm number, which defaults to -1 (the general algorithm). -- divider has a operator / which allows you to use a divider as the divisor in a quotient expression. - -*/ - -namespace libdivide_internal { - -#if LIBDIVIDE_USE_SSE2 -#define MAYBE_VECTOR(x) x -#define MAYBE_VECTOR_PARAM __m128i vector_func(__m128i, const DenomType *) -#else -#define MAYBE_VECTOR(x) 0 -#define MAYBE_VECTOR_PARAM int vector_func -#endif - - /* Some bogus unswitch functions for unsigned types so the same (presumably templated) code can work for both signed and unsigned. */ - uint32_t crash_u32(uint32_t, const libdivide_u32_t *) { abort(); } - uint64_t crash_u64(uint64_t, const libdivide_u64_t *) { abort(); } -#ifdef __APPLE__ - UInt64 crash_u64(UInt64, const libdivide_u64_t *) { abort(); } -#endif -#if LIBDIVIDE_USE_SSE2 - __m128i crash_u32_vector(__m128i, const libdivide_u32_t *) { abort(); } - __m128i crash_u64_vector(__m128i, const libdivide_u64_t *) { abort(); } -#endif - - template - class divider_base { - public: - DenomType denom; - divider_base(IntType d) : denom(gen_func(d)) { } - divider_base(const DenomType & d) : denom(d) { } - - IntType perform_divide(IntType val) const { return do_func(val, &denom); } -#if LIBDIVIDE_USE_SSE2 - __m128i perform_divide_vector(__m128i val) const { return vector_func(val, &denom); } -#endif - - int get_algorithm() const { return get_algo(&denom); } - }; - - - template struct divider_mid { }; - - template<> struct divider_mid { - typedef uint32_t IntType; - typedef struct libdivide_u32_t DenomType; - template struct denom { - typedef divider_base divider; - }; - - template struct algo { }; - template struct algo<-1, J> { typedef denom::divider divider; }; - template struct algo<0, J> { typedef denom::divider divider; }; - template struct algo<1, J> { typedef denom::divider divider; }; - template struct algo<2, J> { typedef denom::divider divider; }; - - /* Define two more bogus ones so that the same (templated, presumably) code can handle both signed and unsigned */ - template struct algo<3, J> { typedef denom::divider divider; }; - template struct algo<4, J> { typedef denom::divider divider; }; - - }; - - template<> struct divider_mid { - typedef int32_t IntType; - typedef struct libdivide_s32_t DenomType; - template struct denom { - typedef divider_base divider; - }; - - - template struct algo { }; - template struct algo<-1, J> { typedef denom::divider divider; }; - template struct algo<0, J> { typedef denom::divider divider; }; - template struct algo<1, J> { typedef denom::divider divider; }; - template struct algo<2, J> { typedef denom::divider divider; }; - template struct algo<3, J> { typedef denom::divider divider; }; - template struct algo<4, J> { typedef denom::divider divider; }; - - }; - -#ifdef __APPLE__ - template<> struct divider_mid { - typedef Int64 IntType; - typedef struct libdivide_s64_t DenomType; - template struct denom { - typedef divider_base divider; - }; - - template struct algo { }; - template struct algo<-1, J> { typedef denom::divider divider; }; - template struct algo<0, J> { typedef denom::divider divider; }; - template struct algo<1, J> { typedef denom::divider divider; }; - template struct algo<2, J> { typedef denom::divider divider; }; - template struct algo<3, J> { typedef denom::divider divider; }; - template struct algo<4, J> { typedef denom::divider divider; }; - }; - - template<> struct divider_mid { - typedef UInt64 IntType; - typedef struct libdivide_u64_t DenomType; - template struct denom { - typedef divider_base divider; - }; - - template struct algo { }; - template struct algo<-1, J> { typedef denom::divider divider; }; - template struct algo<0, J> { typedef denom::divider divider; }; - template struct algo<1, J> { typedef denom::divider divider; }; - template struct algo<2, J> { typedef denom::divider divider; }; - - /* Define two more bogus ones so that the same (templated, presumably) code can handle both signed and unsigned */ - template struct algo<3, J> { typedef denom::divider divider; }; - template struct algo<4, J> { typedef denom::divider divider; }; - - - }; -#endif - - template<> struct divider_mid { - typedef uint64_t IntType; - typedef struct libdivide_u64_t DenomType; - template struct denom { - typedef divider_base divider; - }; - - template struct algo { }; - template struct algo<-1, J> { typedef denom::divider divider; }; - template struct algo<0, J> { typedef denom::divider divider; }; - template struct algo<1, J> { typedef denom::divider divider; }; - template struct algo<2, J> { typedef denom::divider divider; }; - - /* Define two more bogus ones so that the same (templated, presumably) code can handle both signed and unsigned */ - template struct algo<3, J> { typedef denom::divider divider; }; - template struct algo<4, J> { typedef denom::divider divider; }; - - - }; - - template<> struct divider_mid { - typedef int64_t IntType; - typedef struct libdivide_s64_t DenomType; - template struct denom { - typedef divider_base divider; - }; - - template struct algo { }; - template struct algo<-1, J> { typedef denom::divider divider; }; - template struct algo<0, J> { typedef denom::divider divider; }; - template struct algo<1, J> { typedef denom::divider divider; }; - template struct algo<2, J> { typedef denom::divider divider; }; - template struct algo<3, J> { typedef denom::divider divider; }; - template struct algo<4, J> { typedef denom::divider divider; }; - }; - -} - -template -class divider -{ - private: - typename libdivide_internal::divider_mid::template algo::divider sub; - template friend divider unswitch(const divider & d); - divider(const typename libdivide_internal::divider_mid::DenomType & denom) : sub(denom) { } - - public: - - /* Ordinary constructor, that takes the divisor as a parameter. */ - divider(T n) : sub(n) { } - - /* Default constructor, that divides by 1 */ - divider() : sub(1) { } - - /* Divides the parameter by the divisor, returning the quotient */ - T perform_divide(T val) const { return sub.perform_divide(val); } - -#if LIBDIVIDE_USE_SSE2 - /* Treats the vector as either two or four packed values (depending on the size), and divides each of them by the divisor, returning the packed quotients. */ - __m128i perform_divide_vector(__m128i val) const { return sub.perform_divide_vector(val); } -#endif - - /* Returns the index of algorithm, for use in the unswitch function */ - int get_algorithm() const { return sub.get_algorithm(); } // returns the algorithm for unswitching - - /* operator== */ - bool operator==(const divider & him) const { return sub.denom.magic == him.sub.denom.magic && sub.denom.more == him.sub.denom.more; } - - bool operator!=(const divider & him) const { return ! (*this == him); } +// The C++ divider class is templated on both an integer type +// (like uint64_t) and an algorithm type. +// * BRANCHFULL is the default algorithm type. +// * BRANCHFREE is the branchfree algorithm type. +enum { + BRANCHFULL, + BRANCHFREE }; -/* Returns a divider specialized for the given algorithm. */ -template -divider unswitch(const divider & d) { return divider(d.sub.denom); } - -/* Overload of the / operator for scalar division. */ -template -int_type operator/(int_type numer, const divider & denom) { - return denom.perform_divide(numer); -} - -#if LIBDIVIDE_USE_SSE2 -/* Overload of the / operator for vector division. */ -template -__m128i operator/(__m128i numer, const divider & denom) { - return denom.perform_divide_vector(numer); -} +#if defined(LIBDIVIDE_AVX512) + #define LIBDIVIDE_VECTOR_TYPE __m512i +#elif defined(LIBDIVIDE_AVX2) + #define LIBDIVIDE_VECTOR_TYPE __m256i +#elif defined(LIBDIVIDE_SSE2) + #define LIBDIVIDE_VECTOR_TYPE __m128i #endif - -#endif //__cplusplus - -#endif //LIBDIVIDE_HEADER_ONLY -#ifdef __cplusplus -} //close namespace libdivide -} //close anonymous namespace +#if !defined(LIBDIVIDE_VECTOR_TYPE) + #define LIBDIVIDE_DIVIDE_VECTOR(ALGO) +#else + #define LIBDIVIDE_DIVIDE_VECTOR(ALGO) \ + LIBDIVIDE_VECTOR_TYPE divide(LIBDIVIDE_VECTOR_TYPE n) const { \ + return libdivide_##ALGO##_do_vector(n, &denom); \ + } #endif -#pragma GCC diagnostic pop +// The DISPATCHER_GEN() macro generates C++ methods (for the given integer +// and algorithm types) that redirect to libdivide's C API. +#define DISPATCHER_GEN(T, ALGO) \ + libdivide_##ALGO##_t denom; \ + dispatcher() { } \ + dispatcher(T d) \ + : denom(libdivide_##ALGO##_gen(d)) \ + { } \ + T divide(T n) const { \ + return libdivide_##ALGO##_do(n, &denom); \ + } \ + LIBDIVIDE_DIVIDE_VECTOR(ALGO) \ + T recover() const { \ + return libdivide_##ALGO##_recover(&denom); \ + } + +// The dispatcher selects a specific division algorithm for a given +// type and ALGO using partial template specialization. +template struct dispatcher { }; + +template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32) }; +template<> struct dispatcher { DISPATCHER_GEN(int32_t, s32_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32) }; +template<> struct dispatcher { DISPATCHER_GEN(uint32_t, u32_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64) }; +template<> struct dispatcher { DISPATCHER_GEN(int64_t, s64_branchfree) }; +template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64) }; +template<> struct dispatcher { DISPATCHER_GEN(uint64_t, u64_branchfree) }; + +// This is the main divider class for use by the user (C++ API). +// The actual division algorithm is selected using the dispatcher struct +// based on the integer and algorithm template parameters. +template +class divider { +public: + // We leave the default constructor empty so that creating + // an array of dividers and then initializing them + // later doesn't slow us down. + divider() { } + + // Constructor that takes the divisor as a parameter + divider(T d) : div(d) { } + + // Divides n by the divisor + T divide(T n) const { + return div.divide(n); + } + + // Recovers the divisor, returns the value that was + // used to initialize this divider object. + T recover() const { + return div.recover(); + } + + bool operator==(const divider& other) const { + return div.denom.magic == other.denom.magic && + div.denom.more == other.denom.more; + } + + bool operator!=(const divider& other) const { + return !(*this == other); + } + +#if defined(LIBDIVIDE_VECTOR_TYPE) + // Treats the vector as packed integer values with the same type as + // the divider (e.g. s32, u32, s64, u64) and divides each of + // them by the divider, returning the packed quotients. + LIBDIVIDE_VECTOR_TYPE divide(LIBDIVIDE_VECTOR_TYPE n) const { + return div.divide(n); + } +#endif + +private: + // Storage for the actual divisor + dispatcher::value, + std::is_signed::value, sizeof(T), ALGO> div; +}; + +// Overload of operator / for scalar division +template +T operator/(T n, const divider& div) { + return div.divide(n); +} + +// Overload of operator /= for scalar division +template +T& operator/=(T& n, const divider& div) { + n = div.divide(n); + return n; +} + +#if defined(LIBDIVIDE_VECTOR_TYPE) + // Overload of operator / for vector division + template + LIBDIVIDE_VECTOR_TYPE operator/(LIBDIVIDE_VECTOR_TYPE n, const divider& div) { + return div.divide(n); + } + // Overload of operator /= for vector division + template + LIBDIVIDE_VECTOR_TYPE& operator/=(LIBDIVIDE_VECTOR_TYPE& n, const divider& div) { + n = div.divide(n); + return n; + } +#endif + +// libdivdie::branchfree_divider +template +using branchfree_divider = divider; + +} // namespace libdivide + +#endif // __cplusplus + +#endif // LIBDIVIDE_H diff --git a/src/Functions/intDiv.cpp b/src/Functions/intDiv.cpp index 0b6734c0136..062a374c00f 100644 --- a/src/Functions/intDiv.cpp +++ b/src/Functions/intDiv.cpp @@ -1,8 +1,9 @@ #include #include -#ifdef __SSE2__ - #define LIBDIVIDE_USE_SSE2 1 +#if defined(__SSE2__) +# define LIBDIVIDE_SSE2 1 +# define LIBDIVIDE_VECTOR_TYPE #endif #include @@ -45,7 +46,7 @@ struct DivideIntegralByConstantImpl const A * a_end = a_pos + size; -#ifdef __SSE2__ +#if defined(__SSE2__) static constexpr size_t values_per_sse_register = 16 / sizeof(A); const A * a_end_sse = a_pos + size / values_per_sse_register * values_per_sse_register; diff --git a/src/Functions/modulo.cpp b/src/Functions/modulo.cpp index 9e4409ca91b..631b7d12263 100644 --- a/src/Functions/modulo.cpp +++ b/src/Functions/modulo.cpp @@ -1,8 +1,8 @@ #include #include -#ifdef __SSE2__ - #define LIBDIVIDE_USE_SSE2 1 +#if defined(__SSE2__) +# define LIBDIVIDE_SSE2 1 #endif #include diff --git a/src/Interpreters/createBlockSelector.cpp b/src/Interpreters/createBlockSelector.cpp index 2b08ca0845c..0759b9d9601 100644 --- a/src/Interpreters/createBlockSelector.cpp +++ b/src/Interpreters/createBlockSelector.cpp @@ -5,8 +5,8 @@ #include -#ifdef __SSE2__ - #define LIBDIVIDE_USE_SSE2 1 +#if defined(__SSE2__) +# define LIBDIVIDE_SSE2 1 #endif #include From 19bb2976b9f82eec86965f6dad0d5934f8eee826 Mon Sep 17 00:00:00 2001 From: Ivan <5627721+abyss7@users.noreply.github.com> Date: Sat, 11 Apr 2020 14:16:14 +0300 Subject: [PATCH 093/208] Update pdqsort to recent version (#10171) --- contrib/pdqsort/pdqsort.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/contrib/pdqsort/pdqsort.h b/contrib/pdqsort/pdqsort.h index 31eb06fece4..01e82b710ee 100644 --- a/contrib/pdqsort/pdqsort.h +++ b/contrib/pdqsort/pdqsort.h @@ -124,11 +124,9 @@ namespace pdqsort_detail { inline bool partial_insertion_sort(Iter begin, Iter end, Compare comp) { typedef typename std::iterator_traits::value_type T; if (begin == end) return true; - - int limit = 0; - for (Iter cur = begin + 1; cur != end; ++cur) { - if (limit > partial_insertion_sort_limit) return false; + std::size_t limit = 0; + for (Iter cur = begin + 1; cur != end; ++cur) { Iter sift = cur; Iter sift_1 = cur - 1; @@ -142,6 +140,8 @@ namespace pdqsort_detail { *sift = PDQSORT_PREFER_MOVE(tmp); limit += cur - sift; } + + if (limit > partial_insertion_sort_limit) return false; } return true; @@ -232,7 +232,7 @@ namespace pdqsort_detail { unsigned char* offsets_r = align_cacheline(offsets_r_storage); int num_l, num_r, start_l, start_r; num_l = num_r = start_l = start_r = 0; - + while (last - first > 2 * block_size) { // Fill up offset blocks with elements that are on the wrong side. if (num_l == 0) { @@ -275,7 +275,7 @@ namespace pdqsort_detail { } int l_size = 0, r_size = 0; - int unknown_left = (last - first) - ((num_r || num_l) ? block_size : 0); + int unknown_left = (int)(last - first) - ((num_r || num_l) ? block_size : 0); if (num_r) { // Handle leftover block by assigning the unknown elements to the other block. l_size = unknown_left; @@ -311,7 +311,7 @@ namespace pdqsort_detail { start_l += num; start_r += num; if (num_l == 0) first += l_size; if (num_r == 0) last -= r_size; - + // We have now fully identified [first, last)'s proper position. Swap the last elements. if (num_l) { offsets_l += start_l; @@ -340,7 +340,7 @@ namespace pdqsort_detail { template inline std::pair partition_right(Iter begin, Iter end, Compare comp) { typedef typename std::iterator_traits::value_type T; - + // Move pivot into local for speed. T pivot(PDQSORT_PREFER_MOVE(*begin)); @@ -359,7 +359,7 @@ namespace pdqsort_detail { // If the first pair of elements that should be swapped to partition are the same element, // the passed in sequence already was correctly partitioned. bool already_partitioned = first >= last; - + // Keep swapping pairs of elements that are on the wrong side of the pivot. Previously // swapped pairs guard the searches, which is why the first iteration is special-cased // above. @@ -388,7 +388,7 @@ namespace pdqsort_detail { T pivot(PDQSORT_PREFER_MOVE(*begin)); Iter first = begin; Iter last = end; - + while (comp(pivot, *--last)); if (last + 1 == end) while (first < last && !comp(pivot, *++first)); @@ -475,11 +475,11 @@ namespace pdqsort_detail { std::iter_swap(pivot_pos - 3, pivot_pos - (l_size / 4 + 2)); } } - + if (r_size >= insertion_sort_threshold) { std::iter_swap(pivot_pos + 1, pivot_pos + (1 + r_size / 4)); std::iter_swap(end - 1, end - r_size / 4); - + if (r_size > ninther_threshold) { std::iter_swap(pivot_pos + 2, pivot_pos + (2 + r_size / 4)); std::iter_swap(pivot_pos + 3, pivot_pos + (3 + r_size / 4)); @@ -493,7 +493,7 @@ namespace pdqsort_detail { if (already_partitioned && partial_insertion_sort(begin, pivot_pos, comp) && partial_insertion_sort(pivot_pos + 1, end, comp)) return; } - + // Sort the left partition first using recursion and do tail recursion elimination for // the right-hand partition. pdqsort_loop(begin, pivot_pos, comp, bad_allowed, leftmost); From 1484ab1f1a0b63e2d7816b66a9375682f73cf8a6 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 17:52:59 +0300 Subject: [PATCH 094/208] Fix machine translation #10191 --- docs/ru/development/architecture.md | 202 +- docs/ru/development/build.md | 140 +- docs/ru/development/build_cross_arm.md | 42 +- docs/ru/development/build_cross_osx.md | 63 +- docs/ru/development/build_osx.md | 92 +- docs/ru/development/index.md | 9 +- docs/ru/development/tests.md | 251 +- .../engines/table_engines/special/generate.md | 60 +- docs/ru/getting_started/tutorial.md | 670 +----- docs/ru/introduction/adopters.md | 81 +- .../sampling_query_profiler.md | 63 +- docs/ru/operations/performance_test.md | 81 +- .../utilities/clickhouse-benchmark.md | 155 +- docs/ru/whats_new/changelog/2017.md | 267 +-- docs/ru/whats_new/changelog/2018.md | 1062 +-------- docs/ru/whats_new/changelog/2019.md | 2073 +---------------- docs/ru/whats_new/roadmap.md | 18 +- 17 files changed, 17 insertions(+), 5312 deletions(-) mode change 100644 => 120000 docs/ru/development/architecture.md mode change 100644 => 120000 docs/ru/development/build.md mode change 100644 => 120000 docs/ru/development/build_cross_arm.md mode change 100644 => 120000 docs/ru/development/build_cross_osx.md mode change 100644 => 120000 docs/ru/development/build_osx.md mode change 100644 => 120000 docs/ru/development/index.md mode change 100644 => 120000 docs/ru/development/tests.md mode change 100644 => 120000 docs/ru/engines/table_engines/special/generate.md mode change 100644 => 120000 docs/ru/getting_started/tutorial.md mode change 100644 => 120000 docs/ru/introduction/adopters.md mode change 100644 => 120000 docs/ru/operations/optimizing_performance/sampling_query_profiler.md mode change 100644 => 120000 docs/ru/operations/performance_test.md mode change 100644 => 120000 docs/ru/operations/utilities/clickhouse-benchmark.md mode change 100644 => 120000 docs/ru/whats_new/changelog/2017.md mode change 100644 => 120000 docs/ru/whats_new/changelog/2018.md mode change 100644 => 120000 docs/ru/whats_new/changelog/2019.md mode change 100644 => 120000 docs/ru/whats_new/roadmap.md diff --git a/docs/ru/development/architecture.md b/docs/ru/development/architecture.md deleted file mode 100644 index 0d1fc2ff947..00000000000 --- a/docs/ru/development/architecture.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Обзор архитектуры ClickHouse {#overview-of-clickhouse-architecture} - -ClickHouse-это настоящая СУБД, ориентированная на столбцы. Данные хранятся столбцами и во время выполнения массивов (векторов или кусков столбцов). Когда это возможно, операции отправляются на массивы, а не на отдельные значения. Это называется «vectorized query execution,» и это помогает снизить стоимость фактической обработки данных. - -> В этой идее нет ничего нового. Она восходит к тому времени, когда `APL` язык программирования и его потомки: `A +`, `J`, `K`, и `Q`. Массивное программирование используется в научной обработке данных. Эта идея также не является чем-то новым в реляционных базах данных: например, она используется в `Vectorwise` система. - -Существует два различных подхода для ускорения обработки запросов: векторизованное выполнение запросов и генерация кода во время выполнения. Последнее устраняет все косвенные действия и динамическую диспетчеризацию. Ни один из этих подходов не является строго лучшим, чем другой. Генерация кода во время выполнения может быть лучше, когда он объединяет множество операций, таким образом полностью используя исполнительные блоки процессора и конвейер. Векторизованное выполнение запроса может быть менее практичным, поскольку оно включает временные векторы, которые должны быть записаны в кэш и считаны обратно. Если временные данные не помещаются в кэш L2, это становится проблемой. Но векторизованное выполнение запросов более легко использует возможности SIMD центрального процессора. Один [научная статья](http://15721.courses.cs.cmu.edu/spring2016/papers/p5-sompolski.pdf) написанное нашими друзьями показывает, что лучше сочетать оба подхода. ClickHouse использует векторизованное выполнение запросов и имеет ограниченную начальную поддержку для генерации кода во время выполнения. - -## Столбцы {#columns} - -`IColumn` интерфейс используется для представления столбцов в памяти (собственно, кусков столбцов). Этот интерфейс предоставляет вспомогательные методы для реализации различных реляционных операторов. Почти все операции неизменяемы: они не изменяют исходный столбец, а создают новый измененный. Например, в `IColumn :: filter` метод принимает маску байта фильтра. Он используется для `WHERE` и `HAVING` реляционный оператор. Дополнительные примеры: `IColumn :: permute` способ поддержки `ORDER BY`, этот `IColumn :: cut` способ поддержки `LIMIT`. - -Различный `IColumn` реализации (`ColumnUInt8`, `ColumnString`, и так далее) отвечают за расположение столбцов в памяти. Расположение памяти обычно представляет собой непрерывный массив. Для целочисленного типа столбцов это всего лишь один непрерывный массив, например `std :: vector`. Для `String` и `Array` столбцы, это два вектора: один для всех элементов массива, расположенных последовательно, и второй для смещений к началу каждого массива. Существует также `ColumnConst` это сохраняет только одно значение в памяти, но выглядит как столбец. - -## Поле {#field} - -Тем не менее, можно работать и с индивидуальными ценностями. Чтобы представить индивидуальную ценность, то `Field` предназначенный. `Field` это просто дискриминированный Союз `UInt64`, `Int64`, `Float64`, `String` и `Array`. `IColumn` имеет `operator[]` метод получения n-го значения в виде a `Field` и `insert` способ, чтобы добавить `Field` до самого конца колонны. Эти методы не очень эффективны, потому что они требуют решения временных проблем `Field` объекты, представляющие индивидуальную ценность. Существуют и более эффективные методы, такие как `insertFrom`, `insertRangeFrom` и так далее. - -`Field` у него нет достаточной информации о конкретном типе данных для таблицы. Например, `UInt8`, `UInt16`, `UInt32`, и `UInt64` все они представлены в виде `UInt64` в `Field`. - -## Дырявые абстракции {#leaky-abstractions} - -`IColumn` есть методы для общих реляционных преобразований данных, но они не удовлетворяют всем потребностям. Например, `ColumnUInt64` не имеет метода для вычисления суммы двух столбцов, и `ColumnString` у него нет метода для запуска поиска по подстрокам. Эти бесчисленные процедуры реализуются за пределами `IColumn`. - -Различные функции на столбцах могут быть реализованы общим, неэффективным способом с использованием `IColumn` способы извлечения `Field` значения, или специализированным способом, использующим знание внутренней компоновки памяти данных в определенном месте. `IColumn` реализация. Он реализуется путем приведения функций к определенному виду `IColumn` тип и дело с внутренним представлением непосредственно. Например, `ColumnUInt64` имеет `getData` метод, который возвращает ссылку на внутренний массив, а затем отдельная процедура считывает или заполняет этот массив непосредственно. У нас есть «leaky abstractions» чтобы обеспечить эффективную специализацию различных процедур. - -## Тип данных {#data_types} - -`IDataType` отвечает за сериализацию и десериализацию: чтение и запись фрагментов столбцов или отдельных значений в двоичной или текстовой форме. `IDataType` непосредственно соответствует типам данных в таблицах. Например, существуют `DataTypeUInt32`, `DataTypeDateTime`, `DataTypeString` и так далее. - -`IDataType` и `IColumn` они лишь слабо связаны друг с другом. Различные типы данных могут быть представлены в памяти одним и тем же именем `IColumn` реализации. Например, `DataTypeUInt32` и `DataTypeDateTime` оба они представлены следующим образом `ColumnUInt32` или `ColumnConstUInt32`. Кроме того, один и тот же тип данных может быть представлен разными `IColumn` реализации. Например, `DataTypeUInt8` может быть представлен следующим образом `ColumnUInt8` или `ColumnConstUInt8`. - -`IDataType` хранит только метаданные. Например, `DataTypeUInt8` не хранит вообще ничего (кроме vptr) и `DataTypeFixedString` магазины просто `N` (размер строк фиксированного размера). - -`IDataType` имеет вспомогательные методы для различных форматов данных. Примерами являются методы сериализации значения с возможным цитированием, сериализации значения для JSON и сериализации значения в формате XML. Прямого соответствия форматам данных не существует. Например, различные форматы данных `Pretty` и `TabSeparated` можно использовать то же самое `serializeTextEscaped` вспомогательный метод от `IDataType` интерфейс. - -## Блок {#block} - -A `Block` это контейнер, представляющий подмножество (фрагмент) таблицы в памяти. Это всего лишь набор троек: `(IColumn, IDataType, column name)`. Во время выполнения запроса данные обрабатываются с помощью `Block`s. Если у нас есть `Block`, у нас есть данные (в `IColumn` объект), у нас есть информация о его типе (в `IDataType`) это говорит нам, как обращаться с этим столбцом, и у нас есть имя столбца. Это может быть либо исходное имя столбца из таблицы, либо какое-то искусственное имя, назначенное для получения временных результатов вычислений. - -Когда мы вычисляем некоторую функцию по столбцам в блоке, мы добавляем другой столбец с его результатом в блок, и мы не касаемся столбцов для аргументов функции, потому что операции неизменяемы. Позже ненужные столбцы могут быть удалены из блока, но не изменены. Это удобно для исключения общих подвыражений. - -Блоки создаются для каждого обработанного фрагмента данных. Обратите внимание, что для одного и того же типа вычисления имена столбцов и типы остаются одинаковыми для разных блоков, и изменяются только данные столбцов. Лучше разделить данные блока из заголовка блока, потому что небольшие размеры блока имеют высокую нагрузку временных строк для копирования shared\_ptrs и имен столбцов. - -## Блокировать Потоки {#block-streams} - -Блочные потоки предназначены для обработки данных. Мы используем потоки блоков для чтения данных откуда-то, выполнения преобразований данных или записи данных куда-то. `IBlockInputStream` имеет `read` метод для извлечения следующего блока, пока он доступен. `IBlockOutputStream` имеет `write` метод, чтобы подтолкнуть блок куда-то. - -Потоки отвечают за: - -1. Чтение или письмо за столом. Таблица просто возвращает поток для чтения или записи блоков. -2. Реализация форматов данных. Например, если вы хотите вывести данные на терминал в `Pretty` форматирование, вы создаете поток вывода блока, где вы толкаете блоки, и он форматирует их. -3. Выполнение преобразований данных. Скажем так у вас есть `IBlockInputStream` и хотите создать отфильтрованный поток. Вы создаете `FilterBlockInputStream` и инициализируйте его с помощью своего потока. Затем, когда вы вытащите блок из `FilterBlockInputStream`, он извлекает блок из вашего потока, фильтрует его и возвращает отфильтрованный блок вам. Конвейеры выполнения запросов представлены таким образом. - -Есть и более сложные трансформации. Например, когда вы тянете из `AggregatingBlockInputStream`, он считывает все данные из своего источника, агрегирует их, а затем возвращает поток агрегированных данных для вас. Еще пример: `UnionBlockInputStream` принимает множество источников ввода в конструкторе, а также ряд потоков. Он запускает несколько потоков и читает из нескольких источников параллельно. - -> Потоки блокируют использовать «pull» подход к управлению потоком: когда вы вытягиваете блок из первого потока, он, следовательно, вытягивает необходимые блоки из вложенных потоков, и весь конвейер выполнения будет работать. Ни «pull» ни «push» это лучшее решение, потому что поток управления является неявным, и это ограничивает реализацию различных функций, таких как одновременное выполнение нескольких запросов (объединение многих конвейеров вместе). Это ограничение может быть преодолено с помощью сопрограмм или просто запуском дополнительных потоков, которые ждут друг друга. У нас может быть больше возможностей, если мы сделаем поток управления явным: если мы найдем логику для передачи данных из одной расчетной единицы в другую вне этих расчетных единиц. Читать это [статья](http://journal.stuffwithstuff.com/2013/01/13/iteration-inside-and-out/) для новых мыслей. - -Следует отметить, что конвейер выполнения запроса создает временные данные на каждом шаге. Мы стараемся держать размер блока достаточно маленьким, чтобы временные данные помещались в кэш процессора. При таком допущении запись и чтение временных данных практически бесплатны по сравнению с другими расчетами. Мы могли бы рассмотреть альтернативу, которая заключается в том, чтобы объединить многие операции в трубопроводе вместе. Это может сделать конвейер как можно короче и удалить большую часть временных данных, что может быть преимуществом, но у него также есть недостатки. Например, разделенный конвейер позволяет легко реализовать кэширование промежуточных данных, кражу промежуточных данных из аналогичных запросов, выполняемых одновременно, и объединение конвейеров для аналогичных запросов. - -## Форматы {#formats} - -Форматы данных реализуются с помощью блочных потоков. Есть «presentational» форматы, пригодные только для вывода данных клиенту, такие как `Pretty` формат, который предоставляет только `IBlockOutputStream`. И есть форматы ввода/вывода, такие как `TabSeparated` или `JSONEachRow`. - -Существуют также потоки подряд : `IRowInputStream` и `IRowOutputStream`. Они позволяют вытягивать / выталкивать данные отдельными строками, а не блоками. И они нужны только для упрощения реализации ориентированных на строки форматов. Обертка `BlockInputStreamFromRowInputStream` и `BlockOutputStreamFromRowOutputStream` позволяет конвертировать потоки, ориентированные на строки, в обычные потоки, ориентированные на блоки. - -## I/O {#io} - -Для байт-ориентированных входов / выходов существуют `ReadBuffer` и `WriteBuffer` абстрактный класс. Они используются вместо C++ `iostream`s. Не волнуйтесь: каждый зрелый проект C++ использует что-то другое, чем `iostream`s по уважительным причинам. - -`ReadBuffer` и `WriteBuffer` это просто непрерывный буфер и курсор, указывающий на позицию в этом буфере. Реализации могут владеть или не владеть памятью для буфера. Существует виртуальный метод заполнения буфера следующими данными (для `ReadBuffer`) или смыть буфер куда-нибудь (например `WriteBuffer`). Виртуальные методы редко вызываются. - -Реализация следующих принципов: `ReadBuffer`/`WriteBuffer` используются для работы с файлами и файловыми дескрипторами, а также сетевыми сокетами, для реализации сжатия (`CompressedWriteBuffer` is initialized with another WriteBuffer and performs compression before writing data to it), and for other purposes – the names `ConcatReadBuffer`, `LimitReadBuffer`, и `HashingWriteBuffer` за себя говорить. - -Буферы чтения/записи имеют дело только с байтами. Есть функции от `ReadHelpers` и `WriteHelpers` заголовочные файлы, чтобы помочь с форматированием ввода / вывода. Например, есть помощники для записи числа в десятичном формате. - -Давайте посмотрим, что происходит, когда вы хотите написать результирующий набор в `JSON` форматирование в stdout. У вас есть результирующий набор, готовый к извлечению из него `IBlockInputStream`. Вы создаете `WriteBufferFromFileDescriptor(STDOUT_FILENO)` чтобы записать байты в stdout. Вы создаете `JSONRowOutputStream`, инициализируется с помощью этого `WriteBuffer`, чтобы записать строки в `JSON` в stdout. Вы создаете `BlockOutputStreamFromRowOutputStream` кроме того, чтобы представить его как `IBlockOutputStream`. А потом ты позвонишь `copyData` для передачи данных из `IBlockInputStream` к `IBlockOutputStream` и все это работает. Внутренне, `JSONRowOutputStream` буду писать в формате JSON различные разделители и вызвать `IDataType::serializeTextJSON` метод со ссылкой на `IColumn` и номер строки в качестве аргументов. Следовательно, `IDataType::serializeTextJSON` вызовет метод из `WriteHelpers.h`: например, `writeText` для числовых типов и `writeJSONString` для `DataTypeString`. - -## Таблицы {#tables} - -То `IStorage` интерфейс представляет собой таблицы. Различные реализации этого интерфейса являются различными движками таблиц. Примеры `StorageMergeTree`, `StorageMemory` и так далее. Экземпляры этих классов являются просто таблицами. - -Ключ `IStorage` методы `read` и `write`. Есть и другие варианты `alter`, `rename`, `drop` и так далее. То `read` метод принимает следующие аргументы: набор столбцов для чтения из таблицы, набор столбцов для чтения из таблицы. `AST` запрос для рассмотрения и желаемое количество потоков для возврата. Он возвращает один или несколько `IBlockInputStream` объекты и информация о стадии обработки данных, которая была завершена внутри табличного движка во время выполнения запроса. - -В большинстве случаев метод read отвечает только за чтение указанных столбцов из таблицы, а не за дальнейшую обработку данных. Вся дальнейшая обработка данных осуществляется интерпретатором запросов и не входит в сферу ответственности компании `IStorage`. - -Но есть и заметные исключения: - -- Запрос AST передается на сервер `read` метод, и механизм таблиц может использовать его для получения использования индекса и считывания меньшего количества данных из таблицы. -- Иногда механизм таблиц может сам обрабатывать данные до определенного этапа. Например, `StorageDistributed` можно отправить запрос на удаленные серверы, попросить их обработать данные на этапе, когда данные с разных удаленных серверов могут быть объединены, и вернуть эти предварительно обработанные данные. Затем интерпретатор запросов завершает обработку данных. - -Стол `read` метод может возвращать несколько значений `IBlockInputStream` объекты, позволяющие осуществлять параллельную обработку данных. Эти несколько блочных входных потоков могут считываться из таблицы параллельно. Затем вы можете обернуть эти потоки с помощью различных преобразований (таких как вычисление выражений или фильтрация), которые могут быть вычислены независимо, и создать `UnionBlockInputStream` поверх них, чтобы читать из нескольких потоков параллельно. - -Есть и другие варианты `TableFunction`s. Это функции, которые возвращают временное значение `IStorage` объект для использования в `FROM` предложение запроса. - -Чтобы получить быстрое представление о том, как реализовать свой движок таблиц, посмотрите на что-то простое, например `StorageMemory` или `StorageTinyLog`. - -> В результате этого `read` метод, `IStorage` возвращается `QueryProcessingStage` – information about what parts of the query were already calculated inside storage. - -## Синтаксический анализатор {#parsers} - -Написанный от руки рекурсивный парсер спуска анализирует запрос. Например, `ParserSelectQuery` просто рекурсивно вызывает базовые Парсеры для различных частей запроса. Парсеры создают `AST`. То `AST` представлен узлами, которые являются экземплярами `IAST`. - -> Генераторы парсеров не используются по историческим причинам. - -## Переводчики {#interpreters} - -Интерпретаторы отвечают за создание конвейера выполнения запроса из `AST`. Есть простые переводчики, такие как `InterpreterExistsQuery` и `InterpreterDropQuery` или более изощренные `InterpreterSelectQuery`. Конвейер выполнения запроса представляет собой комбинацию блочных входных и выходных потоков. Например, результат интерпретации `SELECT` запросов `IBlockInputStream` для чтения результирующего набора из; результат запроса INSERT - это `IBlockOutputStream` чтобы записать данные для вставки в, и результат интерпретации `INSERT SELECT` запросов `IBlockInputStream` это возвращает пустой результирующий набор при первом чтении, но копирует данные из него `SELECT` к `INSERT` в то же время. - -`InterpreterSelectQuery` использует `ExpressionAnalyzer` и `ExpressionActions` машины для анализа запросов и преобразований. Именно здесь выполняется большинство оптимизаций запросов на основе правил. `ExpressionAnalyzer` это довольно грязно и должно быть переписано: различные преобразования запросов и оптимизации должны быть извлечены в отдельные классы, чтобы позволить модульные преобразования или запрос. - -## Функции {#functions} - -Существуют обычные функции и агрегатные функции. Агрегатные функции см. В следующем разделе. - -Ordinary functions don’t change the number of rows – they work as if they are processing each row independently. In fact, functions are not called for individual rows, but for `Block`’s данных для реализации векторизованного выполнения запросов. - -Есть некоторые другие функции, такие как [размер блока](../sql_reference/functions/other_functions.md#function-blocksize), [роунумберинблок](../sql_reference/functions/other_functions.md#function-rownumberinblock), и [runningAccumulate](../sql_reference/functions/other_functions.md#function-runningaccumulate), которые эксплуатируют обработку блоков и нарушают независимость строк. - -ClickHouse имеет сильную типизацию, поэтому нет никакого неявного преобразования типов. Если функция не поддерживает определенную комбинацию типов, она создает исключение. Но функции могут работать (перегружаться) для многих различных комбинаций типов. Например, в `plus` функция (для реализации `+` оператор) работает для любой комбинации числовых типов: `UInt8` + `Float32`, `UInt16` + `Int8` и так далее. Кроме того, некоторые вариадические функции могут принимать любое количество аргументов, например `concat` функция. - -Реализация функции может быть немного неудобной, поскольку функция явно отправляет поддерживаемые типы данных и поддерживается `IColumns`. Например, в `plus` функция имеет код, генерируемый экземпляром шаблона C++ для каждой комбинации числовых типов, а также постоянные или непостоянные левые и правые аргументы. - -Это отличное место для реализации генерации кода во время выполнения, чтобы избежать раздувания кода шаблона. Кроме того, он позволяет добавлять слитые функции, такие как fused multiply-add или выполнять несколько сравнений в одной итерации цикла. - -Из-за векторизованного выполнения запроса функции не закорачиваются. Например, если вы пишете `WHERE f(x) AND g(y)`, обе стороны вычисляются, даже для строк, когда `f(x)` равно нулю (за исключением тех случаев, когда `f(x)` является нулевым постоянным выражением). Но если избирательность самого `f(x)` состояние является высоким, и расчет `f(x)` это гораздо дешевле, чем `g(y)`, лучше всего реализовать многоходовой расчет. Это будет первый расчет `f(x)`, затем отфильтруйте столбцы по результату, а затем вычислите `g(y)` только для небольших отфильтрованных фрагментов данных. - -## Статистическая функция {#aggregate-functions} - -Агрегатные функции - это функции, определяющие состояние. Они накапливают переданные значения в некотором состоянии и позволяют получать результаты из этого состояния. Они управляются с помощью `IAggregateFunction` интерфейс. Состояния могут быть довольно простыми (состояние для `AggregateFunctionCount` это всего лишь один человек `UInt64` значение) или довольно сложное (состояние `AggregateFunctionUniqCombined` представляет собой комбинацию линейного массива, хэш-таблицы и `HyperLogLog` вероятностная структура данных). - -Государства распределяются в `Arena` (пул памяти) для работы с несколькими состояниями при выполнении высокой мощности `GROUP BY` запрос. Состояния могут иметь нетривиальный конструктор и деструктор: например, сложные агрегатные состояния могут сами выделять дополнительную память. Это требует некоторого внимания к созданию и уничтожению государств и правильной передаче их права собственности и порядка уничтожения. - -Агрегатные состояния могут быть сериализованы и десериализованы для передачи по сети во время выполнения распределенного запроса или для записи их на диск, где недостаточно оперативной памяти. Они даже могут храниться в таблице с `DataTypeAggregateFunction` чтобы разрешить инкрементное агрегирование данных. - -> Сериализованный формат данных для состояний агрегатных функций в настоящее время не является версионным. Это нормально, если агрегатные состояния хранятся только временно. Но у нас есть такая возможность `AggregatingMergeTree` механизм таблиц для инкрементного агрегирования, и люди уже используют его в производстве. Именно по этой причине обратная совместимость требуется при изменении сериализованного формата для любой агрегатной функции в будущем. - -## Сервер {#server} - -Сервер реализует несколько различных интерфейсов: - -- Интерфейс HTTP для любых иностранных клиентов. -- TCP-интерфейс для собственного клиента ClickHouse и для межсерверной связи во время выполнения распределенного запроса. -- Интерфейс для передачи данных для репликации. - -Внутренне это просто примитивный многопоточный сервер без сопрограмм или волокон. Поскольку сервер предназначен не для обработки высокой скорости простых запросов, а для обработки относительно низкой скорости сложных запросов, каждый из них может обрабатывать огромное количество данных для аналитики. - -Сервер инициализирует программу `Context` класс с необходимой средой для выполнения запроса: список доступных баз данных, пользователей и прав доступа, настройки, кластеры, список процессов, журнал запросов и так далее. Переводчики используют эту среду. - -Мы поддерживаем полную обратную и прямую совместимость для протокола TCP сервера: старые клиенты могут разговаривать с новыми серверами, а новые клиенты-со старыми серверами. Но мы не хотим поддерживать его вечно, и мы удаляем поддержку старых версий примерно через год. - -!!! note "Примечание" - Для большинства внешних приложений мы рекомендуем использовать интерфейс HTTP, поскольку он прост и удобен в использовании. Протокол TCP более тесно связан с внутренними структурами данных: он использует внутренний формат для передачи блоков данных, а также использует пользовательское обрамление для сжатых данных. Мы не выпустили библиотеку C для этого протокола, потому что она требует связывания большей части кодовой базы ClickHouse, что нецелесообразно. - -## Выполнение Распределенных Запросов {#distributed-query-execution} - -Серверы в кластерной установке в основном независимы. Вы можете создать `Distributed` таблица на одном или всех серверах кластера. То `Distributed` table does not store data itself – it only provides a «view» ко всем локальным таблицам на нескольких узлах кластера. Когда вы выберите из `Distributed` таблица, он переписывает этот запрос, выбирает удаленные узлы в соответствии с настройками балансировки нагрузки и отправляет запрос к ним. То `Distributed` таблица запрашивает удаленные серверы для обработки запроса только до стадии, когда промежуточные результаты с разных серверов могут быть объединены. Затем он получает промежуточные результаты и сливает их. Распределенная таблица пытается распределить как можно больше работы на удаленные серверы и не отправляет много промежуточных данных по сети. - -Все становится сложнее, когда у вас есть подзапросы в предложениях IN или JOIN, и каждый из них использует a `Distributed` стол. У нас есть разные стратегии выполнения этих запросов. - -Глобального плана запросов для выполнения распределенных запросов не существует. Каждый узел имеет свой локальный план запроса для своей части задания. У нас есть только простое однопроходное распределенное выполнение запросов: мы отправляем запросы на удаленные узлы, а затем объединяем результаты. Но это неосуществимо для сложных запросов с высокой мощностью группы BYs или с большим количеством временных данных для соединения. В таких случаях нам необходимо: «reshuffle» данные между серверами, что требует дополнительной координации. ClickHouse не поддерживает такого рода выполнение запросов, и мы должны работать над этим. - -## Дерево Слияния {#merge-tree} - -`MergeTree` это семейство механизмов хранения данных, поддерживающих индексацию по первичному ключу. Первичный ключ может быть произвольным кортежем столбцов или выражений. Данные в a `MergeTree` таблица хранится в «parts». Каждая часть хранит данные в порядке первичного ключа, поэтому данные лексикографически упорядочиваются кортежем первичного ключа. Все столбцы таблицы хранятся отдельно `column.bin` файлы в этих краях. Файлы состоят из сжатых блоков. Каждый блок обычно содержит от 64 КБ до 1 МБ несжатых данных, в зависимости от среднего размера значения. Блоки состоят из значений столбцов, расположенных последовательно друг за другом. Значения столбцов находятся в одном и том же порядке для каждого столбца (первичный ключ определяет порядок), поэтому при итерации по многим столбцам вы получаете значения для соответствующих строк. - -Сам первичный ключ является «sparse». Он адресует не каждую отдельную строку, а только некоторые диапазоны данных. Разделение `primary.idx` файл имеет значение первичного ключа для каждой N-й строки, где N называется `index_granularity` (обычно N = 8192). Кроме того, для каждой колонки у нас есть `column.mrk` файлы с «marks,» которые являются смещениями для каждой N-й строки в файле данных. Каждая метка представляет собой пару: смещение в файле к началу сжатого блока и смещение в распакованном блоке к началу данных. Обычно сжатые блоки выравниваются по меткам, а смещение в распакованном блоке равно нулю. Данные для `primary.idx` всегда находится в памяти, а данные для `column.mrk` файлы кэшируются. - -Когда мы собираемся прочитать что-то из части в `MergeTree`, мы смотрим на `primary.idx` данные и найдите диапазоны, которые могут содержать запрошенные данные, а затем посмотрите на `column.mrk` данные и рассчитать смещения для того, чтобы начать чтение этих диапазонов. Из-за разреженности могут быть прочитаны избыточные данные. ClickHouse не подходит для высокой загрузки простых точечных запросов, так как весь диапазон с `index_granularity` строки должны быть прочитаны для каждого ключа, и весь сжатый блок должен быть распакован для каждого столбца. Мы сделали индекс разреженным, потому что мы должны быть в состоянии поддерживать триллионы строк на одном сервере без заметного потребления памяти для индекса. Кроме того, поскольку первичный ключ разрежен, он не является уникальным: он не может проверить существование ключа в таблице во время вставки. В таблице может быть много строк с одним и тем же ключом. - -Когда вы `INSERT` куча данных в `MergeTree`, эта связка сортируется по порядку первичного ключа и образует новую часть. Существуют фоновые потоки, которые периодически выделяют некоторые детали и объединяют их в одну сортированную деталь, чтобы сохранить количество деталей относительно низким. Вот почему он так называется `MergeTree`. Конечно, слияние приводит к тому, что «write amplification». Все части неизменны: они только создаются и удаляются, но не изменяются. Когда SELECT выполняется, он содержит снимок таблицы (набор деталей). После слияния мы также сохраняем старые детали в течение некоторого времени, чтобы облегчить восстановление после сбоя, поэтому, если мы видим, что какая-то объединенная деталь, вероятно, сломана, мы можем заменить ее исходными частями. - -`MergeTree` это не дерево LSM, потому что оно не содержит «memtable» и «log»: inserted data is written directly to the filesystem. This makes it suitable only to INSERT data in batches, not by individual row and not very frequently – about once per second is ok, but a thousand times a second is not. We did it this way for simplicity’s sake, and because we are already inserting data in batches in our applications. - -> Таблицы MergeTree могут иметь только один (первичный) индекс: вторичных индексов не существует. Было бы неплохо разрешить несколько физических представлений в одной логической таблице, например, хранить данные в более чем одном физическом порядке или даже разрешить представления с предварительно агрегированными данными наряду с исходными данными. - -Есть движки MergeTree, которые выполняют дополнительную работу во время фоновых слияний. Примеры `CollapsingMergeTree` и `AggregatingMergeTree`. Это можно рассматривать как специальную поддержку обновлений. Имейте в виду, что это не настоящие обновления, поскольку пользователи обычно не имеют никакого контроля над временем выполнения фоновых слияний, а данные в `MergeTree` таблица почти всегда хранится в нескольких частях, а не в полностью объединенном виде. - -## Копирование {#replication} - -Репликация в ClickHouse может быть настроена на основе каждой таблицы. Вы можете иметь некоторые реплицированные и некоторые нереплицированные таблицы на одном сервере. Вы также можете иметь таблицы, реплицируемые различными способами,например, одна таблица с двухфакторной репликацией, а другая-с трехфакторной. - -Репликация осуществляется в виде `ReplicatedMergeTree` подсистема хранилища. Путь в `ZooKeeper` указывается в качестве параметра для механизма хранения данных. Все таблицы с одинаковым путем внутри `ZooKeeper` становятся репликами друг друга: они синхронизируют свои данные и поддерживают согласованность. Реплики можно добавлять и удалять динамически, просто создавая или удаляя таблицу. - -Репликация использует асинхронную многомастерную схему. Вы можете вставить данные в любую реплику, которая имеет сеанс с `ZooKeeper`, и данные реплицируются во все остальные реплики асинхронно. Поскольку ClickHouse не поддерживает обновления, репликация является бесконфликтной. Поскольку нет подтверждения кворума вставок, только что вставленные данные могут быть потеряны, если один узел выйдет из строя. - -Метаданные для репликации хранятся в ZooKeeper. Существует журнал репликации, в котором перечислены необходимые действия. Действия таковы: получить часть; объединить части; удалить раздел и так далее. Каждая реплика копирует журнал репликации в свою очередь, а затем выполняет действия из этой очереди. Например, при вставке «get the part» действие создается в журнале, и каждая реплика загружает эту часть. Слияния координируются между репликами для получения идентичных байтам результатов. Все части объединяются одинаково на всех репликах. Это достигается путем выбора одной реплики в качестве лидера, и эта реплика инициирует слияние и запись «merge parts» действия по ведению журнала. - -Репликация является физической: между узлами передаются только сжатые части, а не запросы. Слияния обрабатываются на каждой реплике независимо в большинстве случаев, чтобы снизить затраты на сеть, избегая усиления сети. Большие объединенные части передаются по сети только в случаях значительного запаздывания репликации. - -Кроме того, каждая реплика хранит свое состояние в ZooKeeper как набор деталей и их контрольные суммы. Когда состояние локальной файловой системы отличается от эталонного состояния в ZooKeeper, реплика восстанавливает свою согласованность, загружая недостающие и сломанные части из других реплик. Когда в локальной файловой системе появляются неожиданные или неработающие данные, ClickHouse не удаляет их, а перемещает в отдельный каталог и забывает. - -!!! note "Примечание" - Кластер ClickHouse состоит из независимых сегментов, и каждый сегмент состоит из реплик. Кластер таков **неупругий**, поэтому после добавления нового осколка данные не будут автоматически перебалансированы между осколками. Вместо этого предполагается, что нагрузка на кластер будет регулироваться неравномерно. Эта реализация дает вам больше контроля, и это нормально для относительно небольших кластеров, таких как десятки узлов. Но для кластеров с сотнями узлов, которые мы используем в производстве, этот подход становится существенным недостатком. Мы должны реализовать механизм таблиц, который охватывает весь кластер с динамически реплицируемыми областями, которые могут быть разделены и сбалансированы между кластерами автоматически. - -{## [Оригинальная статья](https://clickhouse.tech/docs/en/development/architecture/) ##} diff --git a/docs/ru/development/architecture.md b/docs/ru/development/architecture.md new file mode 120000 index 00000000000..61968e46da2 --- /dev/null +++ b/docs/ru/development/architecture.md @@ -0,0 +1 @@ +en/development/architecture.md \ No newline at end of file diff --git a/docs/ru/development/build.md b/docs/ru/development/build.md deleted file mode 100644 index f0e0ccfd4aa..00000000000 --- a/docs/ru/development/build.md +++ /dev/null @@ -1,139 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Как построить ClickHouse для развития {#how-to-build-clickhouse-for-development} - -Следующий учебник основан на системе Ubuntu Linux. -С соответствующими изменениями он также должен работать на любом другом дистрибутиве Linux. -Поддерживаемые платформы: x86\_64 и AArch64. Поддержка Power9 является экспериментальной. - -## Установите Git, CMake, Python и Ninja {#install-git-cmake-python-and-ninja} - -``` bash -$ sudo apt-get install git cmake python ninja-build -``` - -Или cmake3 вместо cmake на старых системах. - -## Установка GCC 9 {#install-gcc-9} - -Есть несколько способов сделать это. - -### Установка из PPA пакет {#install-from-a-ppa-package} - -``` bash -$ sudo apt-get install software-properties-common -$ sudo apt-add-repository ppa:ubuntu-toolchain-r/test -$ sudo apt-get update -$ sudo apt-get install gcc-9 g++-9 -``` - -### Установка из источников {#install-from-sources} - -Смотреть на [utils/ci/build-gcc-from-sources.sh](https://github.com/ClickHouse/ClickHouse/blob/master/utils/ci/build-gcc-from-sources.sh) - -## Использовать GCC для сборки 9 {#use-gcc-9-for-builds} - -``` bash -$ export CC=gcc-9 -$ export CXX=g++-9 -``` - -## Проверка Источников ClickHouse {#checkout-clickhouse-sources} - -``` bash -$ git clone --recursive git@github.com:ClickHouse/ClickHouse.git -``` - -или - -``` bash -$ git clone --recursive https://github.com/ClickHouse/ClickHouse.git -``` - -## Построить ClickHouse {#build-clickhouse} - -``` bash -$ cd ClickHouse -$ mkdir build -$ cd build -$ cmake .. -$ ninja -$ cd .. -``` - -Чтобы создать исполняемый файл, выполните команду `ninja clickhouse`. -Это позволит создать `programs/clickhouse` исполняемый файл, который может быть использован с `client` или `server` аргументы. - -# Как построить ClickHouse на любом Linux {#how-to-build-clickhouse-on-any-linux} - -Для сборки требуются следующие компоненты: - -- Git (используется только для проверки исходных текстов, он не нужен для сборки) -- CMake 3.10 или новее -- Ниндзя (рекомендуется) или сделать -- Компилятор C++: gcc 9 или clang 8 или новее -- Компоновщик: lld или gold (классический GNU ld не будет работать) -- Python (используется только внутри сборки LLVM и является необязательным) - -Если все компоненты установлены, Вы можете построить их так же, как и описанные выше шаги. - -Пример для Ubuntu Eoan: - - sudo apt update - sudo apt install git cmake ninja-build g++ python - git clone --recursive https://github.com/ClickHouse/ClickHouse.git - mkdir build && cd build - cmake ../ClickHouse - ninja - -Пример для OpenSUSE перекати-поле: - - sudo zypper install git cmake ninja gcc-c++ python lld - git clone --recursive https://github.com/ClickHouse/ClickHouse.git - mkdir build && cd build - cmake ../ClickHouse - ninja - -Пример для сыромятной кожи Fedora: - - sudo yum update - yum --nogpg install git cmake make gcc-c++ python2 - git clone --recursive https://github.com/ClickHouse/ClickHouse.git - mkdir build && cd build - cmake ../ClickHouse - make -j $(nproc) - -# Вам не нужно строить ClickHouse {#you-dont-have-to-build-clickhouse} - -ClickHouse доступен в готовых двоичных файлах и пакетах. Двоичные файлы являются портативными и могут быть запущены на любом вкусе Linux. - -Они созданы для стабильных, предустановленных и тестовых релизов до тех пор, пока для каждого коммита к мастеру и для каждого запроса на вытягивание. - -Чтобы найти самую свежую сборку из `master`, обратиться [совершает страницы](https://github.com/ClickHouse/ClickHouse/commits/master), нажмите на первую зеленую галочку или красный крестик рядом с фиксацией и нажмите на кнопку «Details» ссылка сразу после этого «ClickHouse Build Check». - -# Как создать пакет ClickHouse Debian {#how-to-build-clickhouse-debian-package} - -## Установите Git и Pbuilder {#install-git-and-pbuilder} - -``` bash -$ sudo apt-get update -$ sudo apt-get install git python pbuilder debhelper lsb-release fakeroot sudo debian-archive-keyring debian-keyring -``` - -## Проверка Источников ClickHouse {#checkout-clickhouse-sources-1} - -``` bash -$ git clone --recursive --branch master https://github.com/ClickHouse/ClickHouse.git -$ cd ClickHouse -``` - -## Запустить Сценарий Выпуска {#run-release-script} - -``` bash -$ ./release -``` - -[Оригинальная статья](https://clickhouse.tech/docs/en/development/build/) diff --git a/docs/ru/development/build.md b/docs/ru/development/build.md new file mode 120000 index 00000000000..156d8382515 --- /dev/null +++ b/docs/ru/development/build.md @@ -0,0 +1 @@ +en/development/build.md \ No newline at end of file diff --git a/docs/ru/development/build_cross_arm.md b/docs/ru/development/build_cross_arm.md deleted file mode 100644 index 184028212e9..00000000000 --- a/docs/ru/development/build_cross_arm.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Как построить ClickHouse на Linux для архитектуры AArch64 (ARM64) {#how-to-build-clickhouse-on-linux-for-aarch64-arm64-architecture} - -Это для случая, когда у вас есть Linux-машина и вы хотите использовать ее для сборки `clickhouse` двоичный файл, который будет работать на другой машине Linux с архитектурой процессора AARCH64. Это предназначено для непрерывной проверки интеграции, которая выполняется на серверах Linux. - -Кросс-сборка для AARCH64 основана на следующих принципах: [Инструкции по сборке](build.md)- сначала следуйте за ними. - -# Установка Clang-8 {#install-clang-8} - -Следуйте инструкциям от https://apt.llvm.org/ для вашей установки Ubuntu или Debian. -Например, в Ubuntu Bionic вы можете использовать следующие команды: - -``` 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} - -``` bash -cd ClickHouse -mkdir -p build-aarch64/cmake/toolchain/linux-aarch64 -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 -C build-aarch64/cmake/toolchain/linux-aarch64 --strip-components=1 -``` - -# Построить ClickHouse {#build-clickhouse} - -``` bash -cd ClickHouse -mkdir build-arm64 -CC=clang-8 CXX=clang++-8 cmake . -Bbuild-arm64 -DCMAKE_TOOLCHAIN_FILE=cmake/linux/toolchain-aarch64.cmake -ninja -C build-arm64 -``` - -Полученный двоичный файл будет работать только в Linux с архитектурой процессора AARCH64. diff --git a/docs/ru/development/build_cross_arm.md b/docs/ru/development/build_cross_arm.md new file mode 120000 index 00000000000..ea33bb61837 --- /dev/null +++ b/docs/ru/development/build_cross_arm.md @@ -0,0 +1 @@ +en/development/build_cross_arm.md \ No newline at end of file diff --git a/docs/ru/development/build_cross_osx.md b/docs/ru/development/build_cross_osx.md deleted file mode 100644 index 04d505f1a83..00000000000 --- a/docs/ru/development/build_cross_osx.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Как построить ClickHouse на Linux для Mac OS X {#how-to-build-clickhouse-on-linux-for-mac-os-x} - -Это для случая, когда у вас есть Linux-машина и вы хотите использовать ее для сборки `clickhouse` двоичный файл, который будет работать на OS X. Это предназначено для непрерывной проверки интеграции, которая выполняется на серверах Linux. Если вы хотите построить ClickHouse непосредственно на Mac OS X, то продолжайте [еще одна инструкция](build_osx.md). - -Кросс-сборка для Mac OS X основана на следующих принципах: [Инструкции по сборке](build.md)- сначала следуйте за ними. - -# Установка Clang-8 {#install-clang-8} - -Следуйте инструкциям от https://apt.llvm.org/ для вашей установки Ubuntu или Debian. -Например команды для Bionic выглядят так: - -``` bash -sudo echo "deb [trusted=yes] http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main" >> /etc/apt/sources.list -sudo apt-get install clang-8 -``` - -# Установка Набора Инструментов Перекрестной Компиляции {#install-cross-compilation-toolset} - -Давайте вспомним путь, по которому мы устанавливаем `cctools` как ${CCTOOLS} - -``` bash -mkdir ${CCTOOLS} - -git clone https://github.com/tpoechtrager/apple-libtapi.git -cd apple-libtapi -INSTALLPREFIX=${CCTOOLS} ./build.sh -./install.sh -cd .. - -git clone https://github.com/tpoechtrager/cctools-port.git -cd cctools-port/cctools -./configure --prefix=${CCTOOLS} --with-libtapi=${CCTOOLS} --target=x86_64-apple-darwin -make install -``` - -Кроме того, нам нужно загрузить MacOS X SDK в рабочее дерево. - -``` bash -cd ClickHouse -wget 'https://github.com/phracker/MacOSX-SDKs/releases/download/10.14-beta4/MacOSX10.14.sdk.tar.xz' -mkdir -p build-darwin/cmake/toolchain/darwin-x86_64 -tar xJf MacOSX10.14.sdk.tar.xz -C build-darwin/cmake/toolchain/darwin-x86_64 --strip-components=1 -``` - -# Построить ClickHouse {#build-clickhouse} - -``` bash -cd ClickHouse -mkdir build-osx -CC=clang-8 CXX=clang++-8 cmake . -Bbuild-osx -DCMAKE_TOOLCHAIN_FILE=cmake/darwin/toolchain-x86_64.cmake \ - -DCMAKE_AR:FILEPATH=${CCTOOLS}/bin/x86_64-apple-darwin-ar \ - -DCMAKE_RANLIB:FILEPATH=${CCTOOLS}/bin/x86_64-apple-darwin-ranlib \ - -DLINKER_NAME=${CCTOOLS}/bin/x86_64-apple-darwin-ld -ninja -C build-osx -``` - -Полученный двоичный файл будет иметь исполняемый формат Mach-O и не может быть запущен в Linux. diff --git a/docs/ru/development/build_cross_osx.md b/docs/ru/development/build_cross_osx.md new file mode 120000 index 00000000000..d4dc16f2fbc --- /dev/null +++ b/docs/ru/development/build_cross_osx.md @@ -0,0 +1 @@ +en/development/build_cross_osx.md \ No newline at end of file diff --git a/docs/ru/development/build_osx.md b/docs/ru/development/build_osx.md deleted file mode 100644 index b218304d9d1..00000000000 --- a/docs/ru/development/build_osx.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Как построить ClickHouse на Mac OS X {#how-to-build-clickhouse-on-mac-os-x} - -Сборка должна работать на Mac OS X 10.15 (Catalina) - -## Установите Homebrew {#install-homebrew} - -``` bash -$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" -``` - -## Установите необходимые компиляторы, инструменты и библиотеки {#install-required-compilers-tools-and-libraries} - -``` bash -$ brew install cmake ninja libtool gettext -``` - -## Проверка Источников ClickHouse {#checkout-clickhouse-sources} - -``` bash -$ git clone --recursive git@github.com:ClickHouse/ClickHouse.git -``` - -или - -``` bash -$ git clone --recursive https://github.com/ClickHouse/ClickHouse.git - -$ cd ClickHouse -``` - -## Построить ClickHouse {#build-clickhouse} - -``` bash -$ mkdir build -$ cd build -$ cmake .. -DCMAKE_CXX_COMPILER=`which clang++` -DCMAKE_C_COMPILER=`which clang` -$ ninja -$ cd .. -``` - -## Предостережения {#caveats} - -Если вы собираетесь запустить clickhouse-сервер, убедитесь в том, чтобы увеличить параметром maxfiles системная переменная. - -!!! info "Примечание" - Вам нужно будет использовать sudo. - -Для этого создайте следующий файл: - -/Библиотека / LaunchDaemons / limit.параметром maxfiles.файл plist: - -``` xml - - - - - Label - limit.maxfiles - ProgramArguments - - launchctl - limit - maxfiles - 524288 - 524288 - - RunAtLoad - - ServiceIPC - - - -``` - -Выполните следующую команду: - -``` bash -$ sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist -``` - -Перезагрузить. - -Чтобы проверить, работает ли он, вы можете использовать `ulimit -n` команда. - -[Оригинальная статья](https://clickhouse.tech/docs/en/development/build_osx/) diff --git a/docs/ru/development/build_osx.md b/docs/ru/development/build_osx.md new file mode 120000 index 00000000000..5c38a2b001a --- /dev/null +++ b/docs/ru/development/build_osx.md @@ -0,0 +1 @@ +en/development/build_osx.md \ No newline at end of file diff --git a/docs/ru/development/index.md b/docs/ru/development/index.md deleted file mode 100644 index 8bf31ed0d3f..00000000000 --- a/docs/ru/development/index.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Разработка ClickHouse {#clickhouse-development} - -[Оригинальная статья](https://clickhouse.tech/docs/en/development/) diff --git a/docs/ru/development/index.md b/docs/ru/development/index.md new file mode 120000 index 00000000000..754385a9f4b --- /dev/null +++ b/docs/ru/development/index.md @@ -0,0 +1 @@ +en/development/index.md \ No newline at end of file diff --git a/docs/ru/development/tests.md b/docs/ru/development/tests.md deleted file mode 100644 index 1dfcdfdfe6f..00000000000 --- a/docs/ru/development/tests.md +++ /dev/null @@ -1,250 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Тестирование ClickHouse {#clickhouse-testing} - -## Функциональные пробы {#functional-tests} - -Функциональные тесты являются наиболее простыми и удобными в использовании. Большинство функций ClickHouse можно протестировать с помощью функциональных тестов, и они обязательны для использования при каждом изменении кода ClickHouse, которое может быть протестировано таким образом. - -Каждый функциональный тест отправляет один или несколько запросов на запущенный сервер ClickHouse и сравнивает результат со ссылкой. - -Тесты расположены в `queries` каталог. Существует два подкаталога: `stateless` и `stateful`. Тесты без состояния выполняют запросы без каких - либо предварительно загруженных тестовых данных-они часто создают небольшие синтетические наборы данных на лету, в самом тесте. Статусные тесты требуют предварительно загруженных тестовых данных от Яндекса.Метрика и не доступна широкой публике. Мы склонны использовать только `stateless` тесты и избегайте добавления новых `stateful` тесты. - -Каждый тест может быть одного из двух типов: `.sql` и `.sh`. `.sql` тест - это простой SQL-скрипт, который передается по конвейеру в `clickhouse-client --multiquery --testmode`. `.sh` тест - это скрипт, который запускается сам по себе. - -Чтобы выполнить все тесты, используйте `testskhouse-test` инструмент. Смотри `--help` для списка возможных вариантов. Вы можете просто запустить все тесты или запустить подмножество тестов, отфильтрованных по подстроке в имени теста: `./clickhouse-test substring`. - -Самый простой способ вызвать функциональные тесты-это скопировать `clickhouse-client` к `/usr/bin/`, бежать `clickhouse-server` а потом бежать `./clickhouse-test` из собственного каталога. - -Чтобы добавить новый тест, создайте `.sql` или `.sh` файл в `queries/0_stateless` каталог, проверьте его вручную, а затем сгенерируйте `.reference` файл создается следующим образом: `clickhouse-client -n --testmode < 00000_test.sql > 00000_test.reference` или `./00000_test.sh > ./00000_test.reference`. - -Тесты должны использовать (создавать, отбрасывать и т. д.) Только таблицы в `test` предполагается, что база данных создается заранее; также тесты могут использовать временные таблицы. - -Если вы хотите использовать распределенные запросы в функциональных тестах, вы можете использовать их в качестве рычагов `remote` функция таблицы с `127.0.0.{1..2}` адреса для запроса самого сервера; или вы можете использовать предопределенные тестовые кластеры в файле конфигурации сервера, например `test_shard_localhost`. - -Некоторые тесты помечены знаком `zookeeper`, `shard` или `long` в своем названии. -`zookeeper` это для тестов, которые используют ZooKeeper. `shard` это для тестов, что -требуется сервер для прослушивания `127.0.0.*`; `distributed` или `global` есть то же самое -значение. `long` это для тестов, которые работают немного дольше, чем одна секунда. Ты можешь -отключите эти группы тестов с помощью `--no-zookeeper`, `--no-shard` и -`--no-long` варианты, соответственно. - -## Известная ошибка {#known-bugs} - -Если мы знаем некоторые ошибки, которые могут быть легко воспроизведены функциональными тестами, мы помещаем подготовленные функциональные тесты в `queries/bugs` каталог. Эти тесты будут перенесены в `teststests_stateless` когда ошибки будут исправлены. - -## Интеграционные Тесты {#integration-tests} - -Интеграционные тесты позволяют тестировать ClickHouse в кластерной конфигурации и взаимодействие ClickHouse с другими серверами, такими как MySQL, Postgres, MongoDB. Они полезны для эмуляции сетевых разбиений, отбрасывания пакетов и т. д. Эти тесты выполняются в Docker и создают несколько контейнеров с различным программным обеспечением. - -Видеть `testsgration/README.md` о том, как проводить эти тесты. - -Обратите внимание, что интеграция ClickHouse со сторонними драйверами не тестируется. Кроме того, в настоящее время у нас нет интеграционных тестов с нашими драйверами JDBC и ODBC. - -## Модульное тестирование {#unit-tests} - -Модульные тесты полезны, если вы хотите протестировать не весь ClickHouse в целом, а одну изолированную библиотеку или класс. Вы можете включить или отключить сборку тестов с помощью `ENABLE_TESTS` Вариант CMake. Модульные тесты (и другие тестовые программы) расположены в `tests` подкаталоги по всему коду. Чтобы запустить модульные тесты, введите `ninja test`. Некоторые тесты используют `gtest`, но некоторые из них-это просто программы, которые возвращают ненулевой код выхода при сбое теста. - -Не обязательно иметь модульные тесты, Если код уже охвачен функциональными тестами (а функциональные тесты обычно гораздо более просты в использовании). - -## Эксплуатационное испытание {#performance-tests} - -Тесты производительности позволяют измерять и сравнивать производительность некоторой изолированной части ClickHouse по синтетическим запросам. Тесты расположены по адресу `tests/performance`. Каждый тест представлен следующим образом `.xml` файл с описанием тестового случая. Тесты выполняются с помощью `clickhouse performance-test` инструмент (который встроен в `clickhouse` двоичный). Видеть `--help` для призыва. - -Каждый тест запускает один или несколько запросов (возможно, с комбинациями параметров) в цикле с некоторыми условиями остановки (например «maximum execution speed is not changing in three seconds») и измерьте некоторые показатели производительности запросов (например, «maximum execution speed»). Некоторые тесты могут содержать предварительные условия для предварительно загруженного тестового набора данных. - -Если вы хотите улучшить производительность ClickHouse в каком-то сценарии, и если улучшения могут наблюдаться в простых запросах, настоятельно рекомендуется написать тест производительности. Это всегда имеет смысл использовать `perf top` или другие инструменты perf во время ваших тестов. - -## Инструменты И Сценарии Тестирования {#test-tools-and-scripts} - -Некоторые программы в `tests` каталог-это не подготовленные тесты, а инструменты тестирования. Например, для `Lexer` есть такой инструмент `dbms/Parsers/tests/lexer` это просто делает токенизацию stdin и записывает раскрашенный результат в stdout. Вы можете использовать эти инструменты в качестве примеров кода, а также для исследования и ручного тестирования. - -Вы также можете разместить пару файлов `.sh` и `.reference` вместе с инструментом нужно запустить его на каком - то заранее заданном входе- тогда результат скрипта можно сравнить с `.reference` файл. Такого рода тесты не автоматизированы. - -## Различные Тесты {#miscellanous-tests} - -Существуют тесты для внешних словарей, расположенных по адресу `tests/external_dictionaries` и для машинно-обученных моделей в `tests/external_models`. Эти тесты не обновляются и должны быть перенесены в интеграционные тесты. - -Существует отдельный тест для вставки кворума. Этот тест запускает кластер ClickHouse на отдельных серверах и эмулирует различные случаи сбоя: разделение сети, отбрасывание пакетов (между узлами ClickHouse, между ClickHouse и ZooKeeper, между сервером ClickHouse и клиентом и т. д.), `kill -9`, `kill -STOP` и `kill -CONT` , любить [Джепсен](https://aphyr.com/tags/Jepsen). Затем тест проверяет, что все признанные вставки были записаны, а все отклоненные вставки-нет. - -Тест кворума был написан отдельной командой еще до того, как ClickHouse стал открытым исходным кодом. Эта команда больше не работает с ClickHouse. Тест был случайно написан на Java. По этим причинам тест кворума должен быть переписан и перенесен в интеграционные тесты. - -## Ручное тестирование {#manual-testing} - -Когда вы разрабатываете новую функцию, разумно также протестировать ее вручную. Вы можете сделать это с помощью следующих шагов: - -Постройте ClickHouse. Запустите ClickHouse из терминала: измените каталог на `programs/clickhouse-server` и запустить его с помощью `./clickhouse-server`. Он будет использовать конфигурацию (`config.xml`, `users.xml` и файлы внутри `config.d` и `users.d` каталоги) из текущего каталога по умолчанию. Чтобы подключиться к серверу ClickHouse, выполните команду `programs/clickhouse-client/clickhouse-client`. - -Обратите внимание, что все инструменты clickhouse (сервер, клиент и т. д.) являются просто символическими ссылками на один двоичный файл с именем `clickhouse`. Вы можете найти этот двоичный файл по адресу `programs/clickhouse`. Все инструменты также могут быть вызваны как `clickhouse tool` вместо `clickhouse-tool`. - -В качестве альтернативы вы можете установить пакет ClickHouse: либо стабильный релиз из репозитория Яндекса, либо вы можете построить пакет для себя с помощью `./release` в корне источников ClickHouse. Затем запустите сервер с помощью `sudo service clickhouse-server start` (или остановить, чтобы остановить сервер). Ищите журналы по адресу `/etc/clickhouse-server/clickhouse-server.log`. - -Когда ClickHouse уже установлен в вашей системе, вы можете построить новый `clickhouse` двоичный код и заменить существующий двоичный код: - -``` bash -$ sudo service clickhouse-server stop -$ sudo cp ./clickhouse /usr/bin/ -$ sudo service clickhouse-server start -``` - -Также вы можете остановить системный clickhouse-сервер и запустить свой собственный с той же конфигурацией, но с регистрацией в терминал: - -``` bash -$ sudo service clickhouse-server stop -$ sudo -u clickhouse /usr/bin/clickhouse server --config-file /etc/clickhouse-server/config.xml -``` - -Пример с gdb: - -``` bash -$ sudo -u clickhouse gdb --args /usr/bin/clickhouse server --config-file /etc/clickhouse-server/config.xml -``` - -Если системный clickhouse-сервер уже запущен, и вы не хотите его останавливать, вы можете изменить номера портов в своей системе. `config.xml` (или переопределить их в файле внутри `config.d` каталог), укажите соответствующий путь к данным и запустите его. - -`clickhouse` binary почти не имеет зависимостей и работает в широком диапазоне дистрибутивов Linux. Чтобы быстро и грязно протестировать свои изменения на сервере, вы можете просто `scp` ваша свежая постройка `clickhouse` двоичный файл на ваш сервер, а затем запустите его, как в приведенных выше примерах. - -## Тестовая среда {#testing-environment} - -Перед публикацией релиза как стабильного мы развертываем его в тестовой среде. Среда тестирования-это кластер, который обрабатывает 1/39 часть [Яндекс.Метрика](https://metrica.yandex.com/) данные. Мы делимся нашей тестовой средой с Яндексом.Команда метрики. ClickHouse обновляется без простоев поверх существующих данных. Мы смотрим сначала на то, что данные обрабатываются успешно, не отставая от реального времени, репликация продолжает работать и нет никаких проблем, видимых Яндексу.Команда метрики. Первую проверку можно провести следующим образом: - -``` sql -SELECT hostName() AS h, any(version()), any(uptime()), max(UTCEventTime), count() FROM remote('example01-01-{1..3}t', merge, hits) WHERE EventDate >= today() - 2 GROUP BY h ORDER BY h; -``` - -В некоторых случаях мы также развернуть на тестирование среды нашего друга команды Яндекса: Маркет, облако и т. д. Кроме того, у нас есть некоторые аппаратные серверы, которые используются для целей разработки. - -## Нагрузочное тестирование {#load-testing} - -После развертывания в среде тестирования мы запускаем нагрузочное тестирование с запросами из производственного кластера. Это делается вручную. - -Убедитесь, что вы включили `query_log` на вашем производственном кластере. - -Сбор журнала запросов в течение одного или нескольких дней: - -``` bash -$ clickhouse-client --query="SELECT DISTINCT query FROM system.query_log WHERE event_date = today() AND query LIKE '%ym:%' AND query NOT LIKE '%system.query_log%' AND type = 2 AND is_initial_query" > queries.tsv -``` - -Это очень сложный пример. `type = 2` будет фильтровать запросы, которые выполняются успешно. `query LIKE '%ym:%'` это выбор релевантных запросов от Яндекса.Метрика. `is_initial_query` это выбор только тех запросов, которые инициируются клиентом, а не самим ClickHouse (как части распределенной обработки запросов). - -`scp` это войдите в свой тестовый кластер и запустите его следующим образом: - -``` bash -$ clickhouse benchmark --concurrency 16 < queries.tsv -``` - -(вероятно, вы также хотите указать a `--user`) - -Затем оставьте его на ночь или выходные и идите отдыхать. - -Вы должны это проверить `clickhouse-server` не дает сбоя, объем памяти ограничен, а производительность не ухудшается с течением времени. - -Точные тайминги выполнения запросов не регистрируются и не сравниваются из-за высокой вариативности запросов и окружающей среды. - -## Построение Тестов {#build-tests} - -Тесты сборки позволяют проверить, что сборка не нарушается на различных альтернативных конфигурациях и на некоторых зарубежных системах. Тесты расположены по адресу `ci` каталог. Они запускают сборку из исходного кода внутри Docker, Vagrant, а иногда и с помощью `qemu-user-static` внутри Докер. Эти тесты находятся в стадии разработки, и тестовые запуски не автоматизированы. - -Мотивация: - -Обычно мы выпускаем и запускаем все тесты на одном варианте сборки ClickHouse. Но есть и альтернативные варианты сборки, которые не проходят тщательной проверки. Примеры: - -- сборка на FreeBSD; -- сборка на Debian с библиотеками из системных пакетов; -- сборка с общим связыванием библиотек; -- построить на платформе AArch64 ; -- постройте на платформе PowerPc. - -Например, сборка с системными пакетами-это плохая практика, потому что мы не можем гарантировать, какая именно версия пакетов будет у системы. Но это действительно необходимо сопровождающим Debian. По этой причине мы, по крайней мере, должны поддерживать этот вариант сборки. Другой пример: Общие ссылки-это общий источник проблем, но он необходим для некоторых энтузиастов. - -Хотя мы не можем выполнить все тесты на всех вариантах сборки, мы хотим проверить, по крайней мере, что различные варианты сборки не нарушены. Для этого мы используем тесты сборки. - -## Тестирование Совместимости Протоколов {#testing-for-protocol-compatibility} - -Когда мы расширяем сетевой протокол ClickHouse, мы вручную проверяем, что старый clickhouse-клиент работает с новым clickhouse-сервером, а новый clickhouse-клиент работает со старым clickhouse-сервером (просто запустив двоичные файлы из соответствующих пакетов). - -## Помощь От Компилятора {#help-from-the-compiler} - -Основной код ClickHouse (который находится в `dbms` каталог) строится с помощью `-Wall -Wextra -Werror` и с некоторыми дополнительными включенными предупреждениями. Хотя эти параметры не включены для сторонних библиотек. - -У Clang есть еще более полезные предупреждения - вы можете искать их с помощью `-Weverything` и выберите что-то для сборки по умолчанию. - -Для производственных сборок используется gcc (он все еще генерирует немного более эффективный код, чем clang). Для развития, лязгают, как правило, более удобны в использовании. Вы можете построить на своей собственной машине с режимом отладки (чтобы сэкономить батарею вашего ноутбука), но обратите внимание, что компилятор способен генерировать больше предупреждений с помощью `-O3` благодаря лучшему потоку управления и межпроцедурному анализу. При строительстве с лязгом, `libc++` используется вместо `libstdc++` и при построении с режимом отладки, отладочная версия `libc++` используется, что позволяет ловить больше ошибок во время выполнения. - -## Дезинфицирующее средство {#sanitizers} - -**Адрес дезинфицирующее средство**. -Мы проводим функциональные и интеграционные тесты в асане на фиксации основы. - -**С Valgrind (Помощи Valgrind)**. -Мы проводим функциональные тесты под Valgrind ночь. Это займет несколько часов. В настоящее время существует один известный ложноположительный результат в `re2` библиотека, см. [эта статья](https://research.swtch.com/sparse). - -**Неопределенное поведение дезинфицирующего средства.** -Мы проводим функциональные и интеграционные тесты в асане на фиксации основы. - -**Дезинфицирующее средство для нитей**. -Мы проводим функциональные тесты в рамках TSan на основе per-commit. Мы все еще не запускаем интеграционные тесты под TSan на основе per-commit. - -**Дезинфицирующее средство для памяти**. -В настоящее время мы все еще не используем MSan. - -**Отладочный распределитель.** -Отладочная версия `jemalloc` используется для отладки сборки. - -## Затуманивающего {#fuzzing} - -Мы используем простой тест fuzz для генерации случайных SQL-запросов и проверки того, что сервер не умирает. Тестирование пуха проводится с помощью адресного дезинфицирующего средства. Вы можете найти его в `00746_sql_fuzzy.pl`. Этот тест следует проводить непрерывно (в течение ночи и дольше). - -По состоянию на декабрь 2018 года мы все еще не используем изолированное тестирование fuzz библиотечного кода. - -## Аудит безопасности {#security-audit} - -Люди из облачного отдела Яндекса делают некоторый базовый обзор возможностей ClickHouse с точки зрения безопасности. - -## Статический анализатор {#static-analyzers} - -Мы бежим `PVS-Studio` на основе каждой фиксации. Мы провели оценку `clang-tidy`, `Coverity`, `cppcheck`, `PVS-Studio`, `tscancode`. Вы найдете инструкции по использованию в `tests/instructions/` каталог. Кроме того, вы можете читать [статья на русском языке](https://habr.com/company/yandex/blog/342018/). - -Если вы используете `CLion` как IDE, вы можете использовать некоторые из них `clang-tidy` выписывает чеки из коробки. - -## Затвердение {#hardening} - -`FORTIFY_SOURCE` используется по умолчанию. Это почти бесполезно, но все же имеет смысл в редких случаях, и мы не отключаем его. - -## Стиль Кода {#code-style} - -Описаны правила стиля кода [здесь](https://clickhouse.tech/docs/en/development/style/). - -Чтобы проверить наличие некоторых распространенных нарушений стиля, вы можете использовать `utils/check-style` скрипт. - -Чтобы принудительно создать правильный стиль вашего кода, Вы можете использовать `clang-format`. Файл `.clang-format` находится в корне источника. Это в основном соответствует нашему фактическому стилю кода. Но применять его не рекомендуется `clang-format` к существующим файлам, потому что это ухудшает форматирование. Вы можете использовать `clang-format-diff` инструмент, который вы можете найти в репозитории Clang source. - -В качестве альтернативы вы можете попробовать `uncrustify` инструмент для переформатирования вашего кода. Конфигурации в `uncrustify.cfg` в корне источников. Это меньше, чем `clang-format`. - -`CLion` имеет свой собственный формататор кода, который должен быть настроен для нашего стиля кода. - -## В2В метрика тесты {#metrica-b2b-tests} - -Каждый релиз ClickHouse тестируется с помощью движков Yandex Metrica и AppMetrica. Тестовые и стабильные версии ClickHouse развертываются на виртуальных машинах и запускаются с небольшой копией движка Metrica engine, который обрабатывает фиксированную выборку входных данных. Затем результаты двух экземпляров двигателя Metrica сравниваются вместе. - -Эти тесты автоматизированы отдельной командой. Из-за большого количества движущихся частей тесты чаще всего проваливаются по совершенно несвязанным причинам, которые очень трудно выяснить. Скорее всего, эти тесты имеют для нас отрицательное значение. Тем не менее эти тесты оказались полезными примерно в одном или двух случаях из сотен. - -## Тестовое покрытие {#test-coverage} - -По состоянию на июль 2018 года мы не отслеживаем покрытие тестов. - -## Автоматизация тестирования {#test-automation} - -Мы проводим тесты с помощью внутренней CI Яндекса и системы автоматизации заданий под названием «Sandbox». - -Задания сборки и тесты выполняются в песочнице на основе каждой фиксации. Полученные пакеты и результаты тестирования публикуются на GitHub и могут быть загружены по прямым ссылкам. Артефакты хранятся вечно. Когда вы отправляете запрос на вытягивание на GitHub, мы помечаем его как «can be tested» и наша система CI построит пакеты ClickHouse (release, debug, with address sanitizer и т. д.) Для вас. - -Мы не используем Travis CI из-за ограничения по времени и вычислительной мощности. -Мы не используем Дженкинса. Он был использован раньше, и теперь мы счастливы, что не используем Дженкинса. - -[Оригинальная статья](https://clickhouse.tech/docs/en/development/tests/) -разработка / испытания/) diff --git a/docs/ru/development/tests.md b/docs/ru/development/tests.md new file mode 120000 index 00000000000..ce23c881f32 --- /dev/null +++ b/docs/ru/development/tests.md @@ -0,0 +1 @@ +en/development/tests.md \ No newline at end of file diff --git a/docs/ru/engines/table_engines/special/generate.md b/docs/ru/engines/table_engines/special/generate.md deleted file mode 100644 index 87004bfe5b1..00000000000 --- a/docs/ru/engines/table_engines/special/generate.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# GenerateRandom {#table_engines-generate} - -Механизм генерации случайных таблиц генерирует случайные данные для данной схемы таблиц. - -Примеры употребления: - -- Используйте в тесте для заполнения воспроизводимого большого стола. -- Генерируйте случайные входные данные для тестов размытия. - -## Использование в сервере ClickHouse {#usage-in-clickhouse-server} - -``` sql -ENGINE = GenerateRandom(random_seed, max_string_length, max_array_length) -``` - -То `max_array_length` и `max_string_length` параметры укажите максимальную длину всех -столбцы массива и строки соответственно в генерируемых данных. - -Генерация таблицы движок поддерживает только `SELECT` запросы. - -Он поддерживает все [Тип данных](../../../engines/table_engines/special/generate.md) это может быть сохранено в таблице за исключением `LowCardinality` и `AggregateFunction`. - -**Пример:** - -**1.** Настройка системы `generate_engine_table` стол: - -``` sql -CREATE TABLE generate_engine_table (name String, value UInt32) ENGINE = GenerateRandom(1, 5, 3) -``` - -**2.** Запрос данных: - -``` sql -SELECT * FROM generate_engine_table LIMIT 3 -``` - -``` text -┌─name─┬──────value─┐ -│ c4xJ │ 1412771199 │ -│ r │ 1791099446 │ -│ 7#$ │ 124312908 │ -└──────┴────────────┘ -``` - -## Детали внедрения {#details-of-implementation} - -- Не поддерживаемый: - - `ALTER` - - `SELECT ... SAMPLE` - - `INSERT` - - Индексы - - Копирование - -[Оригинальная статья](https://clickhouse.tech/docs/en/operations/table_engines/generate/) diff --git a/docs/ru/engines/table_engines/special/generate.md b/docs/ru/engines/table_engines/special/generate.md new file mode 120000 index 00000000000..631f9bbba66 --- /dev/null +++ b/docs/ru/engines/table_engines/special/generate.md @@ -0,0 +1 @@ +en/engines/table_engines/special/generate.md \ No newline at end of file diff --git a/docs/ru/getting_started/tutorial.md b/docs/ru/getting_started/tutorial.md deleted file mode 100644 index 69cdeac8387..00000000000 --- a/docs/ru/getting_started/tutorial.md +++ /dev/null @@ -1,669 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Учебник По Клик-Хаусу {#clickhouse-tutorial} - -## Чего ожидать от этого урока? {#what-to-expect-from-this-tutorial} - -Пройдя через этот учебник,вы узнаете, как настроить простой кластер ClickHouse. Он будет небольшим, но отказоустойчивым и масштабируемым. Затем мы будем использовать один из примеров наборов данных, чтобы заполнить его данными и выполнить некоторые демонстрационные запросы. - -## Настройка Одного Узла {#single-node-setup} - -Чтобы избежать сложностей распределенной среды, мы начнем с развертывания ClickHouse на одном сервере или виртуальной машине. ClickHouse обычно устанавливается из [дебютантка](install.md#install-from-deb-packages) или [оборотов в минуту](install.md#from-rpm-packages) пакеты, но есть и такие [альтернативы](install.md#from-docker-image) для операционных систем, которые их не поддерживают. - -Например, вы выбрали `deb` пакеты и выполненные работы: - -``` bash -sudo apt-get install dirmngr -sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E0C56BD4 - -echo "deb http://repo.clickhouse.tech/deb/stable/ main/" | sudo tee /etc/apt/sources.list.d/clickhouse.list -sudo apt-get update - -sudo apt-get install -y clickhouse-server clickhouse-client -``` - -Что у нас есть в пакетах, которые были установлены: - -- `clickhouse-client` пакет содержит [clickhouse-клиент](../interfaces/cli.md) приложение, интерактивный консольный клиент ClickHouse. -- `clickhouse-common` пакет содержит исполняемый файл ClickHouse. -- `clickhouse-server` пакет содержит файлы конфигурации для запуска ClickHouse в качестве сервера. - -Файлы конфигурации сервера находятся в `/etc/clickhouse-server/`. Прежде чем идти дальше, пожалуйста, обратите внимание на `` элемент в `config.xml`. Путь определяет место для хранения данных, поэтому он должен быть расположен на Томе с большой емкостью диска; значение по умолчанию равно `/var/lib/clickhouse/`. Если вы хотите настроить конфигурацию, то это не удобно для непосредственного редактирования `config.xml` файл, учитывая, что он может быть переписан при будущих обновлениях пакета. Рекомендуемый способ переопределения элементов конфигурации заключается в создании [файлы в конфигурации.D каталог](../operations/configuration_files.md) которые служат в качестве «patches» к конфигурации.XML. - -Как вы могли заметить, `clickhouse-server` не запускается автоматически после установки пакета. Он также не будет автоматически перезапущен после обновления. То, как вы запускаете сервер, зависит от вашей системы init, как правило, это так: - -``` bash -sudo service clickhouse-server start -``` - -или - -``` bash -sudo /etc/init.d/clickhouse-server start -``` - -По умолчанию для журналов сервера используется следующее расположение `/var/log/clickhouse-server/`. Сервер готов к обработке клиентских подключений, как только он регистрирует `Ready for connections` сообщение. - -Как только это произойдет `clickhouse-server` все готово и работает, мы можем использовать `clickhouse-client` чтобы подключиться к серверу и выполнить некоторые тестовые запросы, такие как `SELECT "Hello, world!";`. - -
- -Быстрые советы для clickhouse-клиента -Интерактивный режим: - -``` bash -clickhouse-client -clickhouse-client --host=... --port=... --user=... --password=... -``` - -Включить многострочные запросы: - -``` bash -clickhouse-client -m -clickhouse-client --multiline -``` - -Запуск запросов в пакетном режиме: - -``` bash -clickhouse-client --query='SELECT 1' -echo 'SELECT 1' | clickhouse-client -clickhouse-client <<< 'SELECT 1' -``` - -Вставка данных из файла в заданном формате: - -``` bash -clickhouse-client --query='INSERT INTO table VALUES' < data.txt -clickhouse-client --query='INSERT INTO table FORMAT TabSeparated' < data.tsv -``` - -
- -## Импорт Образца Набора Данных {#import-sample-dataset} - -Теперь пришло время заполнить наш сервер ClickHouse некоторыми образцами данных. В этом уроке мы будем использовать анонимизированные данные Яндекса.Metrica, первый сервис, который запускает ClickHouse в производственном режиме до того, как он стал открытым исходным кодом (подробнее об этом в [раздел истории](../introduction/history.md)). Есть [несколько способов импорта Яндекса.Набор метрика](example_datasets/metrica.md), и ради учебника мы пойдем с самым реалистичным из них. - -### Загрузка и извлечение данных таблицы {#download-and-extract-table-data} - -``` bash -curl https://clickhouse-datasets.s3.yandex.net/hits/tsv/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv -curl https://clickhouse-datasets.s3.yandex.net/visits/tsv/visits_v1.tsv.xz | unxz --threads=`nproc` > visits_v1.tsv -``` - -Извлеченные файлы имеют размер около 10 ГБ. - -### Создавать таблицы {#create-tables} - -Как и в большинстве систем управления базами данных, ClickHouse логически группирует таблицы в «databases». Там есть еще один `default` база данных, но мы создадим новую с именем `tutorial`: - -``` bash -clickhouse-client --query "CREATE DATABASE IF NOT EXISTS tutorial" -``` - -Синтаксис для создания таблиц намного сложнее по сравнению с базами данных (см. [ссылка](../sql_reference/statements/create.md). В общем `CREATE TABLE` в заявлении должны быть указаны три ключевых момента: - -1. Имя таблицы для создания. -2. Table schema, i.e. list of columns and their [тип данных](../sql_reference/data_types/index.md). -3. [Настольный двигатель](../engines/table_engines/index.md) и это настройки, которые определяют все детали того, как запросы к этой таблице будут физически выполняться. - -Яндекс.Metrica - это сервис веб-аналитики, и пример набора данных не охватывает его полную функциональность, поэтому для создания необходимо создать только две таблицы: - -- `hits` это таблица с каждым действием, выполняемым всеми пользователями на всех веб-сайтах, охватываемых сервисом. -- `visits` это таблица, которая содержит предварительно построенные сеансы вместо отдельных действий. - -Давайте посмотрим и выполним реальные запросы create table для этих таблиц: - -``` sql -CREATE TABLE tutorial.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 -``` - -``` sql -CREATE TABLE tutorial.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` (просто запустите его в терминале, не указывая заранее запрос) или попробуйте некоторые [альтернативный интерфейс](../interfaces/index.md) если ты хочешь. - -Как мы видим, `hits_v1` использует [базовый движок MergeTree](../engines/table_engines/mergetree_family/mergetree.md), в то время как `visits_v1` использует [Разрушение](../engines/table_engines/mergetree_family/collapsingmergetree.md) вариант. - -### Импортировать данные {#import-data} - -Импорт данных в ClickHouse осуществляется через [INSERT INTO](../sql_reference/statements/insert_into.md) запрос, как и во многих других базах данных SQL. Однако данные обычно приводятся в одном из следующих документов: [поддерживаемые форматы сериализации](../interfaces/formats.md) вместо `VALUES` предложение (которое также поддерживается). - -Файлы, которые мы загрузили ранее, находятся в формате с разделенными вкладками, поэтому вот как импортировать их через консольный клиент: - -``` bash -clickhouse-client --query "INSERT INTO tutorial.hits_v1 FORMAT TSV" --max_insert_block_size=100000 < hits_v1.tsv -clickhouse-client --query "INSERT INTO tutorial.visits_v1 FORMAT TSV" --max_insert_block_size=100000 < visits_v1.tsv -``` - -У ClickHouse их очень много [настройки для настройки](../operations/settings/index.md) и один из способов указать их в консольном клиенте - это через аргументы, как мы видим с помощью `--max_insert_block_size`. Самый простой способ выяснить, какие настройки доступны, что они означают и каковы значения по умолчанию, - это запросить `system.settings` стол: - -``` sql -SELECT name, value, changed, description -FROM system.settings -WHERE name LIKE '%max_insert_b%' -FORMAT TSV - -max_insert_block_size 1048576 0 "The maximum block size for insertion, if we control the creation of blocks for insertion." -``` - -По желанию вы можете [OPTIMIZE](../sql_reference/misc/#misc_operations-optimize) таблицы после импорта. Таблицы, настроенные с помощью движка из семейства MergeTree, всегда выполняют слияние частей данных в фоновом режиме для оптимизации хранения данных (или, по крайней мере, проверяют, имеет ли это смысл). Эти запросы заставляют механизм таблиц выполнять оптимизацию хранилища прямо сейчас, а не некоторое время спустя: - -``` bash -clickhouse-client --query "OPTIMIZE TABLE tutorial.hits_v1 FINAL" -clickhouse-client --query "OPTIMIZE TABLE tutorial.visits_v1 FINAL" -``` - -Эти запросы запускают интенсивную работу ввода-вывода и процессора, поэтому, если таблица постоянно получает новые данные, лучше оставить ее в покое и позволить слияниям работать в фоновом режиме. - -Теперь мы можем проверить, был ли импорт таблицы успешным: - -``` bash -clickhouse-client --query "SELECT COUNT(*) FROM tutorial.hits_v1" -clickhouse-client --query "SELECT COUNT(*) FROM tutorial.visits_v1" -``` - -## Пример запроса {#example-queries} - -``` sql -SELECT - StartURL AS URL, - AVG(Duration) AS AvgDuration -FROM tutorial.visits_v1 -WHERE StartDate BETWEEN '2014-03-23' AND '2014-03-30' -GROUP BY URL -ORDER BY AvgDuration DESC -LIMIT 10 -``` - -``` sql -SELECT - sum(Sign) AS visits, - sumIf(Sign, has(Goals.ID, 1105530)) AS goal_visits, - (100. * goal_visits) / visits AS goal_percent -FROM tutorial.visits_v1 -WHERE (CounterID = 912887) AND (toYYYYMM(StartDate) = 201403) AND (domain(StartURL) = 'yandex.ru') -``` - -## Развертывание Кластера {#cluster-deployment} - -Кластер ClickHouse-это однородный кластер. Шаги для настройки: - -1. Установите сервер ClickHouse на всех компьютерах кластера -2. Настройка конфигураций кластера в файлах конфигурации -3. Создание локальных таблиц на каждом экземпляре -4. Создать [Распространены таблицы](../engines/table_engines/special/distributed.md) - -[Распространены таблицы](../engines/table_engines/special/distributed.md) это на самом деле своего рода «view» к локальным таблицам кластера ClickHouse. Запрос SELECT из распределенной таблицы выполняется с использованием ресурсов всех сегментов кластера. Вы можете указать конфигурации для нескольких кластеров и создать несколько распределенных таблиц, предоставляющих представления для разных кластеров. - -Пример конфигурации для кластера с тремя сегментами, по одной реплике в каждом: - -``` xml - - - - - example-perftest01j.yandex.ru - 9000 - - - - - example-perftest02j.yandex.ru - 9000 - - - - - example-perftest03j.yandex.ru - 9000 - - - - -``` - -Для дальнейшей демонстрации давайте создадим новую локальную таблицу с тем же именем `CREATE TABLE` запрос, который мы использовали для `hits_v1`, но другое имя таблицы: - -``` sql -CREATE TABLE tutorial.hits_local (...) ENGINE = MergeTree() ... -``` - -Создание распределенной таблицы, предоставляющей представление в локальные таблицы кластера: - -``` sql -CREATE TABLE tutorial.hits_all AS tutorial.hits_local -ENGINE = Distributed(perftest_3shards_1replicas, tutorial, hits_local, rand()); -``` - -Распространенной практикой является создание одинаковых распределенных таблиц на всех машинах кластера. Он позволяет выполнять распределенные запросы на любой машине кластера. Кроме того, существует альтернативный вариант создания временной распределенной таблицы для данного запроса SELECT с помощью [удаленный](../sql_reference/table_functions/remote.md) табличная функция. - -Давай убежим [INSERT SELECT](../sql_reference/statements/insert_into.md) в распределенную таблицу, чтобы распространить таблицу на несколько серверов. - -``` sql -INSERT INTO tutorial.hits_all SELECT * FROM tutorial.hits_v1; -``` - -!!! warning "Уведомление" - Такой подход не подходит для сегментации больших столов. Есть отдельный инструмент [clickhouse-копировальный аппарат](../operations/utilities/clickhouse-copier.md) это может повторно осколить произвольные большие таблицы. - -Как и следовало ожидать, вычислительно тяжелые запросы выполняются в N раз быстрее, если они используют 3 сервера вместо одного. - -В этом случае мы использовали кластер с 3 осколками, и каждый из них содержит одну реплику. - -Для обеспечения устойчивости в рабочей среде рекомендуется, чтобы каждый сегмент содержал 2-3 реплики, распределенные между несколькими зонами доступности или центрами обработки данных (или, по крайней мере, стойками). Обратите внимание, что ClickHouse поддерживает неограниченное количество реплик. - -Пример конфигурации для кластера из одного осколка, содержащего три реплики: - -``` xml - - ... - - - - example-perftest01j.yandex.ru - 9000 - - - example-perftest02j.yandex.ru - 9000 - - - example-perftest03j.yandex.ru - 9000 - - - - -``` - -Чтобы включить собственную репликацию [Смотритель зоопарка](http://zookeeper.apache.org/) требуемый. ClickHouse заботится о согласованности данных во всех репликах и автоматически запускает процедуру восстановления после сбоя. Рекомендуется развернуть кластер ZooKeeper на отдельных серверах (где не выполняются никакие другие процессы, включая ClickHouse). - -!!! note "Примечание" - ZooKeeper не является строгим требованием: в некоторых простых случаях вы можете дублировать данные, записав их во все реплики из кода вашего приложения. Такой подход является **нет** рекомендуется, чтобы в этом случае ClickHouse не мог гарантировать согласованность данных на всех репликах. Таким образом, это становится ответственностью вашего приложения. - -Расположение ZooKeeper указано в конфигурационном файле: - -``` xml - - - zoo01.yandex.ru - 2181 - - - zoo02.yandex.ru - 2181 - - - zoo03.yandex.ru - 2181 - - -``` - -Кроме того, нам нужно установить макросы для идентификации каждого осколка и реплики, которые используются при создании таблицы: - -``` xml - - 01 - 01 - -``` - -Если в данный момент при создании реплицированной таблицы реплик нет, то создается новая первая реплика. Если уже существуют живые реплики, то новая реплика клонирует данные из существующих. У вас есть возможность сначала создать все реплицированные таблицы, а затем вставить в них данные. Другой вариант-создать некоторые реплики и добавить другие после или во время вставки данных. - -``` sql -CREATE TABLE tutorial.hits_replica (...) -ENGINE = ReplcatedMergeTree( - '/clickhouse_perftest/tables/{shard}/hits', - '{replica}' -) -... -``` - -Здесь мы используем [ReplicatedMergeTree](../engines/table_engines/mergetree_family/replication.md) настольный двигатель. В параметрах мы указываем путь ZooKeeper, содержащий идентификаторы сегментов и реплик. - -``` sql -INSERT INTO tutorial.hits_replica SELECT * FROM tutorial.hits_local; -``` - -Репликация работает в режиме мульти-мастер. Данные могут быть загружены в любую реплику, а затем система автоматически синхронизирует их с другими экземплярами. Репликация является асинхронной, поэтому в данный момент не все реплики могут содержать недавно вставленные данные. По крайней мере, одна реплика должна быть готова, чтобы обеспечить прием данных. Другие будут синхронизировать данные и восстанавливать согласованность, как только они снова станут активными. Обратите внимание, что этот подход допускает низкую вероятность потери недавно вставленных данных. - -[Оригинальная статья](https://clickhouse.tech/docs/en/getting_started/tutorial/) diff --git a/docs/ru/getting_started/tutorial.md b/docs/ru/getting_started/tutorial.md new file mode 120000 index 00000000000..18b86bb2e9c --- /dev/null +++ b/docs/ru/getting_started/tutorial.md @@ -0,0 +1 @@ +en/getting_started/tutorial.md \ No newline at end of file diff --git a/docs/ru/introduction/adopters.md b/docs/ru/introduction/adopters.md deleted file mode 100644 index 5f8b825353c..00000000000 --- a/docs/ru/introduction/adopters.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Пользователи ClickHouse {#clickhouse-adopters} - -!!! warning "Оговорка" - Следующий список компаний, использующих ClickHouse, и их истории успеха собраны из открытых источников, поэтому они могут отличаться от текущей реальности. Мы были бы очень признательны, если бы вы поделились историей принятия ClickHouse в свою компанию и [добавьте его в список](https://github.com/ClickHouse/ClickHouse/edit/master/docs/en/introduction/adopters.md), но, пожалуйста, убедитесь, что у вас не будет никаких проблем с NDA, сделав это. Предоставление обновлений с публикациями от других компаний также полезно. - -| Компания | Промышленность | Usecase | Размер кластера | (Un)Сжатый Размер Данных\* | Ссылка | -|---------------------------------------------------------------------------------|----------------------------------------|-----------------------------|------------------------------------------------------------|------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [2ГИС](https://2gis.ru) | Карты | Мониторинг | — | — | [Говорить по-русски, июль 2019](https://youtu.be/58sPkXfq6nw) | -| [Браузер Aloha](https://alohabrowser.com/) | Мобильное приложение | Серверная часть браузера | — | — | [Слайды на русском языке, май 2019 года](https://github.com/yandex/clickhouse-presentations/blob/master/meetup22/aloha.pdf) | -| [Компания Amadeus](https://amadeus.com/) | Путешествовать | Аналитика | — | — | [Пресс-Релиз, Апрель 2018 Года](https://www.altinity.com/blog/2018/4/5/amadeus-technologies-launches-investment-and-insights-tool-based-on-machine-learning-and-strategy-algorithms) | -| [Компания](https://www.appsflyer.com) | Мобильная аналитика | Главный продукт | — | — | [Говорить по-русски, июль 2019](https://www.youtube.com/watch?v=M3wbRlcpBbY) | -| [ArenaData](https://arenadata.tech/) | Платформа данных | Главный продукт | — | — | [Слайды на русском языке, декабрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup38/indexes.pdf) | -| [На Badoo](https://badoo.com) | Знакомства | Таймсерии | — | — | [Слайды на русском языке, декабрь 2019 года](https://presentations.clickhouse.tech/meetup38/forecast.pdf) | -| [Бенокс](https://www.benocs.com/) | Сетевая телеметрия и аналитика | Главный продукт | — | — | [Слайды на английском языке, октябрь 2017 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup9/lpm.pdf) | -| [Блумберг](https://www.bloomberg.com/) | Финансы, СМИ | Мониторинг | 102 сервера | — | [Слайды, Май 2018 Года](https://www.slideshare.net/Altinity/http-analytics-for-6m-requests-per-second-using-clickhouse-by-alexander-bocharov) | -| [Блокси](https://bloxy.info) | Блокчейн | Аналитика | — | — | [Слайды на русском языке, август 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup17/4_bloxy.pptx) | -| `Dataliance/UltraPower` | Телекоммуникационный | Аналитика | — | — | [Слайды на китайском языке, январь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup12/telecom.pdf) | -| [CARTO](https://carto.com/) | Бизнес-разведка | Гео аналитика | — | — | [Геопространственная обработка с помощью Clickhouse](https://carto.com/blog/geospatial-processing-with-clickhouse/) | -| [CERN](http://public.web.cern.ch/public/) | Исследование | Эксперимент | — | — | [Пресс-релиз, апрель 2012 года](https://www.yandex.com/company/press_center/press_releases/2012/2012-04-10/) | -| [Компании Cisco](http://cisco.com/) | Сетевой | Анализ трафика | — | — | [Молниеносный разговор, октябрь 2019 года](https://youtu.be/-hI1vDR2oPY?t=5057) | -| [Ценные Бумаги Цитадели](https://www.citadelsecurities.com/) | Финансы | — | — | — | [Взнос, Март 2019 Года](https://github.com/ClickHouse/ClickHouse/pull/4774) | -| [Ситимобил](https://city-mobil.ru) | Такси | Аналитика | — | — | [Запись в блоге на русском языке, март 2020 года](https://habr.com/en/company/citymobil/blog/490660/) | -| [ContentSquare](https://contentsquare.com) | Веб-аналитика | Главный продукт | — | — | [Запись в блоге на французском языке, ноябрь 2018 года](http://souslecapot.net/2018/11/21/patrick-chatain-vp-engineering-chez-contentsquare-penser-davantage-amelioration-continue-que-revolution-constante/) | -| [Cloudflare](https://cloudflare.com) | CDN | Анализ трафика | 36 серверов | — | [Сообщение в блоге, май 2017 года](https://blog.cloudflare.com/how-cloudflare-analyzes-1m-dns-queries-per-second/), [Сообщение в блоге, март 2018 года](https://blog.cloudflare.com/http-analytics-for-6m-requests-per-second-using-clickhouse/) | -| [Корунет](https://coru.net/) | Аналитика | Главный продукт | — | — | [Слайды на английском языке, апрель 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup21/predictive_models.pdf) | -| [CraiditX 氪信](https://creditx.com) | Финансовый ИИ | Анализ | — | — | [Слайды на английском языке, ноябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup33/udf.pptx) | -| [Criteo / Storetail](https://www.criteo.com/) | Розничная торговля | Главный продукт | — | — | [Слайды на английском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup18/3_storetail.pptx) | -| [Дойче банк](https://db.com) | Финансы | Би аналитика | — | — | [Слайды на английском языке, октябрь 2019 года](https://bigdatadays.ru/wp-content/uploads/2019/10/D2-H3-3_Yakunin-Goihburg.pdf) | -| [Дива-е](https://www.diva-e.com) | Цифровой Консалтинг | Главный продукт | — | — | [Слайды на английском языке, сентябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup29/ClickHouse-MeetUp-Unusual-Applications-sd-2019-09-17.pdf) | -| [Компания Exness](https://www.exness.com) | Торговый | Метрики, Ведение Журнала | — | — | [Разговор на русском языке, май 2019 года](https://youtu.be/_rpU-TvSfZ8?t=3215) | -| [Джинн](https://geniee.co.jp) | Рекламная сеть | Главный продукт | — | — | [Запись в блоге на японском языке, июль 2017 года](https://tech.geniee.co.jp/entry/2017/07/20/160100) | -| [HUYA](https://www.huya.com/) | Потоковое видео | Аналитика | — | — | [Слайды на китайском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/7.%20ClickHouse万亿数据分析实践%20李本旺(sundy-li)%20虎牙.pdf) | -| [Идеалиста](https://www.idealista.com) | Недвижимость | Аналитика | — | — | [Сообщение в блоге на английском языке, апрель 2019 года](https://clickhouse.yandex/blog/en/clickhouse-meetup-in-madrid-on-april-2-2019) | -| [Infovista](https://www.infovista.com/) | Сети | Аналитика | — | — | [Слайды на английском языке, октябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup30/infovista.pdf) | -| [Компания innogames](https://www.innogames.com) | Игры | Метрики, Ведение Журнала | — | — | [Слайды на русском языке, сентябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup28/graphite_and_clickHouse.pdf) | -| [Интегрос](https://integros.com) | Платформа для видеосервисов | Аналитика | — | — | [Слайды на русском языке, май 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup22/strategies.pdf) | -| [Данные По Кадьяку](https://www.kodiakdata.com/) | Облака | Главный продукт | — | — | [Слайды на английском языке, апрель 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup13/kodiak_data.pdf) | -| [Контур](https://kontur.ru) | Разработка программного обеспечения | Метрика | — | — | [Говорить по-русски, ноябрь 2018](https://www.youtube.com/watch?v=U4u4Bd0FtrY) | -| [LifeStreet](https://lifestreet.com/) | Рекламная сеть | Главный продукт | 75 серверов (3 реплики) | 5.27 ПИБ | [Запись в блоге на русском языке, февраль 2017 года](https://habr.com/en/post/322620/) | -| [Mail.ru Облачные Решения](https://mcs.mail.ru/) | Облачные сервисы | Главный продукт | — | — | [Запуск экземпляра ClickHouse на русском языке](https://mcs.mail.ru/help/db-create/clickhouse#) | -| [MessageBird](https://www.messagebird.com) | Электросвязь | Статистика | — | — | [Слайды на английском языке, ноябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup20/messagebird.pdf) | -| [MGID](https://www.mgid.com/) | Рекламная сеть | Веб-аналитика | — | — | [Наш опыт внедрения аналитической СУБД ClickHouse на русском языке](http://gs-studio.com/news-about-it/32777----clickhouse---c) | -| [OneAPM](https://www.oneapm.com/) | Мониторинг и анализ данных | Главный продукт | — | — | [Слайды на китайском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/8.%20clickhouse在OneAPM的应用%20杜龙.pdf) | -| [ПРАГМА Инноваций](http://www.pragma-innovation.fr/) | Телеметрия и анализ Больших Данных | Главный продукт | — | — | [Слайды на английском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup18/4_pragma_innovation.pdf) | -| [QINGCLOUD](https://www.qingcloud.com/) | Облачные сервисы | Главный продукт | — | — | [Слайды на китайском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/4.%20Cloud%20%2B%20TSDB%20for%20ClickHouse%20张健%20QingCloud.pdf) | -| [Qrator](https://qrator.net) | Защита от DDoS-атак | Главный продукт | — | — | [Сообщение В Блоге, Март 2019 Года](https://blog.qrator.net/en/clickhouse-ddos-mitigation_37/) | -| [Beijing PERCENT Information Technology Co., Лимитед.](https://www.percent.cn/) | Аналитика | Главный продукт | — | — | [Слайды на китайском языке, июнь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup24/4.%20ClickHouse万亿数据双中心的设计与实践%20.pdf) | -| [Бродяга](https://rambler.ru) | Интернет услуги | Аналитика | — | — | [Говорить по-русски, апрель 2018](https://medium.com/@ramblertop/разработка-api-clickhouse-для-рамблер-топ-100-f4c7e56f3141) | -| [Tencent](https://www.tencent.com) | Обмен сообщениями | Регистрация | — | — | [Говорить по-китайски, ноябрь 2019](https://youtu.be/T-iVQRuw-QY?t=5050) | -| [Движения Звезд](https://trafficstars.com/) | Рекламная сеть | — | — | — | [Слайды на русском языке, май 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup15/lightning/ninja.pdf) | -| [S7 Airlines](https://www.s7.ru) | Авиакомпании | Метрики, Ведение Журнала | — | — | [Разговор на русском языке, март 2019 года](https://www.youtube.com/watch?v=nwG68klRpPg&t=15s) | -| [Общий](https://www.semrush.com/) | Маркетинг | Главный продукт | — | — | [Слайды на русском языке, август 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup17/5_semrush.pdf) | -| [scireum ГмбХ](https://www.scireum.de/) | электронная коммерция | Главный продукт | — | — | [Говорить по-немецки, февраль 2020](https://www.youtube.com/watch?v=7QWAn5RbyR4) | -| [Караул](https://sentry.io/) | Разработчик | Бэкэнд для продукта | — | — | [Сообщение в блоге на английском языке, май 2019 года](https://blog.sentry.io/2019/05/16/introducing-snuba-sentrys-new-search-infrastructure) | -| [SGK](http://www.sgk.gov.tr/wps/portal/sgk/tr) | Государственное Социальное Обеспечение | Аналитика | — | — | [Слайды на английском языке, ноябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup35/ClickHouse%20Meetup-Ramazan%20POLAT.pdf) | -| [СЕО.делать](https://seo.do/) | Аналитика | Главный продукт | — | — | [Слайды на английском языке, ноябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup35/CH%20Presentation-%20Metehan%20Çetinkaya.pdf) | -| [Зина](http://english.sina.com/index.html) | Новости | — | — | — | [Слайды на китайском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/6.%20ClickHouse最佳实践%20高鹏_新浪.pdf) | -| [SMI2](https://smi2.ru/) | Новости | Аналитика | — | — | [Запись в блоге на русском языке, ноябрь 2017 года](https://habr.com/ru/company/smi2/blog/314558/) | -| [Чмок](https://www.splunk.com/) | Бизнес-аналитика | Главный продукт | — | — | [Слайды на английском языке, январь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup12/splunk.pdf) | -| [Спотифай](https://www.spotify.com) | Музыка | Экспериментирование | — | — | [Слайды, Июль 2018 Года](https://www.slideshare.net/glebus/using-clickhouse-for-experimentation-104247173) | -| [Tencent](https://www.tencent.com) | Большие данные | Обработка данных | — | — | [Слайды на китайском языке, октябрь 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/5.%20ClickHouse大数据集群应用_李俊飞腾讯网媒事业部.pdf) | -| [Убер](https://www.uber.com) | Такси | Регистрация | — | — | [Слайды, Февраль 2020 Года](https://presentations.clickhouse.tech/meetup40/uber.pdf) | -| [ВКонтакте](https://vk.com) | Социальная сеть | Статистика, Ведение Журнала | — | — | [Слайды на русском языке, август 2018 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup17/3_vk.pdf) | -| [Мудрецы](https://wisebits.com/) | IT-решение | Аналитика | — | — | [Слайды на русском языке, май 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup22/strategies.pdf) | -| [Технология Сяосин.](https://www.xiaoheiban.cn/) | Образование | Общая цель | — | — | [Слайды на английском языке, ноябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup33/sync-clickhouse-with-mysql-mongodb.pptx) | -| [Сималайя](https://www.ximalaya.com/) | Общий доступ к аудио | OLAP | — | — | [Слайды на английском языке, ноябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup33/ximalaya.pdf) | -| [Облако Яндекса](https://cloud.yandex.ru/services/managed-clickhouse) | Публичное Облако | Главный продукт | — | — | [Разговор на русском языке, декабрь 2019 года](https://www.youtube.com/watch?v=pgnak9e_E0o) | -| [DataLens Яндекс](https://cloud.yandex.ru/services/datalens) | Бизнес-разведка | Главный продукт | — | — | [Слайды на русском языке, декабрь 2019 года](https://presentations.clickhouse.tech/meetup38/datalens.pdf) | -| [Яндекс Маркет](https://market.yandex.ru/) | электронная коммерция | Метрики, Ведение Журнала | — | — | [Разговор на русском языке, январь 2019 года](https://youtu.be/_l1qP0DyBcA?t=478) | -| [Яндекс Метрика](https://metrica.yandex.com) | Веб-аналитика | Главный продукт | 360 серверов в одном кластере, 1862 сервера в одном отделе | 66.41 ПИБ / 5.68 ПИБ | [Слайды, Февраль 2020 Года](https://presentations.clickhouse.tech/meetup40/introduction/#13) | -| [ЦВТ](https://htc-cs.ru/) | Разработка программного обеспечения | Метрики, Ведение Журнала | — | — | [Сообщение в блоге, март 2019 года, на русском языке](https://vc.ru/dev/62715-kak-my-stroili-monitoring-na-prometheus-clickhouse-i-elk) | -| [МКБ](https://mkb.ru/) | Банк | Мониторинг веб-систем | — | — | [Слайды на русском языке, сентябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup28/mkb.pdf) | -| [金数据](https://jinshuju.net) | Би аналитика | Главный продукт | — | — | [Слайды на китайском языке, октябрь 2019 года](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup24/3.%20金数据数据架构调整方案Public.pdf) | - -[Оригинальная статья](https://clickhouse.tech/docs/en/introduction/adopters/) diff --git a/docs/ru/introduction/adopters.md b/docs/ru/introduction/adopters.md new file mode 120000 index 00000000000..b9b77a27eb9 --- /dev/null +++ b/docs/ru/introduction/adopters.md @@ -0,0 +1 @@ +en/introduction/adopters.md \ No newline at end of file diff --git a/docs/ru/operations/optimizing_performance/sampling_query_profiler.md b/docs/ru/operations/optimizing_performance/sampling_query_profiler.md deleted file mode 100644 index d2cc9738749..00000000000 --- a/docs/ru/operations/optimizing_performance/sampling_query_profiler.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Выборки Профилировщик Запросов {#sampling-query-profiler} - -ClickHouse запускает профилировщик выборок, который позволяет анализировать выполнение запросов. С помощью profiler можно найти подпрограммы исходного кода, которые наиболее часто используются во время выполнения запроса. Вы можете отслеживать процессорное время и время работы настенных часов, включая время простоя. - -Чтобы использовать профилировщик: - -- Настройка программы [журнал трассировки](../server_configuration_parameters/settings.md#server_configuration_parameters-trace_log) раздел конфигурации сервера. - - В этом разделе настраиваются следующие параметры: [журнал трассировки](../../operations/optimizing_performance/sampling_query_profiler.md#system_tables-trace_log) системная таблица, содержащая результаты работы профилировщика. Он настроен по умолчанию. Помните, что данные в этой таблице действительны только для работающего сервера. После перезагрузки сервера ClickHouse не очищает таблицу, и все сохраненные адреса виртуальной памяти могут стать недействительными. - -- Настройка программы [query\_profiler\_cpu\_time\_period\_ns](../settings/settings.md#query_profiler_cpu_time_period_ns) или [query\_profiler\_real\_time\_period\_ns](../settings/settings.md#query_profiler_real_time_period_ns) настройки. Обе настройки можно использовать одновременно. - - Эти параметры позволяют настроить таймеры профилировщика. Поскольку это параметры сеанса, вы можете получить различную частоту дискретизации для всего сервера, отдельных пользователей или профилей пользователей, для вашего интерактивного сеанса и для каждого отдельного запроса. - -Частота дискретизации по умолчанию составляет одну выборку в секунду, и включены как ЦП, так и реальные таймеры. Эта частота позволяет собрать достаточно информации о кластере ClickHouse. В то же время, работая с такой частотой, профилировщик не влияет на производительность сервера ClickHouse. Если вам нужно профилировать каждый отдельный запрос, попробуйте использовать более высокую частоту дискретизации. - -Для того чтобы проанализировать `trace_log` системная таблица: - -- Установите устройство `clickhouse-common-static-dbg` пакет. Видеть [Установка из пакетов DEB](../../getting_started/install.md#install-from-deb-packages). - -- Разрешить функции самоанализа с помощью [allow\_introspection\_functions](../settings/settings.md#settings-allow_introspection_functions) установка. - - По соображениям безопасности функции самоанализа по умолчанию отключены. - -- Используйте `addressToLine`, `addressToSymbol` и `demangle` [функции самоанализа](../../operations/optimizing_performance/sampling_query_profiler.md) чтобы получить имена функций и их позиции в коде ClickHouse. Чтобы получить профиль для какого-либо запроса, вам необходимо агрегировать данные из `trace_log` стол. Вы можете агрегировать данные по отдельным функциям или по всем трассировкам стека. - -Если вам нужно визуализировать `trace_log` информация, попробуйте [огнемет](../../interfaces/third-party/gui/#clickhouse-flamegraph) и [speedscope](https://github.com/laplab/clickhouse-speedscope). - -## Пример {#example} - -В этом примере мы: - -- Фильтрация `trace_log` данные по идентификатору запроса и текущей дате. - -- Агрегирование по трассировке стека. - -- Используя функции интроспекции, мы получим отчет о: - - - Имена символов и соответствующие им функции исходного кода. - - Расположение исходных кодов этих функций. - - - -``` sql -SELECT - count(), - arrayStringConcat(arrayMap(x -> concat(demangle(addressToSymbol(x)), '\n ', addressToLine(x)), trace), '\n') AS sym -FROM system.trace_log -WHERE (query_id = 'ebca3574-ad0a-400a-9cbc-dca382f5998c') AND (event_date = today()) -GROUP BY trace -ORDER BY count() DESC -LIMIT 10 -``` - -``` text -{% include "operations/performance/sampling_query_profiler_example_result.txt" %} -``` diff --git a/docs/ru/operations/optimizing_performance/sampling_query_profiler.md b/docs/ru/operations/optimizing_performance/sampling_query_profiler.md new file mode 120000 index 00000000000..565f39130fb --- /dev/null +++ b/docs/ru/operations/optimizing_performance/sampling_query_profiler.md @@ -0,0 +1 @@ +en/operations/optimizing_performance/sampling_query_profiler.md \ No newline at end of file diff --git a/docs/ru/operations/performance_test.md b/docs/ru/operations/performance_test.md deleted file mode 100644 index 9b5c6f4fed3..00000000000 --- a/docs/ru/operations/performance_test.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Как Протестировать Ваше Оборудование С Помощью ClickHouse {#how-to-test-your-hardware-with-clickhouse} - -С помощью этой инструкции вы можете запустить базовый тест производительности ClickHouse на любом сервере без установки пакетов ClickHouse. - -1. Идти к «commits» страница: https://github.com/ClickHouse/ClickHouse/commits/master - -2. Нажмите на первую зеленую галочку или красный крест с зеленым цветом «ClickHouse Build Check» и нажмите на кнопку «Details» ссылка рядом «ClickHouse Build Check». - -3. Скопируйте ссылку на «clickhouse» двоичный код для amd64 или aarch64. - -4. ssh к серверу и скачать его с помощью wget: - - - - # For amd64: - wget https://clickhouse-builds.s3.yandex.net/0/00ba767f5d2a929394ea3be193b1f79074a1c4bc/1578163263_binary/clickhouse - # For aarch64: - wget https://clickhouse-builds.s3.yandex.net/0/00ba767f5d2a929394ea3be193b1f79074a1c4bc/1578161264_binary/clickhouse - # Then do: - chmod a+x clickhouse - -1. Скачать конфиги: - - - - wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/programs/server/config.xml - wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/programs/server/users.xml - mkdir config.d - wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/programs/server/config.d/path.xml -O config.d/path.xml - wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/programs/server/config.d/log_to_console.xml -O config.d/log_to_console.xml - -1. Скачать тест файлы: - - - - wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/benchmark/clickhouse/benchmark-new.sh - chmod a+x benchmark-new.sh - wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/benchmark/clickhouse/queries.sql - -1. Загрузите тестовые данные в соответствии с [Яндекс.Набор метрика](../getting_started/example_datasets/metrica.md) инструкция («hits» таблица, содержащая 100 миллионов строк). - - - - wget https://clickhouse-datasets.s3.yandex.net/hits/partitions/hits_100m_obfuscated_v1.tar.xz - tar xvf hits_100m_obfuscated_v1.tar.xz -C . - mv hits_100m_obfuscated_v1/* . - -1. Запустите сервер: - - - - ./clickhouse server - -1. Проверьте данные: ssh на сервер в другом терминале - - - - ./clickhouse client --query "SELECT count() FROM hits_100m_obfuscated" - 100000000 - -1. Отредактируйте текст benchmark-new.sh, изменение «clickhouse-client» к «./clickhouse client» и добавить «–max\_memory\_usage 100000000000» параметр. - - - - mcedit benchmark-new.sh - -1. Выполнить тест: - - - - ./benchmark-new.sh hits_100m_obfuscated - -1. Отправьте номера и информацию о конфигурации вашего оборудования по адресу clickhouse-feedback@yandex-team.com - -Все результаты опубликованы здесь: https://clickhouse-да.технология / benchmark\_hardware.HTML diff --git a/docs/ru/operations/performance_test.md b/docs/ru/operations/performance_test.md new file mode 120000 index 00000000000..3787adb92bd --- /dev/null +++ b/docs/ru/operations/performance_test.md @@ -0,0 +1 @@ +en/operations/performance_test.md \ No newline at end of file diff --git a/docs/ru/operations/utilities/clickhouse-benchmark.md b/docs/ru/operations/utilities/clickhouse-benchmark.md deleted file mode 100644 index 5467a58676e..00000000000 --- a/docs/ru/operations/utilities/clickhouse-benchmark.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# clickhouse-бенчмарк {#clickhouse-benchmark} - -Подключается к серверу ClickHouse и повторно отправляет указанные запросы. - -Синтаксис: - -``` bash -$ echo "single query" | clickhouse-benchmark [keys] -``` - -или - -``` bash -$ clickhouse-benchmark [keys] <<< "single query" -``` - -Если вы хотите отправить набор запросов, создайте текстовый файл и поместите каждый запрос в отдельную строку в этом файле. Например: - -``` sql -SELECT * FROM system.numbers LIMIT 10000000 -SELECT 1 -``` - -Затем передайте этот файл на стандартный вход `clickhouse-benchmark`. - -``` bash -clickhouse-benchmark [keys] < queries_file -``` - -## Ключи {#clickhouse-benchmark-keys} - -- `-c N`, `--concurrency=N` — Number of queries that `clickhouse-benchmark` посылает одновременно. Значение по умолчанию: 1. -- `-d N`, `--delay=N` — Interval in seconds between intermediate reports (set 0 to disable reports). Default value: 1. -- `-h WORD`, `--host=WORD` — Server host. Default value: `localhost`. Для [режим сравнения](#clickhouse-benchmark-comparison-mode) вы можете использовать несколько `-h` ключи. -- `-p N`, `--port=N` — Server port. Default value: 9000. For the [режим сравнения](#clickhouse-benchmark-comparison-mode) вы можете использовать несколько `-p` ключи. -- `-i N`, `--iterations=N` — Total number of queries. Default value: 0. -- `-r`, `--randomize` — Random order of queries execution if there is more then one input query. -- `-s`, `--secure` — Using TLS connection. -- `-t N`, `--timelimit=N` — Time limit in seconds. `clickhouse-benchmark` прекращает отправку запросов по достижении указанного срока. Значение по умолчанию: 0 (ограничение по времени отключено). -- `--confidence=N` — Level of confidence for T-test. Possible values: 0 (80%), 1 (90%), 2 (95%), 3 (98%), 4 (99%), 5 (99.5%). Default value: 5. In the [режим сравнения](#clickhouse-benchmark-comparison-mode) `clickhouse-benchmark` выполняет следующие функции: [Независимый двухпробный t-тест Стьюдента](https://en.wikipedia.org/wiki/Student%27s_t-test#Independent_two-sample_t-test) проверьте, не отличаются ли эти два распределения с выбранным уровнем достоверности. -- `--cumulative` — Printing cumulative data instead of data per interval. -- `--database=DATABASE_NAME` — ClickHouse database name. Default value: `default`. -- `--json=FILEPATH` — JSON output. When the key is set, `clickhouse-benchmark` выводит отчет в указанный JSON-файл. -- `--user=USERNAME` — ClickHouse user name. Default value: `default`. -- `--password=PSWD` — ClickHouse user password. Default value: empty string. -- `--stacktrace` — Stack traces output. When the key is set, `clickhouse-bencmark` выводит трассировки стека исключений. -- `--stage=WORD` — Query processing stage at server. ClickHouse stops query processing and returns answer to `clickhouse-benchmark` на указанном этапе. Возможное значение: `complete`, `fetch_columns`, `with_mergeable_state`. Значение по умолчанию: `complete`. -- `--help` — Shows the help message. - -Если вы хотите применить некоторые из них [настройки](../../operations/settings/index.md) для запросов передайте их в качестве ключа `--= SETTING_VALUE`. Например, `--max_memory_usage=1048576`. - -## Выход {#clickhouse-benchmark-output} - -По умолчанию, `clickhouse-benchmark` отчеты для каждого из них `--delay` интервал. - -Пример отчета: - -``` text -Queries executed: 10. - -localhost:9000, queries 10, QPS: 6.772, RPS: 67904487.440, MiB/s: 518.070, result RPS: 67721584.984, result MiB/s: 516.675. - -0.000% 0.145 sec. -10.000% 0.146 sec. -20.000% 0.146 sec. -30.000% 0.146 sec. -40.000% 0.147 sec. -50.000% 0.148 sec. -60.000% 0.148 sec. -70.000% 0.148 sec. -80.000% 0.149 sec. -90.000% 0.150 sec. -95.000% 0.150 sec. -99.000% 0.150 sec. -99.900% 0.150 sec. -99.990% 0.150 sec. -``` - -В отчете вы можете найти:: - -- Количество запросов в системе `Queries executed:` поле. - -- Строка состояния, содержащая (по порядку): - - - Конечная точка сервера ClickHouse. - - Количество обработанных запросов. - - QPS: QPS: сколько запросов сервер выполняет в секунду в течение периода, указанного в `--delay` аргумент. - - RPS: сколько строк сервер читает в секунду в течение периода, указанного в `--delay` аргумент. - - MiB/s: сколько мегабайт сервер читает в секунду в течение периода, указанного в `--delay` аргумент. - - result RPS: сколько строк помещается сервером в результат запроса в секунду в течение периода, указанного в `--delay` аргумент. - - результат MiB/s. сколько мебибайт помещается сервером в результат запроса в секунду в течение периода, указанного в `--delay` аргумент. - -- Процентили времени выполнения запросов. - -## Режим сравнения {#clickhouse-benchmark-comparison-mode} - -`clickhouse-benchmark` можно сравнить производительность для двух запущенных серверов ClickHouse. - -Чтобы использовать режим сравнения, укажите конечные точки обоих серверов по двум парам `--host`, `--port` ключи. Ключи, сопоставленные вместе по позиции в списке аргументов, первые `--host` сопоставляется с первым `--port` и так далее. `clickhouse-benchmark` устанавливает соединения с обоими серверами, а затем отправляет запросы. Каждый запрос адресован случайно выбранному серверу. Результаты отображаются для каждого сервера отдельно. - -## Пример {#clickhouse-benchmark-example} - -``` bash -$ echo "SELECT * FROM system.numbers LIMIT 10000000 OFFSET 10000000" | clickhouse-benchmark -i 10 -``` - -``` text -Loaded 1 queries. - -Queries executed: 6. - -localhost:9000, queries 6, QPS: 6.153, RPS: 123398340.957, MiB/s: 941.455, result RPS: 61532982.200, result MiB/s: 469.459. - -0.000% 0.159 sec. -10.000% 0.159 sec. -20.000% 0.159 sec. -30.000% 0.160 sec. -40.000% 0.160 sec. -50.000% 0.162 sec. -60.000% 0.164 sec. -70.000% 0.165 sec. -80.000% 0.166 sec. -90.000% 0.166 sec. -95.000% 0.167 sec. -99.000% 0.167 sec. -99.900% 0.167 sec. -99.990% 0.167 sec. - - - -Queries executed: 10. - -localhost:9000, queries 10, QPS: 6.082, RPS: 121959604.568, MiB/s: 930.478, result RPS: 60815551.642, result MiB/s: 463.986. - -0.000% 0.159 sec. -10.000% 0.159 sec. -20.000% 0.160 sec. -30.000% 0.163 sec. -40.000% 0.164 sec. -50.000% 0.165 sec. -60.000% 0.166 sec. -70.000% 0.166 sec. -80.000% 0.167 sec. -90.000% 0.167 sec. -95.000% 0.170 sec. -99.000% 0.172 sec. -99.900% 0.172 sec. -99.990% 0.172 sec. -``` diff --git a/docs/ru/operations/utilities/clickhouse-benchmark.md b/docs/ru/operations/utilities/clickhouse-benchmark.md new file mode 120000 index 00000000000..fda8b1a50c7 --- /dev/null +++ b/docs/ru/operations/utilities/clickhouse-benchmark.md @@ -0,0 +1 @@ +en/operations/utilities/clickhouse-benchmark.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2017.md b/docs/ru/whats_new/changelog/2017.md deleted file mode 100644 index 1c820453901..00000000000 --- a/docs/ru/whats_new/changelog/2017.md +++ /dev/null @@ -1,266 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -### ClickHouse релиз 1.1.54327, 2017-12-21 {#clickhouse-release-1-1-54327-2017-12-21} - -Этот выпуск содержит исправления ошибок для предыдущей версии 1.1.54318: - -- Исправлена ошибка с возможным состоянием гонки в репликации, которая могла привести к потере данных. Эта проблема затрагивает версии 1.1.54310 и 1.1.54318. Если вы используете одну из этих версий с Реплицированными таблицами, настоятельно рекомендуется обновить ее. Эта проблема отображается в журналах в предупреждающих сообщениях, таких как `Part ... from own log doesn't exist.` Эта проблема актуальна, даже если вы не видите эти сообщения в журналах. - -### ClickHouse релиз 1.1.54318, 2017-11-30 {#clickhouse-release-1-1-54318-2017-11-30} - -Этот выпуск содержит исправления ошибок для предыдущей версии 1.1.54310: - -- Исправлено некорректное удаление строк при слияниях в движке SummingMergeTree -- Исправлена утечка памяти в несложных движках MergeTree -- Исправлено снижение производительности при частых вставках в двигатели MergeTree -- Исправлена ошибка, из-за которой очередь репликации останавливалась -- Исправлена ротация и архивация журналов сервера - -### ClickHouse релиз 1.1.54310, 2017-11-01 {#clickhouse-release-1-1-54310-2017-11-01} - -#### Новые средства: {#new-features} - -- Пользовательский ключ секционирования для семейства движков таблиц MergeTree. -- [Кафка](https://clickhouse.yandex/docs/en/operations/table_engines/kafka/) настольный двигатель. -- Добавлена поддержка загрузки [CatBoost](https://catboost.yandex/) модели и их применение к данным, хранящимся в ClickHouse. -- Добавлена поддержка часовых поясов с нецелочисленными смещениями от UTC. -- Добавлена поддержка арифметических операций с временными интервалами. -- Диапазон значений для типов Date и DateTime расширен до 2105 года. -- Добавил тот `CREATE MATERIALIZED VIEW x TO y` запрос (указывает существующую таблицу для хранения данных материализованного представления). -- Добавил тот `ATTACH TABLE` запрос без аргументов. -- Логика обработки вложенных столбцов с именами, оканчивающимися на-Map в таблице SummingMergeTree, была извлечена в агрегатную функцию sumMap. Теперь вы можете указать такие столбцы явно. -- Максимальный размер словаря IP trie увеличен до 128 миллионов записей. -- Добавлена функция getSizeOfEnumType. -- Добавлена агрегатная функция sumWithOverflow. -- Добавлена поддержка формата ввода Cap'n Proto. -- Теперь вы можете настроить уровень сжатия при использовании алгоритма zstd. - -#### Назад несовместимые изменения: {#backward-incompatible-changes} - -- Создание временных таблиц с движком, отличным от памяти, не допускается. -- Явное создание таблиц с помощью движка View или MaterializedView не допускается. -- Во время создания таблицы новая проверка проверяет, что выражение ключа выборки включено в первичный ключ. - -#### Устранение ошибок: {#bug-fixes} - -- Исправлены зависания при синхронной вставке в распределенную таблицу. -- Исправлено неатомное добавление и удаление деталей в реплицируемых таблицах. -- Данные, вставленные в материализованное представление, не подвергаются ненужной дедупликации. -- Выполнение запроса к распределенной таблице, для которой локальная реплика отстает, а удаленные реплики недоступны, больше не приводит к ошибке. -- Пользователям не нужны разрешения на доступ к `default` база данных для создания временных таблиц больше не существует. -- Исправлен сбой при указании типа массива без аргументов. -- Исправлены зависания, когда дисковый том, содержащий журналы сервера, заполнен. -- Исправлено переполнение в функции toRelativeWeekNum для первой недели эпохи Unix. - -#### Улучшения сборки: {#build-improvements} - -- Несколько сторонних библиотек (особенно Poco) были обновлены и преобразованы в подмодули git. - -### ClickHouse релиз 1.1.54304, 2017-10-19 {#clickhouse-release-1-1-54304-2017-10-19} - -#### Новые средства: {#new-features-1} - -- Поддержка TLS в собственном протоколе (чтобы включить, установите `tcp_ssl_port` в `config.xml` ). - -#### Устранение ошибок: {#bug-fixes-1} - -- `ALTER` для реплицированных таблиц теперь пытается начать работать как можно скорее. -- Исправлен сбой при чтении данных с настройкой `preferred_block_size_bytes=0.` -- Исправлены сбои в работе `clickhouse-client` при нажатии на кнопку `Page Down` -- Правильная интерпретация некоторых сложных запросов с помощью `GLOBAL IN` и `UNION ALL` -- `FREEZE PARTITION` теперь он всегда работает атомарно. -- Пустые почтовые запросы теперь возвращают ответ с кодом 411. -- Исправлены ошибки интерпретации таких выражений, как `CAST(1 AS Nullable(UInt8)).` -- Исправлена ошибка при чтении `Array(Nullable(String))` колонки от `MergeTree` таблицы. -- Исправлен сбой при разборе таких запросов, как `SELECT dummy AS dummy, dummy AS b` -- Пользователи обновляются правильно с недопустимым `users.xml` -- Правильная обработка, когда исполняемый словарь возвращает ненулевой код ответа. - -### ClickHouse релиз 1.1.54292, 2017-09-20 {#clickhouse-release-1-1-54292-2017-09-20} - -#### Новые средства: {#new-features-2} - -- Добавил тот `pointInPolygon` функция для работы с координатами на координатной плоскости. -- Добавил тот `sumMap` агрегатная функция для вычисления суммы массивов, аналогичная `SummingMergeTree`. -- Добавил тот `trunc` функция. Улучшена производительность функций округления (`round`, `floor`, `ceil`, `roundToExp2`) и скорректировал логику их работы. Поменялась логика игры `roundToExp2` функция для дробей и отрицательных чисел. -- Исполняемый файл ClickHouse теперь меньше зависит от версии libc. Один и тот же исполняемый файл ClickHouse может работать на самых разных системах Linux. Существует еще зависимость при использовании скомпилированных запросов (с настройкой `compile = 1` , который не используется по умолчанию). -- Сократилось время, необходимое для динамической компиляции запросов. - -#### Устранение ошибок: {#bug-fixes-2} - -- Исправлена ошибка, которая иногда производилась `part ... intersects previous part` сообщения и ослабленная согласованность реплик. -- Исправлена ошибка, из-за которой сервер блокировался, если ZooKeeper был недоступен во время завершения работы. -- Удалено избыточное ведение журнала при восстановлении реплик. -- Исправлена ошибка в объединении всех реализаций. -- Исправлена ошибка в функции concat, возникшая, если первый столбец в блоке имеет тип массива. -- Прогресс теперь отображается в системе правильно.таблица слияний. - -### ClickHouse релиз 1.1.54289, 2017-09-13 {#clickhouse-release-1-1-54289-2017-09-13} - -#### Новые средства: {#new-features-3} - -- `SYSTEM` запросы для администрирования сервера: `SYSTEM RELOAD DICTIONARY`, `SYSTEM RELOAD DICTIONARIES`, `SYSTEM DROP DNS CACHE`, `SYSTEM SHUTDOWN`, `SYSTEM KILL`. -- Добавлены функции для работы с массивами: `concat`, `arraySlice`, `arrayPushBack`, `arrayPushFront`, `arrayPopBack`, `arrayPopFront`. -- Добавлен `root` и `identity` параметры для конфигурации ZooKeeper. Это позволяет изолировать отдельных пользователей в одном кластере ZooKeeper. -- Добавлены статистические функции `groupBitAnd`, `groupBitOr`, и `groupBitXor` (для совместимости они также доступны под названиями `BIT_AND`, `BIT_OR`, и `BIT_XOR`). -- Внешние словари можно загрузить из MySQL, указав сокет в файловой системе. -- Внешние словари могут быть загружены из MySQL по протоколу SSL (`ssl_cert`, `ssl_key`, `ssl_ca` параметры). -- Добавил тот `max_network_bandwidth_for_user` настройка для ограничения общего использования полосы пропускания для запросов на одного пользователя. -- Поддержка `DROP TABLE` для временных таблиц. -- Поддержка чтения `DateTime` значения в формате временных меток Unix от `CSV` и `JSONEachRow` форматы. -- Запаздывающие реплики в распределенных запросах теперь исключаются по умолчанию (пороговое значение по умолчанию-5 минут). -- Блокировка FIFO используется во время ALTER: запрос ALTER не блокируется бесконечно для непрерывно выполняемых запросов. -- Возможность установки `umask` в конфигурационном файле. -- Улучшенная производительность для запросов с помощью `DISTINCT` . - -#### Устранение ошибок: {#bug-fixes-3} - -- Улучшен процесс удаления старых узлов в ZooKeeper. Раньше старые узлы иногда не удалялись, если были очень частые вставки, что приводило к медленному завершению работы сервера, среди прочего. -- Исправлена рандомизация при выборе хостов для подключения к ZooKeeper. -- Исправлено исключение запаздывающих реплик в распределенных запросах, если реплика является localhost. -- Исправлена ошибка, когда часть данных в a `ReplicatedMergeTree` стол может быть сломан после запуска `ALTER MODIFY` на элементе в `Nested` структура. -- Исправлена ошибка, которая могла привести к тому, что запросы SELECT «hang». -- Улучшения в распределенных DDL-запросах. -- Исправлен запрос `CREATE TABLE ... AS `. -- Разрешен тупик в работе `ALTER ... CLEAR COLUMN IN PARTITION` запрос для `Buffer` таблицы. -- Исправлено недопустимое значение по умолчанию для `Enum` s (0 вместо минимума) при использовании `JSONEachRow` и `TSKV` форматы. -- Разрешен внешний вид зомби-процессов при использовании словаря с помощью `executable` источник. -- Исправлена обработка выхода онлайн / оффлайн для запроса. - -#### Улучшен рабочий процесс разработки и сборки ClickHouse: {#improved-workflow-for-developing-and-assembling-clickhouse} - -- Вы можете использовать `pbuilder` чтобы построить ClickHouse. -- Вы можете использовать `libc++` вместо `libstdc++` для сборок на Linux. -- Добавлены инструкции по использованию инструментов статического анализа кода: `Coverage`, `clang-tidy`, `cppcheck`. - -#### Пожалуйста, обратите внимание при обновлении: {#please-note-when-upgrading} - -- Теперь существует более высокое значение по умолчанию для параметра MergeTree `max_bytes_to_merge_at_max_space_in_pool` (максимальный общий размер частей данных для слияния, в байтах): он увеличился со 100 гигабайт до 150 гигабайт. Это может привести к большим слияниям, выполняемым после обновления сервера, что может привести к увеличению нагрузки на дисковую подсистему. Если свободное пространство, доступное на сервере, меньше чем в два раза общего объема выполняемых слияний, это приведет к остановке всех других слияний, включая слияния небольших частей данных. В результате запросы INSERT завершатся ошибкой с сообщением «Merges are processing significantly slower than inserts.» Используйте `SELECT * FROM system.merges` запрос на мониторинг ситуации. Вы также можете проверить следующее: `DiskSpaceReservedForMerge` метрика в системе `system.metrics` таблица, или в графите. Вам не нужно ничего делать, чтобы исправить это, так как проблема будет решена сама собой, как только большие слияния закончатся. Если вы сочтете это неприемлемым, вы можете восстановить предыдущее значение для `max_bytes_to_merge_at_max_space_in_pool` установка. Чтобы сделать это, перейдите в раздел раздел в конфигурации.xml, набор ``` ``107374182400 ``` и перезагрузите сервер. - -### ClickHouse релиз 1.1.54284, 2017-08-29 {#clickhouse-release-1-1-54284-2017-08-29} - -- Это исправленный выпуск для предыдущей версии 1.1.54282. Он исправляет утечки в каталоге запчастей в ZooKeeper. - -### ClickHouse релиз 1.1.54282, 2017-08-23 {#clickhouse-release-1-1-54282-2017-08-23} - -Этот выпуск содержит исправления ошибок для предыдущей версии 1.1.54276: - -- Исправлено `DB::Exception: Assertion violation: !_path.empty()` при вставке в распределенную таблицу. -- Исправлен синтаксический анализ при вставке в формат RowBinary, если входные данные начинаются с';'. -- Errors during runtime compilation of certain aggregate functions (e.g. `groupArray()`). - -### Clickhouse Релиз 1.1.54276, 2017-08-16 {#clickhouse-release-1-1-54276-2017-08-16} - -#### Новые средства: {#new-features-4} - -- Добавлен дополнительный раздел для запроса SELECT. Пример запроса: `WITH 1+1 AS a SELECT a, a*a` -- Вставка может быть выполнена синхронно в распределенной таблице: OK возвращается только после того, как все данные сохранены на всех осколках. Это активируется установкой insert\_distributed\_sync=1. -- Добавлен тип данных UUID для работы с 16-байтовыми идентификаторами. -- Добавлены псевдонимы CHAR, FLOAT и других типов для совместимости с таблицей. -- Добавлены функции toYYYYMM, toYYYYMMDD и toYYYYMMDDhhmmss для преобразования времени в числа. -- Вы можете использовать IP-адреса (вместе с именем хоста) для идентификации серверов для кластеризованных запросов DDL. -- Добавлена поддержка непостоянных аргументов и отрицательных смещений в функции `substring(str, pos, len).` -- Добавлен параметр max\_size для `groupArray(max_size)(column)` агрегатная функция и оптимизированная ее производительность. - -#### Основное изменение: {#main-changes} - -- Улучшения безопасности: все файлы сервера создаются с разрешениями 0640 (могут быть изменены с помощью параметр config). -- Улучшены сообщения об ошибках для запросов с неверным синтаксисом. -- Значительно сокращается потребление памяти и повышается производительность при слиянии больших разделов данных MergeTree. -- Значительно повысилась производительность слияний данных для заменяющего движка Mergetree. -- Улучшена производительность асинхронных вставок из распределенной таблицы за счет объединения нескольких исходных вставок. Чтобы включить эту функцию, используйте параметр distributed\_directory\_monitor\_batch\_inserts=1. - -#### Назад несовместимые изменения: {#backward-incompatible-changes-1} - -- Изменен двоичный формат агрегатных состояний `groupArray(array_column)` функции для массивов. - -#### Полный список изменений: {#complete-list-of-changes} - -- Добавил тот `output_format_json_quote_denormals` настройка, которая позволяет выводить значения nan и inf в формате JSON. -- Оптимизировано распределение потока при чтении из распределенной таблицы. -- Настройки можно настроить в режиме только для чтения, если значение не изменяется. -- Добавлена возможность извлечения нецелочисленных гранул движка MergeTree для выполнения ограничений на размер блока, указанных в параметре preferred\_block\_size\_bytes. Цель состоит в том, чтобы уменьшить потребление оперативной памяти и увеличить локальность кэша при обработке запросов из таблиц с большими столбцами. -- Эффективное использование индексов, содержащих такие выражения, как `toStartOfHour(x)` для таких условий, как `toStartOfHour(x) op сonstexpr.` -- Добавлены новые настройки для движков MergeTree (раздел merge\_tree в config.XML): - - replicated\_deduplication\_window\_seconds задает количество секунд, разрешенных для дедуплицирующих вставок в реплицируемые таблицы. - - cleanup\_delay\_period устанавливает, как часто нужно запустить программу очистки, чтобы удалить устаревшие данные. - - replicated\_can\_become\_leader может препятствовать тому, чтобы реплика становилась лидером (и назначала слияния). -- Ускоренная очистка для удаления устаревших данных из ZooKeeper. -- Множество улучшений и исправлений для кластеризованных DDL-запросов. Особый интерес представляет новая настройка distributed\_ddl\_task\_timeout, которая ограничивает время ожидания ответа от серверов в кластере. Если запрос ddl не был выполнен на всех хостах, ответ будет содержать ошибку таймаута, и запрос будет выполнен в асинхронном режиме. -- Улучшено отображение трассировок стека в журналах сервера. -- Добавил тот «none» значение для метода сжатия. -- Вы можете использовать несколько разделов dictionaries\_config в config.XML. -- Можно подключиться к MySQL через сокет в файловой системе. -- Система.в таблице деталей появился новый столбец с информацией о размере меток, в байтах. - -#### Устранение ошибок: {#bug-fixes-4} - -- Распределенные таблицы, использующие таблицу слияния, теперь корректно работают для запроса SELECT с условием на `_table` поле. -- Исправлено редкое состояние гонки в ReplicatedMergeTree при проверке частей данных. -- Исправлена возможная заморозка на «leader election» при запуске сервера. -- Параметр max\_replica\_delay\_for\_distributed\_queries был проигнорирован при использовании локальной реплики источника данных. Это было исправлено. -- Исправлено некорректное поведение `ALTER TABLE CLEAR COLUMN IN PARTITION` при попытке очистить несуществующий столбец. -- Исправлено исключение в функции multif при использовании пустых массивов или строк. -- Исправлено чрезмерное выделение памяти при десериализации собственного формата. -- Исправлено некорректное автоматическое обновление словарей Trie. -- Исправлено исключение при выполнении запросов с предложением GROUP BY из таблицы слияния при использовании SAMPLE. -- Исправлена ошибка, из группы при использовании distributed\_aggregation\_memory\_efficient=1. -- Теперь вы можете указать базу данных.таблицы в правой стороне и присоединиться. -- Слишком много потоков было использовано для параллельной агрегации. Это было исправлено. -- Исправлено как то «if» функция работает с аргументами FixedString. -- Выберите из распределенной таблицы неправильно сработавшие осколки с весом 0. Это было исправлено. -- Бегущий `CREATE VIEW IF EXISTS no longer causes crashes.` -- Исправлено некорректное поведение при установке input\_format\_skip\_unknown\_fields=1 и наличии отрицательных чисел. -- Исправлен бесконечный цикл в `dictGetHierarchy()` функция, если в словаре есть какие-то недопустимые данные. -- Исправлено `Syntax error: unexpected (...)` ошибки при выполнении распределенных запросов с вложенными запросами в предложении IN или JOIN и таблицах слияния. -- Исправлена неправильная интерпретация запроса SELECT из таблиц справочника. -- Исправлена ошибка «Cannot mremap» ошибка при использовании массивов в предложениях IN и JOIN с более чем 2 миллиардами элементов. -- Исправлена ошибка отработки отказа для словарей с MySQL в качестве источника. - -#### Улучшен рабочий процесс разработки и сборки ClickHouse: {#improved-workflow-for-developing-and-assembling-clickhouse-1} - -- Сборки могут быть собраны в Аркадии. -- Вы можете использовать gcc 7 для компиляции ClickHouse. -- Параллельные сборки с использованием ccache+distcc теперь работают быстрее. - -### ClickHouse релиз 1.1.54245, 2017-07-04 {#clickhouse-release-1-1-54245-2017-07-04} - -#### Новые средства: {#new-features-5} - -- Распределенный DDL (например, `CREATE TABLE ON CLUSTER`) -- Реплицированный запрос `ALTER TABLE CLEAR COLUMN IN PARTITION.` -- Движок для таблиц словаря (доступ к данным словаря в виде таблицы). -- Компонент Dictionary database engine (этот тип базы данных автоматически содержит таблицы словарей, доступные для всех подключенных внешних словарей). -- Вы можете проверить наличие обновлений в словаре, отправив запрос источнику. -- Полные имена столбцов -- Цитирование идентификаторов с использованием двойных кавычек. -- Сеансы в интерфейсе HTTP. -- Запрос оптимизации для реплицированной таблицы может выполняться не только на лидере. - -#### Назад несовместимые изменения: {#backward-incompatible-changes-2} - -- Удалить набор глобальных. - -#### Несущественные изменения: {#minor-changes} - -- Теперь после срабатывания предупреждения журнал печатает полную трассировку стека. -- Ослаблена проверка количества поврежденных / лишних частей данных при запуске (было слишком много ложных срабатываний). - -#### Устранение ошибок: {#bug-fixes-5} - -- Исправлена плохая связь «sticking» при вставке в распределенную таблицу. -- GLOBAL IN теперь работает для запроса из таблицы слияния, которая смотрит на распределенную таблицу. -- Неверное количество ядер было обнаружено на виртуальной машине Google Compute Engine. Это было исправлено. -- Изменения в том, как работает исполняемый источник кэшированных внешних словарей. -- Исправлено сравнение строк, содержащих нулевые символы. -- Исправлено сравнение полей первичного ключа Float32 с константами. -- Ранее неверная оценка размера поля могла привести к чрезмерно большим распределениям. -- Исправлена ошибка, при отправке запроса столбец допускает значения NULL в таблицу с помощью инструкции Alter. -- Исправлена ошибка при сортировке по нулевому столбцу, если количество строк меньше предельного. -- Исправлен порядок по подзапросу, состоящему только из постоянных значений. -- Ранее реплицированная таблица могла оставаться в недопустимом состоянии после неудачного удаления таблицы. -- Псевдонимы для скалярных подзапросов с пустыми результатами больше не теряются. -- Теперь запрос, который использовал компиляцию, не завершается ошибкой, если файл .so поврежден. diff --git a/docs/ru/whats_new/changelog/2017.md b/docs/ru/whats_new/changelog/2017.md new file mode 120000 index 00000000000..f278c42f170 --- /dev/null +++ b/docs/ru/whats_new/changelog/2017.md @@ -0,0 +1 @@ +en/whats_new/changelog/2017.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2018.md b/docs/ru/whats_new/changelog/2018.md deleted file mode 100644 index 5de3ba68437..00000000000 --- a/docs/ru/whats_new/changelog/2018.md +++ /dev/null @@ -1,1061 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -## ClickHouse релиз 18.16 {#clickhouse-release-18-16} - -### ClickHouse релиз 18.16.1, 2018-12-21 {#clickhouse-release-18-16-1-2018-12-21} - -#### Устранение ошибок: {#bug-fixes} - -- Исправлена ошибка, которая приводила к проблемам с обновлением словарей с источником ODBC. [\#3825](https://github.com/ClickHouse/ClickHouse/issues/3825), [\#3829](https://github.com/ClickHouse/ClickHouse/issues/3829) -- JIT-компиляция агрегатных функций теперь работает с колонками LowCardinality. [\#3838](https://github.com/ClickHouse/ClickHouse/issues/3838) - -#### Улучшения: {#improvements} - -- Добавил тот `low_cardinality_allow_in_native_format` настройка (включена по умолчанию). Если этот параметр отключен, столбцы с низким коэффициентом полезности будут преобразованы в обычные столбцы для запросов SELECT, а обычные столбцы будут ожидаться для запросов INSERT. [\#3879](https://github.com/ClickHouse/ClickHouse/pull/3879) - -#### Улучшения сборки: {#build-improvements} - -- Исправления для сборок на macOS и ARM. - -### ClickHouse релиз 18.16.0, 2018-12-14 {#clickhouse-release-18-16-0-2018-12-14} - -#### Новые средства: {#new-features} - -- `DEFAULT` выражения вычисляются для пропущенных полей при загрузке данных в полуструктурированные входные форматы (`JSONEachRow`, `TSKV`). Эта функция включена с помощью `insert_sample_with_metadata` установка. [\#3555](https://github.com/ClickHouse/ClickHouse/pull/3555) -- То `ALTER TABLE` запрос теперь имеет следующее значение `MODIFY ORDER BY` действие для изменения ключа сортировки при добавлении или удалении столбца таблицы. Это полезно для таблиц в `MergeTree` семейство, выполняющее дополнительные задачи при слиянии на основе этого ключа сортировки, например `SummingMergeTree`, `AggregatingMergeTree` и так далее. [\#3581](https://github.com/ClickHouse/ClickHouse/pull/3581) [\#3755](https://github.com/ClickHouse/ClickHouse/pull/3755) -- Для столиков в центре города `MergeTree` семья, теперь вы можете указать другой ключ сортировки (`ORDER BY`) и индекс (`PRIMARY KEY`). Ключ сортировки может быть длиннее индекса. [\#3581](https://github.com/ClickHouse/ClickHouse/pull/3581) -- Добавил тот `hdfs` функция таблицы и `HDFS` механизм таблиц для импорта и экспорта данных в HDFS. [chenxing-xc](https://github.com/ClickHouse/ClickHouse/pull/3617) -- Добавлены функции для работы с base64: `base64Encode`, `base64Decode`, `tryBase64Decode`. [Александр Крашенинников](https://github.com/ClickHouse/ClickHouse/pull/3350) -- Теперь вы можете использовать параметр для настройки точности `uniqCombined` агрегатная функция (выбор количества ячеек Гиперлога). [\#3406](https://github.com/ClickHouse/ClickHouse/pull/3406) -- Добавил тот `system.contributors` таблица, содержащая имена всех, кто совершил коммиты в ClickHouse. [\#3452](https://github.com/ClickHouse/ClickHouse/pull/3452) -- Добавлена возможность опустить Раздел для `ALTER TABLE ... FREEZE` запрос для резервного копирования всех разделов сразу. [\#3514](https://github.com/ClickHouse/ClickHouse/pull/3514) -- Добавлен `dictGet` и `dictGetOrDefault` функции, которые не требуют указания типа возвращаемого значения. Тип определяется автоматически из описания словаря. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3564) -- Теперь вы можете указать комментарии для столбца в описании таблицы и изменить его с помощью `ALTER`. [\#3377](https://github.com/ClickHouse/ClickHouse/pull/3377) -- Чтение поддерживается для `Join` введите таблицы с простыми ключами. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3728) -- Теперь вы можете указать следующие параметры `join_use_nulls`, `max_rows_in_join`, `max_bytes_in_join`, и `join_overflow_mode` при создании `Join` типизированная таблица. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3728) -- Добавил тот `joinGet` функция, которая позволяет вам использовать a `Join` введите таблицу, как словарь. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3728) -- Добавил тот `partition_key`, `sorting_key`, `primary_key`, и `sampling_key` колонны в сторону `system.tables` таблица для того, чтобы предоставить информацию о ключах таблицы. [\#3609](https://github.com/ClickHouse/ClickHouse/pull/3609) -- Добавил тот `is_in_partition_key`, `is_in_sorting_key`, `is_in_primary_key`, и `is_in_sampling_key` колонны в сторону `system.columns` стол. [\#3609](https://github.com/ClickHouse/ClickHouse/pull/3609) -- Добавил тот `min_time` и `max_time` колонны в сторону `system.parts` стол. Эти столбцы заполняются, когда ключ секционирования является выражением, состоящим из `DateTime` столбцы. [Emmanuel Donin de Rosière](https://github.com/ClickHouse/ClickHouse/pull/3800) - -#### Устранение ошибок: {#bug-fixes-1} - -- Исправления и улучшения производительности для `LowCardinality` тип данных. `GROUP BY` с помощью `LowCardinality(Nullable(...))`. Получение значений `extremes`. Обработка функций высокого порядка. `LEFT ARRAY JOIN`. Распределенный `GROUP BY`. Функции, которые возвращают `Array`. Исполнение приказа `ORDER BY`. Написание в адрес `Distributed` таблицы (nicelulu). Обратная совместимость для `INSERT` запросы от старых клиентов, которые реализуют `Native` протокол. Поддержка `LowCardinality` для `JOIN`. Улучшена производительность при работе в одном потоке. [\#3823](https://github.com/ClickHouse/ClickHouse/pull/3823) [\#3803](https://github.com/ClickHouse/ClickHouse/pull/3803) [\#3799](https://github.com/ClickHouse/ClickHouse/pull/3799) [\#3769](https://github.com/ClickHouse/ClickHouse/pull/3769) [\#3744](https://github.com/ClickHouse/ClickHouse/pull/3744) [\#3681](https://github.com/ClickHouse/ClickHouse/pull/3681) [\#3651](https://github.com/ClickHouse/ClickHouse/pull/3651) [\#3649](https://github.com/ClickHouse/ClickHouse/pull/3649) [\#3641](https://github.com/ClickHouse/ClickHouse/pull/3641) [\#3632](https://github.com/ClickHouse/ClickHouse/pull/3632) [\#3568](https://github.com/ClickHouse/ClickHouse/pull/3568) [\#3523](https://github.com/ClickHouse/ClickHouse/pull/3523) [\#3518](https://github.com/ClickHouse/ClickHouse/pull/3518) -- Исправлено как то `select_sequential_consistency` вариант работает. Ранее, когда этот параметр был включен, неполный результат иногда возвращался после начала записи в новый раздел. [\#2863](https://github.com/ClickHouse/ClickHouse/pull/2863) -- Базы данных правильно задаются при выполнении DDL `ON CLUSTER` запросы и `ALTER UPDATE/DELETE`. [\#3772](https://github.com/ClickHouse/ClickHouse/pull/3772) [\#3460](https://github.com/ClickHouse/ClickHouse/pull/3460) -- Базы данных правильно задаются для вложенных запросов внутри представления. [\#3521](https://github.com/ClickHouse/ClickHouse/pull/3521) -- Исправлена ошибка в работе `PREWHERE` с `FINAL` для `VersionedCollapsingMergeTree`. [7167bfd7](https://github.com/ClickHouse/ClickHouse/commit/7167bfd7b365538f7a91c4307ad77e552ab4e8c1) -- Теперь вы можете использовать `KILL QUERY` чтобы отменить запросы, которые еще не начались, потому что они ждут блокировки таблицы. [\#3517](https://github.com/ClickHouse/ClickHouse/pull/3517) -- Исправлены расчеты даты и времени, если часы были перенесены назад в полночь (это происходит в Иране, а произошло в Москве с 1981 по 1983 год). Ранее это приводило к тому, что время сбрасывалось на день раньше необходимого, а также вызывало неправильное форматирование даты и времени в текстовом формате. [\#3819](https://github.com/ClickHouse/ClickHouse/pull/3819) -- Исправлены ошибки в некоторых случаях `VIEW` и подзапросы, которые опускают базу данных. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3521) -- Исправлено состояние гонки при одновременном чтении из `MATERIALIZED VIEW` и удаление `MATERIALIZED VIEW` из-за того, что внутренняя дверь не запирается `MATERIALIZED VIEW`. [\#3404](https://github.com/ClickHouse/ClickHouse/pull/3404) [\#3694](https://github.com/ClickHouse/ClickHouse/pull/3694) -- Исправлена ошибка `Lock handler cannot be nullptr.` [\#3689](https://github.com/ClickHouse/ClickHouse/pull/3689) -- Исправлена обработка запросов, когда `compile_expressions` опция включена (она включена по умолчанию). Недетерминированные постоянные выражения, такие как `now` функции больше не разворачиваются. [\#3457](https://github.com/ClickHouse/ClickHouse/pull/3457) -- Исправлена ошибка при указании непостоянного аргумента масштаба в `toDecimal32/64/128` функции. -- Исправлена ошибка при попытке вставить массив с помощью `NULL` элементы в системе `Values` форматирование в столбец типа `Array` без `Nullable` (если `input_format_values_interpret_expressions` = 1). [\#3487](https://github.com/ClickHouse/ClickHouse/pull/3487) [\#3503](https://github.com/ClickHouse/ClickHouse/pull/3503) -- Исправлена непрерывная ошибка входа в систему `DDLWorker` если смотритель зоопарка не доступен. [8f50c620](https://github.com/ClickHouse/ClickHouse/commit/8f50c620334988b28018213ec0092fe6423847e2) -- Исправлен тип возврата для `quantile*` функции от `Date` и `DateTime` тип аргумента. [\#3580](https://github.com/ClickHouse/ClickHouse/pull/3580) -- Исправлена ошибка `WITH` предложение, если оно указывает простой псевдоним без выражений. [\#3570](https://github.com/ClickHouse/ClickHouse/pull/3570) -- Исправлена обработка запросов с именованными подзапросами и квалифицированными именами столбцов, когда `enable_optimize_predicate_expression` это включено. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3588) -- Исправлена ошибка `Attempt to attach to nullptr thread group` при работе с материализованными представлениями. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3623) -- Исправлена ошибка при передаче некоторых неверных аргументов в систему `arrayReverse` функция. [73e3a7b6](https://github.com/ClickHouse/ClickHouse/commit/73e3a7b662161d6005e7727d8a711b930386b871) -- Исправлено переполнение буфера в системе `extractURLParameter` функция. Повышение производительности. Добавлена корректная обработка строк, содержащих ноль байт. [141e9799](https://github.com/ClickHouse/ClickHouse/commit/141e9799e49201d84ea8e951d1bed4fb6d3dacb5) -- Исправлено переполнение буфера в системе `lowerUTF8` и `upperUTF8` функции. Удалена возможность выполнения этих функций сверх `FixedString` аргумент типа. [\#3662](https://github.com/ClickHouse/ClickHouse/pull/3662) -- Исправлено редкое состояние гонки при удалении `MergeTree` таблицы. [\#3680](https://github.com/ClickHouse/ClickHouse/pull/3680) -- Исправлено состояние гонки при чтении с `Buffer` таблицы и одновременно выполнять `ALTER` или `DROP` на целевых столах. [\#3719](https://github.com/ClickHouse/ClickHouse/pull/3719) -- Исправлен сегфолт, если `max_temporary_non_const_columns` лимит был превышен. [\#3788](https://github.com/ClickHouse/ClickHouse/pull/3788) - -#### Улучшения: {#improvements-1} - -- Сервер не записывает обработанные конфигурационные файлы в систему. `/etc/clickhouse-server/` каталог. Вместо этого он спасает их в будущем. `preprocessed_configs` каталог внутри `path`. Это означает, что `/etc/clickhouse-server/` Директория не имеет доступа на запись для `clickhouse` пользователь, что повышает безопасность. [\#2443](https://github.com/ClickHouse/ClickHouse/pull/2443) -- То `min_merge_bytes_to_use_direct_io` по умолчанию параметр установлен на 10 гигабайт. Слияние, которое образует большие части таблиц из семейства MergeTree, будет выполнено в `O_DIRECT` режим, который предотвращает чрезмерное вытеснение кэша страниц. [\#3504](https://github.com/ClickHouse/ClickHouse/pull/3504) -- Ускоренный запуск сервера при наличии очень большого количества таблиц. [\#3398](https://github.com/ClickHouse/ClickHouse/pull/3398) -- Добавлен пул соединений и HTTP `Keep-Alive` для связи между репликами. [\#3594](https://github.com/ClickHouse/ClickHouse/pull/3594) -- Если синтаксис запроса неверен, то `400 Bad Request` код возвращается в виде `HTTP` интерфейс (ранее было возвращено 500). [31bc680a](https://github.com/ClickHouse/ClickHouse/commit/31bc680ac5f4bb1d0360a8ba4696fa84bb47d6ab) -- То `join_default_strictness` параметр установлен в значение `ALL` по умолчанию для обеспечения совместимости. [120e2cbe](https://github.com/ClickHouse/ClickHouse/commit/120e2cbe2ff4fbad626c28042d9b28781c805afe) -- Удалено ведение журнала в `stderr` из `re2` библиотека для недопустимых или сложных регулярных выражений. [\#3723](https://github.com/ClickHouse/ClickHouse/pull/3723) -- Добавлено в `Kafka` механизм таблиц: проверяет наличие подписок перед началом чтения из Kafka; параметр kafka\_max\_block\_size для таблицы. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3396) -- То `cityHash64`, `farmHash64`, `metroHash64`, `sipHash64`, `halfMD5`, `murmurHash2_32`, `murmurHash2_64`, `murmurHash3_32`, и `murmurHash3_64` функции теперь работают для любого количества аргументов и для аргументов в виде кортежей. [\#3451](https://github.com/ClickHouse/ClickHouse/pull/3451) [\#3519](https://github.com/ClickHouse/ClickHouse/pull/3519) -- То `arrayReverse` функция теперь работает с любыми типами массивов. [73e3a7b6](https://github.com/ClickHouse/ClickHouse/commit/73e3a7b662161d6005e7727d8a711b930386b871) -- Добавлен необязательный параметр: размер слота для `timeSlots` функция. [Кирилл Шваков](https://github.com/ClickHouse/ClickHouse/pull/3724) -- Для `FULL` и `RIGHT JOIN`, этот `max_block_size` настройка используется для потока несвязанных данных из правой таблицы. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3699) -- Добавил тот `--secure` параметр командной строки в `clickhouse-benchmark` и `clickhouse-performance-test` чтобы включить TLS. [\#3688](https://github.com/ClickHouse/ClickHouse/pull/3688) [\#3690](https://github.com/ClickHouse/ClickHouse/pull/3690) -- Тип преобразования, когда структура a `Buffer` таблица типов не соответствует структуре целевой таблицы. [Виталий Баранов](https://github.com/ClickHouse/ClickHouse/pull/3603) -- Добавил тот `tcp_keep_alive_timeout` опция для включения пакетов keep-alive после бездействия в течение заданного интервала времени. [\#3441](https://github.com/ClickHouse/ClickHouse/pull/3441) -- Удалены ненужные кавычки значений для ключа раздела В разделе `system.parts` таблица, если она состоит из одного столбца. [\#3652](https://github.com/ClickHouse/ClickHouse/pull/3652) -- Функция по модулю работает для `Date` и `DateTime` тип данных. [\#3385](https://github.com/ClickHouse/ClickHouse/pull/3385) -- Добавлены синонимы для этого `POWER`, `LN`, `LCASE`, `UCASE`, `REPLACE`, `LOCATE`, `SUBSTR`, и `MID` функции. [\#3774](https://github.com/ClickHouse/ClickHouse/pull/3774) [\#3763](https://github.com/ClickHouse/ClickHouse/pull/3763) Некоторые имена функций не зависят от регистра для обеспечения совместимости со стандартом SQL. Добавлен синтаксический сахар `SUBSTRING(expr FROM start FOR length)` для совместимости с SQL. [\#3804](https://github.com/ClickHouse/ClickHouse/pull/3804) -- Добавлена возможность `mlock` страницы памяти, соответствующие `clickhouse-server` исполняемый код, чтобы предотвратить его вытеснение из памяти. По умолчанию эта функция отключена. [\#3553](https://github.com/ClickHouse/ClickHouse/pull/3553) -- Улучшенная производительность при чтении с `O_DIRECT` (с помощью `min_bytes_to_use_direct_io` опция включена). [\#3405](https://github.com/ClickHouse/ClickHouse/pull/3405) -- Улучшенная производительность системы `dictGet...OrDefault` функция для постоянного ключевого аргумента и непостоянного аргумента по умолчанию. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3563) -- То `firstSignificantSubdomain` функция теперь обрабатывает Домены `gov`, `mil`, и `edu`. [Игорь Hatarist](https://github.com/ClickHouse/ClickHouse/pull/3601) Повышение производительности. [\#3628](https://github.com/ClickHouse/ClickHouse/pull/3628) -- Возможность указать пользовательские переменные среды для запуска `clickhouse-server` с помощью `SYS-V init.d` сценарий по определению `CLICKHOUSE_PROGRAM_ENV` в `/etc/default/clickhouse`. - [Павел Башинский](https://github.com/ClickHouse/ClickHouse/pull/3612) -- Правильный код возврата для сценария clickhouse-server init. [\#3516](https://github.com/ClickHouse/ClickHouse/pull/3516) -- То `system.metrics` таблица теперь имеет `VersionInteger` метрика и `system.build_options` есть ли добавленная строка `VERSION_INTEGER`, который содержит числовую форму версии ClickHouse, например `18016000`. [\#3644](https://github.com/ClickHouse/ClickHouse/pull/3644) -- Удалена возможность сравнения `Date` введите с номером, чтобы избежать потенциальных ошибок, таких как `date = 2018-12-17`, где кавычки вокруг даты опущены по ошибке. [\#3687](https://github.com/ClickHouse/ClickHouse/pull/3687) -- Исправлено поведение статусных функций, таких как `rowNumberInAllBlocks`. Ранее они выводили результат, который был на одно число больше из-за запуска во время анализа запроса. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3729) -- Если `force_restore_data` файл не может быть удален, отображается сообщение об ошибке. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3794) - -#### Улучшения сборки: {#build-improvements-1} - -- Обновлено приложение `jemalloc` библиотека, которая исправляет потенциальную утечку памяти. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3557) -- Профилирование с помощью `jemalloc` включен по умолчанию для отладки сборок. [2cc82f5c](https://github.com/ClickHouse/ClickHouse/commit/2cc82f5cbe266421cd4c1165286c2c47e5ffcb15) -- Добавлена возможность запуска интеграционных тестов только тогда, когда `Docker` устанавливается в системе. [\#3650](https://github.com/ClickHouse/ClickHouse/pull/3650) -- Добавлен тест выражения fuzz в запросах SELECT. [\#3442](https://github.com/ClickHouse/ClickHouse/pull/3442) -- Добавлен стресс-тест для коммитов, который выполняет функциональные тесты параллельно и в случайном порядке, чтобы обнаружить больше условий гонки. [\#3438](https://github.com/ClickHouse/ClickHouse/pull/3438) -- Улучшен метод запуска clickhouse-сервера в образе Docker. [Эльгазал Ахмед](https://github.com/ClickHouse/ClickHouse/pull/3663) -- Для Docker образ, добавлена поддержка для инициализации базы данных с помощью файлов в `/docker-entrypoint-initdb.d` каталог. [Константин Лебедев](https://github.com/ClickHouse/ClickHouse/pull/3695) -- Исправления опирается на руку. [\#3709](https://github.com/ClickHouse/ClickHouse/pull/3709) - -#### Назад несовместимые изменения: {#backward-incompatible-changes} - -- Удалена возможность сравнения `Date` тип с номером. Вместо `toDate('2018-12-18') = 17883`, вы должны использовать явное преобразование типов `= toDate(17883)` [\#3687](https://github.com/ClickHouse/ClickHouse/pull/3687) - -## ClickHouse релиз 18.14 {#clickhouse-release-18-14} - -### ClickHouse релиз 18.14.19, 2018-12-19 {#clickhouse-release-18-14-19-2018-12-19} - -#### Устранение ошибок: {#bug-fixes-2} - -- Исправлена ошибка, которая привела к проблемам с обновлением словарей с источником ODBC. [\#3825](https://github.com/ClickHouse/ClickHouse/issues/3825), [\#3829](https://github.com/ClickHouse/ClickHouse/issues/3829) -- Базы данных правильно задаются при выполнении DDL `ON CLUSTER` запросы. [\#3460](https://github.com/ClickHouse/ClickHouse/pull/3460) -- Исправлен сегфолт, если `max_temporary_non_const_columns` лимит был превышен. [\#3788](https://github.com/ClickHouse/ClickHouse/pull/3788) - -#### Улучшения сборки: {#build-improvements-2} - -- Исправления опирается на руку. - -### ClickHouse релиз 18.14.18, 2018-12-04 {#clickhouse-release-18-14-18-2018-12-04} - -#### Устранение ошибок: {#bug-fixes-3} - -- Исправлена ошибка в работе `dictGet...` функция для словарей типа `range`, если один из аргументов является постоянным, а другой-нет. [\#3751](https://github.com/ClickHouse/ClickHouse/pull/3751) -- Исправлена ошибка, приводившая к появлению сообщений `netlink: '...': attribute type 1 has an invalid length` чтобы быть напечатанным в журнале ядра Linux, это происходило только на достаточно свежих версиях ядра Linux. [\#3749](https://github.com/ClickHouse/ClickHouse/pull/3749) -- Исправлена обработка выхода онлайн / оффлайн в функции `empty` для аргументации из `FixedString` тип. [Дэниел, Дао Куанг Мин](https://github.com/ClickHouse/ClickHouse/pull/3703) -- Исправлено чрезмерное выделение памяти при использовании большого значения `max_query_size` настройка (фрагмент памяти из `max_query_size` байты были предварительно распределены сразу). [\#3720](https://github.com/ClickHouse/ClickHouse/pull/3720) - -#### Изменения в сборке: {#build-changes} - -- Исправлена сборка с библиотеками LLVM/Clang версии 7 из пакетов ОС (эти библиотеки используются для компиляции запросов во время выполнения). [\#3582](https://github.com/ClickHouse/ClickHouse/pull/3582) - -### ClickHouse релиз 18.14.17, 2018-11-30 {#clickhouse-release-18-14-17-2018-11-30} - -#### Устранение ошибок: {#bug-fixes-4} - -- Исправлены случаи, когда процесс моста ODBC не завершался с основным серверным процессом. [\#3642](https://github.com/ClickHouse/ClickHouse/pull/3642) -- Исправлено одновременное включение в `Distributed` таблица со списком столбцов, который отличается от списка столбцов удаленной таблицы. [\#3673](https://github.com/ClickHouse/ClickHouse/pull/3673) -- Исправлено редкое состояние гонки, которое может привести к аварии при падении таблицы MergeTree. [\#3643](https://github.com/ClickHouse/ClickHouse/pull/3643) -- Исправлена взаимоблокировка запросов в случае сбоя при создании потока запросов с помощью `Resource temporarily unavailable` ошибка. [\#3643](https://github.com/ClickHouse/ClickHouse/pull/3643) -- Исправлен разбор текста `ENGINE` п. Когда `CREATE AS table` был использован синтаксис, а также `ENGINE` оговорка была указана еще до того, как `AS table` (ошибка привела к игнорированию указанного движка). [\#3692](https://github.com/ClickHouse/ClickHouse/pull/3692) - -### ClickHouse релиз 18.14.15, 2018-11-21 {#clickhouse-release-18-14-15-2018-11-21} - -#### Устранение ошибок: {#bug-fixes-5} - -- Размер блока памяти был завышен при десериализации столбца типа `Array(String)` это приводит к тому, что «Memory limit exceeded» ошибки. Проблема появилась в версии 18.12.13. [\#3589](https://github.com/ClickHouse/ClickHouse/issues/3589) - -### ClickHouse релиз 18.14.14, 2018-11-20 {#clickhouse-release-18-14-14-2018-11-20} - -#### Устранение ошибок: {#bug-fixes-6} - -- Исправлено `ON CLUSTER` запросы, когда кластер настроен как безопасный (флаг ``). [\#3599](https://github.com/ClickHouse/ClickHouse/pull/3599) - -#### Изменения в сборке: {#build-changes-1} - -- Исправлены неполадки (llvm-7 от system, macos) [\#3582](https://github.com/ClickHouse/ClickHouse/pull/3582) - -### ClickHouse релиз 18.14.13, 2018-11-08 {#clickhouse-release-18-14-13-2018-11-08} - -#### Устранение ошибок: {#bug-fixes-7} - -- Исправлена ошибка `Block structure mismatch in MergingSorted stream` ошибка. [\#3162](https://github.com/ClickHouse/ClickHouse/issues/3162) -- Исправлено `ON CLUSTER` запросы в случае, если в конфигурации кластера были включены защищенные соединения (the `` флаг). [\#3465](https://github.com/ClickHouse/ClickHouse/pull/3465) -- Исправлена ошибка в запросах, которые использовались `SAMPLE`, `PREWHERE` и столбцы псевдонимов. [\#3543](https://github.com/ClickHouse/ClickHouse/pull/3543) -- Исправлена редкая ошибка `unknown compression method` ошибка, когда `min_bytes_to_use_direct_io` настройка была включена. [3544](https://github.com/ClickHouse/ClickHouse/pull/3544) - -#### Улучшения в производительности: {#performance-improvements} - -- Исправлена регрессия производительности запросов с помощью `GROUP BY` столбцов типа UInt16 или Date при выполнении на процессорах AMD EPYC. [Игорь Лапко](https://github.com/ClickHouse/ClickHouse/pull/3512) -- Исправлена регрессия производительности запросов, обрабатывающих длинные строки. [\#3530](https://github.com/ClickHouse/ClickHouse/pull/3530) - -#### Улучшения сборки: {#build-improvements-3} - -- Улучшения для упрощения сборки Arcadia. [\#3475](https://github.com/ClickHouse/ClickHouse/pull/3475), [\#3535](https://github.com/ClickHouse/ClickHouse/pull/3535) - -### ClickHouse релиз 18.14.12, 2018-11-02 {#clickhouse-release-18-14-12-2018-11-02} - -#### Устранение ошибок: {#bug-fixes-8} - -- Исправлена ошибка при соединении двух безымянных подзапросов. [\#3505](https://github.com/ClickHouse/ClickHouse/pull/3505) -- Исправлена генерация некорректных запросов (с пустым именем `WHERE` пункт 2) при запросе внешних баз данных. [хотид](https://github.com/ClickHouse/ClickHouse/pull/3477) -- Исправлено использование неверного значения таймаута в словарях ODBC. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3511) - -### ClickHouse релиз 18.14.11, 2018-10-29 {#clickhouse-release-18-14-11-2018-10-29} - -#### Устранение ошибок: {#bug-fixes-9} - -- Исправлена ошибка `Block structure mismatch in UNION stream: different number of columns` в предельных запросах. [\#2156](https://github.com/ClickHouse/ClickHouse/issues/2156) -- Исправлены ошибки при объединении данных в таблицах, содержащих массивы внутри вложенных структур. [\#3397](https://github.com/ClickHouse/ClickHouse/pull/3397) -- Исправлены неправильные результаты запроса, если `merge_tree_uniform_read_distribution` настройка отключена (по умолчанию она включена). [\#3429](https://github.com/ClickHouse/ClickHouse/pull/3429) -- Исправлена ошибка при вставках в распределенную таблицу в собственном формате. [\#3411](https://github.com/ClickHouse/ClickHouse/issues/3411) - -### ClickHouse релиз 18.14.10, 2018-10-23 {#clickhouse-release-18-14-10-2018-10-23} - -- То `compile_expressions` настройка (JIT-компиляция выражений) по умолчанию отключена. [\#3410](https://github.com/ClickHouse/ClickHouse/pull/3410) -- То `enable_optimize_predicate_expression` по умолчанию этот параметр отключен. - -### ClickHouse релиз 18.14.9, 2018-10-16 {#clickhouse-release-18-14-9-2018-10-16} - -#### Новые средства: {#new-features-1} - -- То `WITH CUBE` модификатор для `GROUP BY` (альтернативный синтаксис `GROUP BY CUBE(...)` также доступный). [\#3172](https://github.com/ClickHouse/ClickHouse/pull/3172) -- Добавил тот `formatDateTime` функция. [Александр Крашенинников](https://github.com/ClickHouse/ClickHouse/pull/2770) -- Добавил тот `JDBC` двигатель таблицы и `jdbc` табличная функция (требуется установка clickhouse-jdbc-bridge). [Александр Крашенинников](https://github.com/ClickHouse/ClickHouse/pull/3210) -- Добавлены функции для работы с номером недели ISO: `toISOWeek`, `toISOYear`, `toStartOfISOYear`, и `toDayOfYear`. [\#3146](https://github.com/ClickHouse/ClickHouse/pull/3146) -- Теперь вы можете использовать `Nullable` колонки для `MySQL` и `ODBC` таблицы. [\#3362](https://github.com/ClickHouse/ClickHouse/pull/3362) -- Вложенные структуры данных могут быть прочитаны как вложенные объекты в `JSONEachRow` формат. Добавил тот `input_format_import_nested_json` установка. [Веломан Юнкан](https://github.com/ClickHouse/ClickHouse/pull/3144) -- Параллельная обработка доступна для многих `MATERIALIZED VIEW`s при вставке данных. Смотрите сами `parallel_view_processing` установка. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3208) -- Добавил тот `SYSTEM FLUSH LOGS` запрос (принудительный сброс журнала в системные таблицы, такие как `query_log`) [\#3321](https://github.com/ClickHouse/ClickHouse/pull/3321) -- Теперь вы можете использовать заранее определенные `database` и `table` макросы при объявлении `Replicated` таблицы. [\#3251](https://github.com/ClickHouse/ClickHouse/pull/3251) -- Добавлена возможность чтения `Decimal` введите значения в инженерной нотации (с указанием степеней десять). [\#3153](https://github.com/ClickHouse/ClickHouse/pull/3153) - -#### Экспериментальная возможность: {#experimental-features} - -- Оптимизация группы по предложению для `LowCardinality data types.` [\#3138](https://github.com/ClickHouse/ClickHouse/pull/3138) -- Оптимизированный расчет выражений для `LowCardinality data types.` [\#3200](https://github.com/ClickHouse/ClickHouse/pull/3200) - -#### Улучшения: {#improvements-2} - -- Значительно уменьшено потребление памяти для запросов с помощью `ORDER BY` и `LIMIT`. Смотрите сами `max_bytes_before_remerge_sort` установка. [\#3205](https://github.com/ClickHouse/ClickHouse/pull/3205) -- В случае отсутствия `JOIN` (`LEFT`, `INNER`, …), `INNER JOIN` предполагается. [\#3147](https://github.com/ClickHouse/ClickHouse/pull/3147) -- Квалифицированные звездочки корректно работают в запросах с `JOIN`. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3202) -- То `ODBC` механизм таблиц правильно выбирает метод для цитирования идентификаторов на диалекте SQL удаленной базы данных. [Александр Крашенинников](https://github.com/ClickHouse/ClickHouse/pull/3210) -- То `compile_expressions` настройка (JIT-компиляция выражений) включена по умолчанию. -- Исправлено поведение для одновременного удаления базы данных / таблицы, если она существует, и создания базы данных/таблицы, если она не существует. Ранее, а `CREATE DATABASE ... IF NOT EXISTS` запрос может вернуть сообщение об ошибке «File … already exists», и то `CREATE TABLE ... IF NOT EXISTS` и `DROP TABLE IF EXISTS` запросы могут вернуться `Table ... is creating or attaching right now`. [\#3101](https://github.com/ClickHouse/ClickHouse/pull/3101) -- Как и в выражениях с постоянной правой половиной, они передаются на удаленный сервер при запросе из таблиц MySQL или ODBC. [\#3182](https://github.com/ClickHouse/ClickHouse/pull/3182) -- Сравнения с постоянными выражениями в предложении WHERE передаются удаленному серверу при запросе из таблиц MySQL и ODBC. Раньше проходили только сравнения с константами. [\#3182](https://github.com/ClickHouse/ClickHouse/pull/3182) -- Правильный расчет ширины строки в терминале для `Pretty` форматы, в том числе строки с иероглифами. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/3257). -- `ON CLUSTER` может быть указан для `ALTER UPDATE` запросы. -- Улучшенная производительность для считывания данных в `JSONEachRow` формат. [\#3332](https://github.com/ClickHouse/ClickHouse/pull/3332) -- Добавлены синонимы для этого `LENGTH` и `CHARACTER_LENGTH` функции для обеспечения совместимости. То `CONCAT` функция больше не зависит от регистра. [\#3306](https://github.com/ClickHouse/ClickHouse/pull/3306) -- Добавил тот `TIMESTAMP` синоним для этого `DateTime` тип. [\#3390](https://github.com/ClickHouse/ClickHouse/pull/3390) -- В журналах сервера всегда есть место, зарезервированное для query\_id, даже если строка журнала не связана с запросом. Это упрощает синтаксический анализ текстовых журналов сервера с помощью сторонних инструментов. -- Потребление памяти запросом регистрируется, когда оно превышает следующий уровень целого числа гигабайт. [\#3205](https://github.com/ClickHouse/ClickHouse/pull/3205) -- Добавлен режим совместимости для случая, когда клиентская библиотека, использующая собственный протокол, по ошибке отправляет меньше столбцов, чем сервер ожидает для запроса INSERT. Этот сценарий был возможен при использовании библиотеки clickhouse-cpp. Ранее этот сценарий приводил к сбою сервера. [\#3171](https://github.com/ClickHouse/ClickHouse/pull/3171) -- В пользовательском выражении WHERE in `clickhouse-copier`, теперь вы можете использовать a `partition_key` псевдоним (для дополнительной фильтрации по исходному разделу таблицы). Это полезно, если схема секционирования изменяется во время копирования,но только незначительно. [\#3166](https://github.com/ClickHouse/ClickHouse/pull/3166) -- Рабочий процесс компании `Kafka` движок был перемещен в фоновый пул потоков, чтобы автоматически снизить скорость считывания данных при высоких нагрузках. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3215). -- Поддержка чтения `Tuple` и `Nested` значения таких структур, как `struct` в `Cap'n'Proto format`. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3216) -- Список доменов верхнего уровня для `firstSignificantSubdomain` функция теперь включает в себя домен `biz`. [деказеал](https://github.com/ClickHouse/ClickHouse/pull/3219) -- В конфигурации внешних справочников, `null_value` интерпретируется как значение типа данных по умолчанию. [\#3330](https://github.com/ClickHouse/ClickHouse/pull/3330) -- Поддержка для the `intDiv` и `intDivOrZero` функции для `Decimal`. [b48402e8](https://github.com/ClickHouse/ClickHouse/commit/b48402e8712e2b9b151e0eef8193811d433a1264) -- Поддержка для the `Date`, `DateTime`, `UUID`, и `Decimal` типы в качестве ключа для `sumMap` статистическая функция. [\#3281](https://github.com/ClickHouse/ClickHouse/pull/3281) -- Поддержка для the `Decimal` тип данных во внешних справочниках. [\#3324](https://github.com/ClickHouse/ClickHouse/pull/3324) -- Поддержка для the `Decimal` введите данные в поле `SummingMergeTree` таблицы. [\#3348](https://github.com/ClickHouse/ClickHouse/pull/3348) -- Добавлены специализации для `UUID` в `if`. [\#3366](https://github.com/ClickHouse/ClickHouse/pull/3366) -- Уменьшилось количество `open` и `close` системные вызовы для чтения `MergeTree table`. [\#3283](https://github.com/ClickHouse/ClickHouse/pull/3283) -- A `TRUNCATE TABLE` запрос может быть выполнен на любой реплике (запрос передается в реплику лидера). [Кирилл Шваков](https://github.com/ClickHouse/ClickHouse/pull/3375) - -#### Устранение ошибок: {#bug-fixes-10} - -- Исправлена проблема с `Dictionary` таблицы для `range_hashed` словари. Эта ошибка произошла в версии 18.12.17. [\#1702](https://github.com/ClickHouse/ClickHouse/pull/1702) -- Исправлена ошибка при загрузке `range_hashed` словари (сообщение `Unsupported type Nullable (...)`). Эта ошибка произошла в версии 18.12.17. [\#3362](https://github.com/ClickHouse/ClickHouse/pull/3362) -- Исправлены ошибки в работе `pointInPolygon` функция обусловлена накоплением неточных вычислений для полигонов с большим количеством вершин, расположенных близко друг к другу. [\#3331](https://github.com/ClickHouse/ClickHouse/pull/3331) [\#3341](https://github.com/ClickHouse/ClickHouse/pull/3341) -- Если после слияния частей данных контрольная сумма для результирующей части отличается от результата того же слияния в другой реплике, то результат слияния удаляется и часть данных загружается из другой реплики (это правильное поведение). Но после загрузки части данных она не могла быть добавлена в рабочий набор из-за ошибки, что часть уже существует (потому что часть данных была удалена с некоторой задержкой после слияния). Это привело к циклическим попыткам загрузить одни и те же данные. [\#3194](https://github.com/ClickHouse/ClickHouse/pull/3194) -- Исправлено неправильное вычисление общего потребления памяти запросами (из-за неправильного вычисления `max_memory_usage_for_all_queries` установка сработала неправильно и то `MemoryTracking` метрика имела неверное значение). Эта ошибка произошла в версии 18.12.13. [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3344) -- Исправлена функциональность программы `CREATE TABLE ... ON CLUSTER ... AS SELECT ...` Эта ошибка произошла в версии 18.12.13. [\#3247](https://github.com/ClickHouse/ClickHouse/pull/3247) -- Исправлена ненужная подготовка структур данных для `JOIN`s на сервере, который инициирует запрос, если `JOIN` выполняется только на удаленных серверах. [\#3340](https://github.com/ClickHouse/ClickHouse/pull/3340) -- Исправлены ошибки в работе `Kafka` движок: взаимоблокировки после исключений при запуске чтения данных и блокировки по завершении работы [Marek Vavruša](https://github.com/ClickHouse/ClickHouse/pull/3215). -- Для `Kafka` таблицы, опциональные `schema` параметр не был передан (схема `Cap'n'Proto` формат). [Войтех Splichal](https://github.com/ClickHouse/ClickHouse/pull/3150) -- Если в ансамбле серверов ZooKeeper есть серверы, которые принимают соединение, но затем немедленно закрывают его вместо ответа на рукопожатие, ClickHouse выбирает для подключения другой сервер. Ранее это приводило к ошибке `Cannot read all data. Bytes read: 0. Bytes expected: 4.` и сервер не мог запуститься. [8218cf3a](https://github.com/ClickHouse/ClickHouse/commit/8218cf3a5f39a43401953769d6d12a0bb8d29da9) -- Если ансамбль серверов ZooKeeper содержит серверы, для которых DNS-запрос возвращает ошибку, эти серверы игнорируются. [17b8e209](https://github.com/ClickHouse/ClickHouse/commit/17b8e209221061325ad7ba0539f03c6e65f87f29) -- Фиксированное преобразование типа между `Date` и `DateTime` при вставке данных в `VALUES` формат (если `input_format_values_interpret_expressions = 1`). Ранее преобразование производилось между числовым значением числа дней в Unix Epoch time и unix timestamp, что приводило к неожиданным результатам. [\#3229](https://github.com/ClickHouse/ClickHouse/pull/3229) -- Исправлено преобразование типов между `Decimal` и целые числа. [\#3211](https://github.com/ClickHouse/ClickHouse/pull/3211) -- Исправлены ошибки в работе `enable_optimize_predicate_expression` установка. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3231) -- Исправлена ошибка синтаксического анализа в формате CSV с числами с плавающей запятой, если используется нестандартный разделитель CSV, например `;` [\#3155](https://github.com/ClickHouse/ClickHouse/pull/3155) -- Исправлена ошибка `arrayCumSumNonNegative` функция (она не накапливает отрицательных значений, если накопитель меньше нуля). [Алексей Студнев](https://github.com/ClickHouse/ClickHouse/pull/3163) -- Исправлено как `Merge` таблицы работают на верхней части `Distributed` таблицы при использовании `PREWHERE`. [\#3165](https://github.com/ClickHouse/ClickHouse/pull/3165) -- Исправлены ошибки в системе `ALTER UPDATE` запрос. -- Исправлены ошибки в работе `odbc` табличная функция, появившаяся в версии 18.12. [\#3197](https://github.com/ClickHouse/ClickHouse/pull/3197) -- Исправлена работа агрегатных функций с помощью `StateArray` комбинаторы. [\#3188](https://github.com/ClickHouse/ClickHouse/pull/3188) -- Исправлена ошибка при делении `Decimal` значение по нулю. [69dd6609](https://github.com/ClickHouse/ClickHouse/commit/69dd6609193beb4e7acd3e6ad216eca0ccfb8179) -- Фиксированный вывод типов для использования операций `Decimal` и целочисленные аргументы. [\#3224](https://github.com/ClickHouse/ClickHouse/pull/3224) -- Исправлена обработка выхода онлайн / оффлайн в `GROUP BY` на `Decimal128`. [3359ba06](https://github.com/ClickHouse/ClickHouse/commit/3359ba06c39fcd05bfdb87d6c64154819621e13a) -- То `log_query_threads` настройка (протоколирование информации о каждом потоке выполнения запроса) теперь вступает в силу только в том случае, если `log_queries` параметр (протоколирование информации о запросах) имеет значение 1. Поскольку `log_query_threads` опция включена по умолчанию, информация о потоках ранее регистрировалась, даже если ведение журнала запросов было отключено. [\#3241](https://github.com/ClickHouse/ClickHouse/pull/3241) -- Исправлена ошибка в распределенной работе агрегатной функции квантилей (сообщение об ошибке `Not found column quantile...`). [292a8855](https://github.com/ClickHouse/ClickHouse/commit/292a885533b8e3b41ce8993867069d14cbd5a664) -- Исправлена проблема совместимости при работе с кластером серверов версии 18.12.17 и более старых серверов одновременно. Для распределенных запросов с ключами GROUP BY как фиксированной, так и не фиксированной длины при наличии большого объема данных для агрегирования возвращаемые данные не всегда были полностью агрегированы (две разные строки содержали одни и те же ключи агрегирования). [\#3254](https://github.com/ClickHouse/ClickHouse/pull/3254) -- Исправлена обработка подстановок в `clickhouse-performance-test`, если запрос содержит только часть подстановок, объявленных в тесте. [\#3263](https://github.com/ClickHouse/ClickHouse/pull/3263) -- Исправлена ошибка при использовании `FINAL` с `PREWHERE`. [\#3298](https://github.com/ClickHouse/ClickHouse/pull/3298) -- Исправлена ошибка при использовании `PREWHERE` над столбцами, которые были добавлены во время `ALTER`. [\#3298](https://github.com/ClickHouse/ClickHouse/pull/3298) -- Добавлена проверка на отсутствие `arrayJoin` для `DEFAULT` и `MATERIALIZED` выражения. Ранее, `arrayJoin` это привело к ошибке при вставке данных. [\#3337](https://github.com/ClickHouse/ClickHouse/pull/3337) -- Добавлена проверка на отсутствие `arrayJoin` в `PREWHERE` пункт. Ранее это приводило к таким сообщениям, как `Size ... doesn't match` или `Unknown compression method` при выполнении запросов. [\#3357](https://github.com/ClickHouse/ClickHouse/pull/3357) -- Исправлена ошибка segfault, которая могла возникнуть в редких случаях после оптимизации, которая заменила и цепочки из оценок равенства с соответствующим выражением IN. [люимин-бытданс](https://github.com/ClickHouse/ClickHouse/pull/3339) -- Незначительные исправления к `clickhouse-benchmark`: раньше информация о клиенте не отправлялась на сервер, теперь количество выполненных запросов вычисляется более точно при выключении и ограничении количества итераций. [\#3351](https://github.com/ClickHouse/ClickHouse/pull/3351) [\#3352](https://github.com/ClickHouse/ClickHouse/pull/3352) - -#### Назад несовместимые изменения: {#backward-incompatible-changes-1} - -- Удалил то `allow_experimental_decimal_type` вариант. То `Decimal` тип данных доступен для использования по умолчанию. [\#3329](https://github.com/ClickHouse/ClickHouse/pull/3329) - -## ClickHouse релиз 18.12 {#clickhouse-release-18-12} - -### ClickHouse релиз 18.12.17, 2018-09-16 {#clickhouse-release-18-12-17-2018-09-16} - -#### Новые средства: {#new-features-2} - -- `invalidate_query` (возможность задать запрос для проверки необходимости обновления внешнего словаря) реализована для `clickhouse` источник. [\#3126](https://github.com/ClickHouse/ClickHouse/pull/3126) -- Добавлена возможность использования `UInt*`, `Int*`, и `DateTime` типы данных (вместе с `Date` типа) как `range_hashed` внешний ключ словаря, определяющий границы диапазонов. Сейчас `NULL` может использоваться для обозначения открытого диапазона. [Василий Немков](https://github.com/ClickHouse/ClickHouse/pull/3123) -- То `Decimal` тип теперь поддерживает `var*` и `stddev*` статистическая функция. [\#3129](https://github.com/ClickHouse/ClickHouse/pull/3129) -- То `Decimal` тип теперь поддерживает математические функции (`exp`, `sin` и так далее.) [\#3129](https://github.com/ClickHouse/ClickHouse/pull/3129) -- То `system.part_log` таблица теперь имеет `partition_id` колонка. [\#3089](https://github.com/ClickHouse/ClickHouse/pull/3089) - -#### Устранение ошибок: {#bug-fixes-11} - -- `Merge` теперь работает правильно на `Distributed` таблицы. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3159) -- Исправлена несовместимость (ненужная зависимость от `glibc` версия), что сделало невозможным запуск ClickHouse на `Ubuntu Precise` и более старые версии. Несовместимость возникла в версии 18.12.13. [\#3130](https://github.com/ClickHouse/ClickHouse/pull/3130) -- Исправлены ошибки в работе `enable_optimize_predicate_expression` установка. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3107) -- Исправлена незначительная проблема с обратной совместимостью, возникшая при работе с кластером реплик на версиях ранее 18.12.13 и одновременном создании новой реплики таблицы на сервере с более новой версией (показано в сообщении `Can not clone replica, because the ... updated to new ClickHouse version`, что вполне логично, но не должно произойти). [\#3122](https://github.com/ClickHouse/ClickHouse/pull/3122) - -#### Назад несовместимые изменения: {#backward-incompatible-changes-2} - -- То `enable_optimize_predicate_expression` опция включена по умолчанию (что довольно оптимистично). Если возникают ошибки анализа запросов, связанные с поиском имен столбцов, установите `enable_optimize_predicate_expression` до 0. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3107) - -### ClickHouse релиз 18.12.14, 2018-09-13 {#clickhouse-release-18-12-14-2018-09-13} - -#### Новые средства: {#new-features-3} - -- Добавлена поддержка для `ALTER UPDATE` запросы. [\#3035](https://github.com/ClickHouse/ClickHouse/pull/3035) -- Добавил тот `allow_ddl` опция, которая ограничивает доступ пользователя к DDL-запросам. [\#3104](https://github.com/ClickHouse/ClickHouse/pull/3104) -- Добавил тот `min_merge_bytes_to_use_direct_io` вариант для `MergeTree` движки, которые позволяют установить пороговое значение для общего размера слияния (при превышении порогового значения файлы частей данных будут обрабатываться с помощью O\_DIRECT). [\#3117](https://github.com/ClickHouse/ClickHouse/pull/3117) -- То `system.merges` системная таблица теперь содержит `partition_id` колонка. [\#3099](https://github.com/ClickHouse/ClickHouse/pull/3099) - -#### Улучшения {#improvements-3} - -- Если часть данных остается неизменной во время мутации, она не загружается репликами. [\#3103](https://github.com/ClickHouse/ClickHouse/pull/3103) -- Автозаполнение доступно для имен настроек при работе с ними `clickhouse-client`. [\#3106](https://github.com/ClickHouse/ClickHouse/pull/3106) - -#### Устранение ошибок: {#bug-fixes-12} - -- Добавлена проверка размеров массивов, являющихся элементами `Nested` введите поля при вставке. [\#3118](https://github.com/ClickHouse/ClickHouse/pull/3118) -- Исправлена ошибка обновления внешних словарей с помощью `ODBC` источник и `hashed` место хранения. Эта ошибка произошла в версии 18.12.13. -- Исправлена ошибка при создании временной таблицы из запроса с помощью `IN` состояние. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3098) -- Исправлена ошибка в агрегатных функциях для массивов, которые могут иметь `NULL` элементы. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/3097) - -### ClickHouse релиз 18.12.13, 2018-09-10 {#clickhouse-release-18-12-13-2018-09-10} - -#### Новые средства: {#new-features-4} - -- Добавил тот `DECIMAL(digits, scale)` тип данных (`Decimal32(scale)`, `Decimal64(scale)`, `Decimal128(scale)`). Чтобы включить его, используйте параметр `allow_experimental_decimal_type`. [\#2846](https://github.com/ClickHouse/ClickHouse/pull/2846) [\#2970](https://github.com/ClickHouse/ClickHouse/pull/2970) [\#3008](https://github.com/ClickHouse/ClickHouse/pull/3008) [\#3047](https://github.com/ClickHouse/ClickHouse/pull/3047) -- Новый `WITH ROLLUP` модификатор для `GROUP BY` (альтернативный синтаксис: `GROUP BY ROLLUP(...)`). [\#2948](https://github.com/ClickHouse/ClickHouse/pull/2948) -- В запросах с соединением символ звезды расширяется до списка столбцов во всех таблицах в соответствии со стандартом SQL. Вы можете восстановить старое поведение, установив `asterisk_left_columns_only` до 1 на уровне конфигурации пользователя. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2787) -- Добавлена поддержка соединения с табличными функциями. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2907) -- Автозаполнение осуществляется нажатием клавиши Tab в clickhouse-клиенте. [Сергей Щербин](https://github.com/ClickHouse/ClickHouse/pull/2447) -- Сочетание клавиш CTRL+C в clickhouse-клиент сбрасывает запрос, который был введен. [\#2877](https://github.com/ClickHouse/ClickHouse/pull/2877) -- Добавил тот `join_default_strictness` уставка: `"`, `'any'`, `'all'`). Это позволяет вам не указывать `ANY` или `ALL` для `JOIN`. [\#2982](https://github.com/ClickHouse/ClickHouse/pull/2982) -- Каждая строка журнала сервера, связанная с обработкой запросов, показывает идентификатор запроса. [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- Теперь вы можете получить журналы выполнения запросов в clickhouse-клиенте (используйте `send_logs_level` установочный). При распределенной обработке запросов журналы каскадируются со всех серверов. [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- То `system.query_log` и `system.processes` (`SHOW PROCESSLIST`) таблицы теперь содержат информацию обо всех измененных настройках при выполнении запроса (вложенная структура запроса). `Settings` данные). Добавил тот `log_query_settings` установка. [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- То `system.query_log` и `system.processes` теперь в таблицах отображается информация о количестве потоков, участвующих в выполнении запроса (см. `thread_numbers` колонка). [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- Добавлен `ProfileEvents` счетчики, которые измеряют время, затраченное на чтение и запись по сети и чтение и запись на диск, количество сетевых ошибок и время ожидания, когда пропускная способность сети ограничена. [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- Добавлен `ProfileEvents`счетчики, содержащие системные метрики из rusage (их можно использовать для получения информации об использовании ЦП в пользовательском пространстве и ядре, сбоях страниц и переключателях контекста), а также метрики taskstats (используйте их для получения информации о времени ожидания ввода-вывода, времени ожидания ЦП и объеме данных, считываемых и записываемых как с помощью кэша страниц, так и без него). [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- То `ProfileEvents` счетчики применяются глобально и для каждого запроса, а также для каждого потока выполнения запроса, что позволяет детально профилировать потребление ресурсов запросом. [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- Добавил тот `system.query_thread_log` таблица, содержащая информацию о каждом потоке выполнения запроса. Добавил тот `log_query_threads` установка. [\#2482](https://github.com/ClickHouse/ClickHouse/pull/2482) -- То `system.metrics` и `system.events` таблицы теперь имеют встроенную документацию. [\#3016](https://github.com/ClickHouse/ClickHouse/pull/3016) -- Добавил тот `arrayEnumerateDense` функция. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2975) -- Добавил тот `arrayCumSumNonNegative` и `arrayDifference` функции. [Алексей Студнев](https://github.com/ClickHouse/ClickHouse/pull/2942) -- Добавил тот `retention` статистическая функция. [Вашим Ли](https://github.com/ClickHouse/ClickHouse/pull/2887) -- Теперь вы можете добавить (объединить) состояния агрегатных функций с помощью оператора плюс и умножить состояния агрегатных функций на неотрицательную константу. [\#3062](https://github.com/ClickHouse/ClickHouse/pull/3062) [\#3034](https://github.com/ClickHouse/ClickHouse/pull/3034) -- Таблицы в семействе MergeTree теперь имеют виртуальный столбец `_partition_id`. [\#3089](https://github.com/ClickHouse/ClickHouse/pull/3089) - -#### Экспериментальная возможность: {#experimental-features-1} - -- Добавил тот `LowCardinality(T)` тип данных. Этот тип данных автоматически создает локальный словарь значений и позволяет обрабатывать данные без распаковки словаря. [\#2830](https://github.com/ClickHouse/ClickHouse/pull/2830) -- Добавлен кэш JIT-скомпилированных функций и счетчик количества использований перед компиляцией. Чтобы выполнить JIT-компиляцию выражений, включите `compile_expressions` установка. [\#2990](https://github.com/ClickHouse/ClickHouse/pull/2990) [\#3077](https://github.com/ClickHouse/ClickHouse/pull/3077) - -#### Улучшения: {#improvements-4} - -- Исправлена проблема с неограниченным накоплением журнала репликации при наличии брошенных реплик. Добавлен эффективный режим восстановления для реплик с длительным запаздыванием. -- Улучшенная производительность `GROUP BY` с несколькими полями агрегации, когда одно из них является строковым, а другие-фиксированной длины. -- Улучшенная производительность при использовании `PREWHERE` и с неявной передачей выражений в `PREWHERE`. -- Улучшена производительность синтаксического анализа для текстовых форматов (`CSV`, `TSV`). [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2977) [\#2980](https://github.com/ClickHouse/ClickHouse/pull/2980) -- Улучшена производительность чтения строк и массивов в двоичных форматах. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2955) -- Повышенная производительность и снижение потребления памяти для запросов к `system.tables` и `system.columns` при наличии очень большого количества таблиц на одном сервере. [\#2953](https://github.com/ClickHouse/ClickHouse/pull/2953) -- Исправлена проблема производительности в случае большого потока запросов, приводящих к ошибке (the `_dl_addr` функция видна в `perf top`, но сервер не использует много процессора). [\#2938](https://github.com/ClickHouse/ClickHouse/pull/2938) -- Условия бросаются в поле зрения (когда `enable_optimize_predicate_expression` включен). [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2907) -- Улучшения в функциональности для `UUID` тип данных. [\#3074](https://github.com/ClickHouse/ClickHouse/pull/3074) [\#2985](https://github.com/ClickHouse/ClickHouse/pull/2985) -- То `UUID` тип данных поддерживается в словарях-Alchemist. [\#2822](https://github.com/ClickHouse/ClickHouse/pull/2822) -- То `visitParamExtractRaw` функция корректно работает с вложенными структурами. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2974) -- Когда `input_format_skip_unknown_fields` настройка включена, поля объекта в поле `JSONEachRow` формат пропущен правильно. [BlahGeek](https://github.com/ClickHouse/ClickHouse/pull/2958) -- Для `CASE` выражение с условиями теперь можно опустить `ELSE`, что эквивалентно `ELSE NULL`. [\#2920](https://github.com/ClickHouse/ClickHouse/pull/2920) -- Тайм-аут операции теперь можно настроить при работе с ZooKeeper. [urykhy](https://github.com/ClickHouse/ClickHouse/pull/2971) -- Вы можете указать смещение для `LIMIT n, m` как `LIMIT n OFFSET m`. [\#2840](https://github.com/ClickHouse/ClickHouse/pull/2840) -- Вы можете использовать `SELECT TOP n` синтаксис как альтернатива для `LIMIT`. [\#2840](https://github.com/ClickHouse/ClickHouse/pull/2840) -- Увеличен размер очереди для записи в системные таблицы, так что `SystemLog parameter queue is full` ошибки случаются не так часто. -- То `windowFunnel` агрегатная функция теперь поддерживает события, удовлетворяющие нескольким условиям. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2801) -- Повторяющиеся столбцы могут быть использованы в a `USING` пунктом `JOIN`. [\#3006](https://github.com/ClickHouse/ClickHouse/pull/3006) -- `Pretty` форматы теперь имеют ограничение на выравнивание столбцов по ширине. Используйте `output_format_pretty_max_column_pad_width` установка. Если значение больше, то оно все равно будет отображаться полностью, но другие ячейки таблицы не будут слишком широкими. [\#3003](https://github.com/ClickHouse/ClickHouse/pull/3003) -- То `odbc` функция таблицы теперь позволяет указать имя базы данных / схемы. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2885) -- Добавлена возможность использовать имя Пользователя, указанное в `clickhouse-client` конфигурационный файл. [Владимир Козбин](https://github.com/ClickHouse/ClickHouse/pull/2909) -- То `ZooKeeperExceptions` счетчик был разделен на три счетчика: `ZooKeeperUserExceptions`, `ZooKeeperHardwareExceptions`, и `ZooKeeperOtherExceptions`. -- `ALTER DELETE` запросы работают для материализованных представлений. -- Добавлена рандомизация при периодическом запуске потока очистки для `ReplicatedMergeTree` таблицы во избежание периодических скачков нагрузки при наличии очень большого количества `ReplicatedMergeTree` таблицы. -- Поддержка `ATTACH TABLE ... ON CLUSTER` запросы. [\#3025](https://github.com/ClickHouse/ClickHouse/pull/3025) - -#### Устранение ошибок: {#bug-fixes-13} - -- Исправлена проблема с `Dictionary` таблицы (бросает то `Size of offsets doesn't match size of column` или `Unknown compression method` исключение). Эта ошибка появилась в версии 18.10.3. [\#2913](https://github.com/ClickHouse/ClickHouse/issues/2913) -- Исправлена ошибка при слиянии `CollapsingMergeTree` таблицы, если одна из частей данных пуста (эти части формируются во время слияния или `ALTER DELETE` если все данные были удалены), а также `vertical` для слияния был использован алгоритм. [\#3049](https://github.com/ClickHouse/ClickHouse/pull/3049) -- Исправлено состояние гонки во время `DROP` или `TRUNCATE` для `Memory` столы с одновременным `SELECT`, что может привести к сбоям сервера. Эта ошибка появилась в версии 1.1.54388. [\#3038](https://github.com/ClickHouse/ClickHouse/pull/3038) -- Исправлена возможность потери данных при вставке в систему `Replicated` таблицы, если `Session is expired` возвращается ошибка (потеря данных может быть обнаружена с помощью `ReplicatedDataLoss` метрический). Эта ошибка произошла в версии 1.1.54378. [\#2939](https://github.com/ClickHouse/ClickHouse/pull/2939) [\#2949](https://github.com/ClickHouse/ClickHouse/pull/2949) [\#2964](https://github.com/ClickHouse/ClickHouse/pull/2964) -- Исправлен сегфолт при `JOIN ... ON`. [\#3000](https://github.com/ClickHouse/ClickHouse/pull/3000) -- Исправлена ошибка поиска имен столбцов, когда `WHERE` выражение полностью состоит из квалифицированного имени столбца, например `WHERE table.column`. [\#2994](https://github.com/ClickHouse/ClickHouse/pull/2994) -- Исправлена ошибка «Not found column» ошибка, возникшая при выполнении распределенных запросов, если с удаленного сервера запрашивается один столбец, состоящий из выражения IN с вложенным запросом. [\#3087](https://github.com/ClickHouse/ClickHouse/pull/3087) -- Исправлена ошибка `Block structure mismatch in UNION stream: different number of columns` ошибка, возникшая для распределенных запросов, если один из сегментов является локальным, а другой-нет, и оптимизация перемещения в `PREWHERE` это срабатывает. [\#2226](https://github.com/ClickHouse/ClickHouse/pull/2226) [\#3037](https://github.com/ClickHouse/ClickHouse/pull/3037) [\#3055](https://github.com/ClickHouse/ClickHouse/pull/3055) [\#3065](https://github.com/ClickHouse/ClickHouse/pull/3065) [\#3073](https://github.com/ClickHouse/ClickHouse/pull/3073) [\#3090](https://github.com/ClickHouse/ClickHouse/pull/3090) [\#3093](https://github.com/ClickHouse/ClickHouse/pull/3093) -- Исправлена ошибка `pointInPolygon` функция для некоторых случаев невыпуклых многоугольников. [\#2910](https://github.com/ClickHouse/ClickHouse/pull/2910) -- Исправлен неверный результат при сравнении `nan` с целыми числами. [\#3024](https://github.com/ClickHouse/ClickHouse/pull/3024) -- Исправлена ошибка в системе `zlib-ng` библиотека, которая в редких случаях может привести к segfault. [\#2854](https://github.com/ClickHouse/ClickHouse/pull/2854) -- Исправлена утечка памяти при вставке в таблицу с помощью `AggregateFunction` столбцы, если состояние агрегатной функции не простое (выделяет память отдельно), и если один запрос на вставку приводит к нескольким небольшим блокам. [\#3084](https://github.com/ClickHouse/ClickHouse/pull/3084) -- Исправлено состояние гонки при создании и удалении одного и того же объекта `Buffer` или `MergeTree` стол одновременно. -- Исправлена возможность segfault при сравнении кортежей, составленных из определенных нетривиальных типов, таких как кортежи. [\#2989](https://github.com/ClickHouse/ClickHouse/pull/2989) -- Исправлена возможность возникновения segfault при запуске некоторых `ON CLUSTER` запросы. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2960) -- Исправлена ошибка в системе `arrayDistinct` функция для `Nullable` элемент массива. [\#2845](https://github.com/ClickHouse/ClickHouse/pull/2845) [\#2937](https://github.com/ClickHouse/ClickHouse/pull/2937) -- То `enable_optimize_predicate_expression` опция теперь корректно поддерживает случаи с `SELECT *`. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2929) -- Исправлена ошибка segfault при повторной инициализации сеанса ZooKeeper. [\#2917](https://github.com/ClickHouse/ClickHouse/pull/2917) -- Исправлена блокировка при работе с зоопарка. -- Исправлен неверный код для добавления вложенных структур данных в a `SummingMergeTree`. -- При выделении памяти для состояний агрегатных функций корректно учитывается выравнивание, что позволяет использовать операции, требующие выравнивания при реализации состояний агрегатных функций. [chenxing-xc](https://github.com/ClickHouse/ClickHouse/pull/2808) - -#### Исправление безопасности: {#security-fix} - -- Безопасное использование источников данных ODBC. Взаимодействие с драйверами ODBC использует отдельный интерфейс `clickhouse-odbc-bridge` процесс. Ошибки в сторонних драйверах ODBC больше не вызывают проблем со стабильностью сервера или уязвимостями. [\#2828](https://github.com/ClickHouse/ClickHouse/pull/2828) [\#2879](https://github.com/ClickHouse/ClickHouse/pull/2879) [\#2886](https://github.com/ClickHouse/ClickHouse/pull/2886) [\#2893](https://github.com/ClickHouse/ClickHouse/pull/2893) [\#2921](https://github.com/ClickHouse/ClickHouse/pull/2921) -- Исправлена неправильная проверка пути к файлу в системе `catBoostPool` табличная функция. [\#2894](https://github.com/ClickHouse/ClickHouse/pull/2894) -- Содержание системных таблиц (`tables`, `databases`, `parts`, `columns`, `parts_columns`, `merges`, `mutations`, `replicas`, и `replication_queue`) фильтруются в соответствии с настроенным пользователем доступом к базам данных (`allow_databases`). [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2856) - -#### Назад несовместимые изменения: {#backward-incompatible-changes-3} - -- В запросах с соединением символ звезды расширяется до списка столбцов во всех таблицах в соответствии со стандартом SQL. Вы можете восстановить старое поведение, установив `asterisk_left_columns_only` до 1 на уровне конфигурации пользователя. - -#### Изменения в сборке: {#build-changes-2} - -- Большинство интеграционных тестов теперь можно запускать с помощью commit. -- Проверка стиля кода также может выполняться с помощью commit. -- То `memcpy` реализация выбрана правильно при построении на CentOS7/Fedora. [Этьен Шампетье](https://github.com/ClickHouse/ClickHouse/pull/2912) -- При использовании clang для сборки, некоторые предупреждения от `-Weverything` были добавлены, в дополнение к обычным `-Wall-Wextra -Werror`. [\#2957](https://github.com/ClickHouse/ClickHouse/pull/2957) -- Отладка сборки использует следующие методы: `jemalloc` вариант отладки. -- Интерфейс библиотеки для взаимодействия с ZooKeeper объявлен абстрактным. [\#2950](https://github.com/ClickHouse/ClickHouse/pull/2950) - -## ClickHouse релиз 18.10 {#clickhouse-release-18-10} - -### ClickHouse релиз 18.10.3, 2018-08-13 {#clickhouse-release-18-10-3-2018-08-13} - -#### Новые средства: {#new-features-5} - -- HTTPS можно использовать для репликации. [\#2760](https://github.com/ClickHouse/ClickHouse/pull/2760) -- Добавлены функции `murmurHash2_64`, `murmurHash3_32`, `murmurHash3_64`, и `murmurHash3_128` в дополнение к существующим `murmurHash2_32`. [\#2791](https://github.com/ClickHouse/ClickHouse/pull/2791) -- Поддержка типы, допускающие значения NULL в драйвере ODBC ClickHouse (`ODBCDriver2` выходной формат). [\#2834](https://github.com/ClickHouse/ClickHouse/pull/2834) -- Поддержка `UUID` в ключевых колонках. - -#### Улучшения: {#improvements-5} - -- Кластеры могут быть удалены без перезагрузки сервера, когда они удаляются из конфигурационных файлов. [\#2777](https://github.com/ClickHouse/ClickHouse/pull/2777) -- Внешние словари могут быть удалены без перезагрузки сервера, когда они удаляются из конфигурационных файлов. [\#2779](https://github.com/ClickHouse/ClickHouse/pull/2779) -- Добавлен `SETTINGS` поддержка для the `Kafka` настольный двигатель. [Александр Маршалов](https://github.com/ClickHouse/ClickHouse/pull/2781) -- Улучшения для компании `UUID` тип данных (еще не полный). [\#2618](https://github.com/ClickHouse/ClickHouse/pull/2618) -- Поддержка для пустых частей после слияния в `SummingMergeTree`, `CollapsingMergeTree` и `VersionedCollapsingMergeTree` двигатели. [\#2815](https://github.com/ClickHouse/ClickHouse/pull/2815) -- Старые записи завершенных мутаций удаляются (`ALTER DELETE`). [\#2784](https://github.com/ClickHouse/ClickHouse/pull/2784) -- Добавил тот `system.merge_tree_settings` стол. [Кирилл Шваков](https://github.com/ClickHouse/ClickHouse/pull/2841) -- То `system.tables` таблица теперь имеет столбцы зависимостей: `dependencies_database` и `dependencies_table`. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2851) -- Добавил тот `max_partition_size_to_drop` вариант конфигурации. [\#2782](https://github.com/ClickHouse/ClickHouse/pull/2782) -- Добавил тот `output_format_json_escape_forward_slashes` вариант. [Александр Бочаров](https://github.com/ClickHouse/ClickHouse/pull/2812) -- Добавил тот `max_fetch_partition_retries_count` установка. [\#2831](https://github.com/ClickHouse/ClickHouse/pull/2831) -- Добавил тот `prefer_localhost_replica` настройка для отключения предпочтения для локальной реплики и перехода к локальной реплике без межпроцессного взаимодействия. [\#2832](https://github.com/ClickHouse/ClickHouse/pull/2832) -- То `quantileExact` возвращает агрегатная функция `nan` в случае агрегации на пустом месте `Float32` или `Float64` набор. [Вашим Ли](https://github.com/ClickHouse/ClickHouse/pull/2855) - -#### Устранение ошибок: {#bug-fixes-14} - -- Удалено ненужное экранирование параметров строки подключения для ODBC, что сделало невозможным установление соединения. Эта ошибка произошла в версии 18.6.0. -- Исправлена логика обработки `REPLACE PARTITION` команды в очереди репликации. Если их будет двое `REPLACE` команды для одного и того же раздела, неправильная логика может привести к тому, что один из них останется в очереди репликации и не будет выполнен. [\#2814](https://github.com/ClickHouse/ClickHouse/pull/2814) -- Исправлена ошибка слияния, когда все части данных были пусты (части, которые были сформированы из слияния или из `ALTER DELETE` если все данные были удалены). Эта ошибка появилась в версии 18.1.0. [\#2930](https://github.com/ClickHouse/ClickHouse/pull/2930) -- Исправлена ошибка при одновременном использовании `Set` или `Join`. [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2823) -- Исправлена ошибка `Block structure mismatch in UNION stream: different number of columns` ошибка, которая произошла для `UNION ALL` запросы внутри подзапроса, если один из `SELECT` запросы содержат повторяющиеся имена столбцов. [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2094) -- Исправлена утечка памяти, если при подключении к серверу MySQL возникало исключение. -- Исправлен неверный код ответа clickhouse-клиента в случае ошибки запроса. -- Исправлено некорректное поведение материализованных представлений, содержащих отличия. [\#2795](https://github.com/ClickHouse/ClickHouse/issues/2795) - -#### Назад несовместимые изменения {#backward-incompatible-changes-4} - -- Удалена поддержка запросов CHECK TABLE для распределенных таблиц. - -#### Изменения в сборке: {#build-changes-3} - -- Распределитель был заменен: `jemalloc` теперь используется вместо `tcmalloc`. В некоторых сценариях это увеличивает скорость до 20%. Однако есть запросы, которые замедлились до 20%. Потребление памяти было уменьшено приблизительно на 10% в некоторых сценариях, с улучшенной стабильностью. При высокой конкурентной нагрузке использование процессора в пользовательском пространстве и в системе показывает лишь небольшое увеличение. [\#2773](https://github.com/ClickHouse/ClickHouse/pull/2773) -- Использование libressl из подмодуля. [\#1983](https://github.com/ClickHouse/ClickHouse/pull/1983) [\#2807](https://github.com/ClickHouse/ClickHouse/pull/2807) -- Использование unixodbc из подмодуля. [\#2789](https://github.com/ClickHouse/ClickHouse/pull/2789) -- Использование mariadb-connector-c из подмодуля. [\#2785](https://github.com/ClickHouse/ClickHouse/pull/2785) -- Добавлены функциональные тестовые файлы в репозиторий, зависящие от доступности тестовых данных (пока без самих тестовых данных). - -## ClickHouse релиз 18.6 {#clickhouse-release-18-6} - -### ClickHouse релиз 18.6.0, 2018-08-02 {#clickhouse-release-18-6-0-2018-08-02} - -#### Новые средства: {#new-features-6} - -- Добавлена поддержка выражений для соединения на синтаксис: - `JOIN ON Expr([table.]column ...) = Expr([table.]column, ...) [AND Expr([table.]column, ...) = Expr([table.]column, ...) ...]` - Выражение должно быть цепочкой равенств, Соединенных оператором и. Каждая сторона равенства может быть произвольным выражением над столбцами одной из таблиц. Поддерживается использование полных имен столбцов (`table.name`, `database.table.name`, `table_alias.name`, `subquery_alias.name`) для правильного стола. [\#2742](https://github.com/ClickHouse/ClickHouse/pull/2742) -- HTTPS может быть включен для репликации. [\#2760](https://github.com/ClickHouse/ClickHouse/pull/2760) - -#### Улучшения: {#improvements-6} - -- Сервер передает клиенту компонент исправлений своей версии. Данные о компоненте версии патча находятся в `system.processes` и `query_log`. [\#2646](https://github.com/ClickHouse/ClickHouse/pull/2646) - -## ClickHouse релиз 18.5 {#clickhouse-release-18-5} - -### ClickHouse релиз 18.5.1, 2018-07-31 {#clickhouse-release-18-5-1-2018-07-31} - -#### Новые средства: {#new-features-7} - -- Добавлена хэш-функция `murmurHash2_32` [\#2756](https://github.com/ClickHouse/ClickHouse/pull/2756). - -#### Улучшения: {#improvements-7} - -- Теперь вы можете использовать `from_env` [\#2741](https://github.com/ClickHouse/ClickHouse/pull/2741) атрибут для установки значений в конфигурационных файлах из переменных окружения. -- Добавлены версии с нечувствительностью к регистру символов `coalesce`, `ifNull`, и `nullIf functions` [\#2752](https://github.com/ClickHouse/ClickHouse/pull/2752). - -#### Устранение ошибок: {#bug-fixes-15} - -- Исправлена возможная ошибка при запуске реплики [\#2759](https://github.com/ClickHouse/ClickHouse/pull/2759). - -## ClickHouse релиз 18.4 {#clickhouse-release-18-4} - -### ClickHouse релиз 18.4.0, 2018-07-28 {#clickhouse-release-18-4-0-2018-07-28} - -#### Новые средства: {#new-features-8} - -- Добавлены системные таблицы: `formats`, `data_type_families`, `aggregate_function_combinators`, `table_functions`, `table_engines`, `collations` [\#2721](https://github.com/ClickHouse/ClickHouse/pull/2721). -- Добавлена возможность использовать табличную функцию вместо таблицы в качестве аргумента a `remote` или `cluster table function` [\#2708](https://github.com/ClickHouse/ClickHouse/pull/2708). -- Поддержка `HTTP Basic` аутентификация в протоколе репликации [\#2727](https://github.com/ClickHouse/ClickHouse/pull/2727). -- То `has` функция теперь позволяет искать числовое значение в массиве `Enum` ценности [Максим Хрисанфов](https://github.com/ClickHouse/ClickHouse/pull/2699). -- Поддержка добавления произвольных разделителей сообщений при чтении из `Kafka` [Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2701). - -#### Улучшения: {#improvements-8} - -- То `ALTER TABLE t DELETE WHERE` запрос не перезаписывает части данных, которые не были затронуты условием WHERE [\#2694](https://github.com/ClickHouse/ClickHouse/pull/2694). -- То `use_minimalistic_checksums_in_zookeeper` вариант для `ReplicatedMergeTree` таблицы включены по умолчанию. Этот параметр был добавлен в версии 1.1.54378, 2018-04-16. Версии, которые старше 1.1.54378, больше не могут быть установлены. -- Поддержка для бега `KILL` и `OPTIMIZE` запросы, которые определяют `ON CLUSTER` [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2689). - -#### Устранение ошибок: {#bug-fixes-16} - -- Исправлена ошибка `Column ... is not under an aggregate function and not in GROUP BY` для агрегатирования с выражением. Эта ошибка появилась в версии 18.1.0. ([bbdd780b](https://github.com/ClickHouse/ClickHouse/commit/bbdd780be0be06a0f336775941cdd536878dd2c2)) -- Исправлена ошибка в системе `windowFunnel aggregate function` [Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2735). -- Исправлена ошибка в системе `anyHeavy` статистическая функция ([a2101df2](https://github.com/ClickHouse/ClickHouse/commit/a2101df25a6a0fba99aa71f8793d762af2b801ee)) -- Исправлен сбой сервера при использовании `countArray()` статистическая функция. - -#### Назад несовместимые изменения: {#backward-incompatible-changes-5} - -- Параметры для `Kafka` двигатель был изменен с `Kafka(kafka_broker_list, kafka_topic_list, kafka_group_name, kafka_format[, kafka_schema, kafka_num_consumers])` к `Kafka(kafka_broker_list, kafka_topic_list, kafka_group_name, kafka_format[, kafka_row_delimiter, kafka_schema, kafka_num_consumers])`. Если ваши таблицы используют `kafka_schema` или `kafka_num_consumers` параметры, вы должны вручную редактировать файлы метаданных `path/metadata/database/table.sql` и добавить `kafka_row_delimiter` параметр с `''` ценность. - -## ClickHouse релиз 18.1 {#clickhouse-release-18-1} - -### ClickHouse релиз 18.1.0, 2018-07-23 {#clickhouse-release-18-1-0-2018-07-23} - -#### Новые средства: {#new-features-9} - -- Поддержка для the `ALTER TABLE t DELETE WHERE` запрос на нереплицируемые MergeTree таблицы ([\#2634](https://github.com/ClickHouse/ClickHouse/pull/2634)). -- Поддержка произвольных типов для `uniq*` семейство агрегатных функций ([\#2010](https://github.com/ClickHouse/ClickHouse/issues/2010)). -- Поддержка произвольных типов в операторах сравнения ([\#2026](https://github.com/ClickHouse/ClickHouse/issues/2026)). -- То `users.xml` файл позволяет установить маску подсети в формате `10.0.0.1/255.255.255.0`. Это необходимо для использования масок для сетей IPv6 с нулями посередине ([\#2637](https://github.com/ClickHouse/ClickHouse/pull/2637)). -- Добавил тот `arrayDistinct` функция ([\#2670](https://github.com/ClickHouse/ClickHouse/pull/2670)). -- Движок SummingMergeTree теперь может работать со столбцами типа AggregateFunction ([Константин Сергеевич Пан](https://github.com/ClickHouse/ClickHouse/pull/2566)). - -#### Улучшения: {#improvements-9} - -- Изменена схема нумерации для версий выпуска. Теперь первая часть содержит год выпуска (A. D., Московский часовой пояс, минус 2000), вторая часть содержит номер для крупных изменений (увеличивается для большинства релизов), а третья часть-это патч-версия. Релизы по-прежнему имеют обратную совместимость, если в списке изменений не указано иное. -- Более быстрое преобразование чисел с плавающей запятой в строку ([Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2664)). -- Если некоторые строки были пропущены во время вставки из-за ошибок синтаксического анализа (это возможно с помощью `input_allow_errors_num` и `input_allow_errors_ratio` настройки включены), количество пропущенных строк теперь записывается в журнал сервера ([Леонардо Чекки](https://github.com/ClickHouse/ClickHouse/pull/2669)). - -#### Устранение ошибок: {#bug-fixes-17} - -- Исправлена команда усечения для временных таблиц ([Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2624)). -- Исправлена редкая тупиковая ситуация в клиентской библиотеке ZooKeeper, возникшая при возникновении сетевой ошибки при чтении ответа ([c315200](https://github.com/ClickHouse/ClickHouse/commit/c315200e64b87e44bdf740707fc857d1fdf7e947)). -- Исправлена ошибка во время бросания на типы, допускающие значение null ([\#1322](https://github.com/ClickHouse/ClickHouse/issues/1322)). -- Исправлен неверный результат работы системы `maxIntersection()` функция, когда границы интервалов совпадают ([Майкл Фурмур](https://github.com/ClickHouse/ClickHouse/pull/2657)). -- Исправлено некорректное преобразование цепочки выражений OR в аргумент функции ([chenxing-xc](https://github.com/ClickHouse/ClickHouse/pull/2663)). -- Исправлено снижение производительности для запросов, содержащих `IN (subquery)` выражения внутри другого подзапроса ([\#2571](https://github.com/ClickHouse/ClickHouse/issues/2571)). -- Исправлена несовместимость серверов с различными версиями в распределенных запросах, использующих a `CAST` функция, которая не написана прописными буквами ([fe8c4d6](https://github.com/ClickHouse/ClickHouse/commit/fe8c4d64e434cacd4ceef34faa9005129f2190a5)). -- Добавлено отсутствующее цитирование идентификаторов для запросов к внешней СУБД ([\#2635](https://github.com/ClickHouse/ClickHouse/issues/2635)). - -#### Назад несовместимые изменения: {#backward-incompatible-changes-6} - -- Преобразование строки, содержащей нулевое число, в DateTime не работает. Пример: `SELECT toDateTime('0')`. Это также является причиной того, что `DateTime DEFAULT '0'` не работает в таблицах, а также `0` в словарях. Решение: заменить `0` с `0000-00-00 00:00:00`. - -## ClickHouse release 1.1 {#clickhouse-release-1-1} - -### ClickHouse релиз 1.1.54394, 2018-07-12 {#clickhouse-release-1-1-54394-2018-07-12} - -#### Новые средства: {#new-features-10} - -- Добавил тот `histogram` статистическая функция ([Михаил Сурин](https://github.com/ClickHouse/ClickHouse/pull/2521)). -- Сейчас `OPTIMIZE TABLE ... FINAL` может использоваться без указания разделов для `ReplicatedMergeTree` ([Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2600)). - -#### Устранение ошибок: {#bug-fixes-18} - -- Исправлена проблема с очень малым таймаутом для сокетов (одна секунда) для чтения и записи при отправке и загрузке реплицированных данных, что делало невозможной загрузку больших частей при наличии нагрузки на сеть или диск (это приводило к циклическим попыткам загрузки частей). Эта ошибка произошла в версии 1.1.54388. -- Исправлены проблемы при использовании chroot в ZooKeeper, если вы вставили дубликаты блоков данных в таблицу. -- То `has` функция теперь корректно работает для массива с нулевыми элементами ([\#2115](https://github.com/ClickHouse/ClickHouse/issues/2115)). -- То `system.tables` таблица теперь работает корректно при использовании в распределенных запросах. То `metadata_modification_time` и `engine_full` столбцы теперь не являются виртуальными. Исправлена ошибка, возникавшая при запросе из таблицы только этих столбцов. -- Исправлено как пустой `TinyLog` таблица работает после вставки пустого блока данных ([\#2563](https://github.com/ClickHouse/ClickHouse/issues/2563)). -- То `system.zookeeper` таблица работает, если значение узла в ZooKeeper равно NULL. - -### ClickHouse релиз 1.1.54390, 2018-07-06 {#clickhouse-release-1-1-54390-2018-07-06} - -#### Новые средства: {#new-features-11} - -- Запросы могут быть отправлены в `multipart/form-data` формат (в виде `query` поле), что полезно, если внешние данные также отправляются для обработки запросов ([Ольга Хвостикова](https://github.com/ClickHouse/ClickHouse/pull/2490)). -- Добавлена возможность включения или отключения обработки одинарных или двойных кавычек при чтении данных в формате CSV. Вы можете настроить это в разделе `format_csv_allow_single_quotes` и `format_csv_allow_double_quotes` настройки ([Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2574)). -- Сейчас `OPTIMIZE TABLE ... FINAL` может использоваться без указания раздела для нереплицированных вариантов `MergeTree` ([Амос Птица](https://github.com/ClickHouse/ClickHouse/pull/2599)). - -#### Улучшения: {#improvements-10} - -- Улучшенная производительность, снижение потребления памяти и корректное отслеживание потребления памяти с использованием оператора IN, когда можно использовать табличный индекс ([\#2584](https://github.com/ClickHouse/ClickHouse/pull/2584)). -- Удалена избыточная проверка контрольных сумм при добавлении части данных. Это важно при наличии большого количества реплик, так как в этих случаях общее число проверок было равно N^2. -- Добавлена поддержка для `Array(Tuple(...))` аргументы в пользу этого `arrayEnumerateUniq` функция ([\#2573](https://github.com/ClickHouse/ClickHouse/pull/2573)). -- Добавлен `Nullable` поддержка для the `runningDifference` функция ([\#2594](https://github.com/ClickHouse/ClickHouse/pull/2594)). -- Улучшена производительность анализа запросов при наличии очень большого количества выражений ([\#2572](https://github.com/ClickHouse/ClickHouse/pull/2572)). -- Более быстрый выбор частей данных для слияния в `ReplicatedMergeTree` таблицы. Более быстрое восстановление сеанса смотрителя зоопарка ([\#2597](https://github.com/ClickHouse/ClickHouse/pull/2597)). -- То `format_version.txt` файл для `MergeTree` таблицы создаются заново, если они отсутствуют, что имеет смысл, если ClickHouse запускается после копирования структуры каталогов без файлов ([Киприан Хакман](https://github.com/ClickHouse/ClickHouse/pull/2593)). - -#### Устранение ошибок: {#bug-fixes-19} - -- Исправлена ошибка при работе с ZooKeeper, которая могла сделать невозможным восстановление сеанса и состояний таблиц только для чтения перед перезапуском сервера. -- Исправлена ошибка при работе с ZooKeeper, которая могла привести к тому, что старые узлы не удалялись, если сеанс прерывался. -- Исправлена ошибка в системе `quantileTDigest` функции для Аргументов с плавающей точкой (эта ошибка была введена в версии 1.1.54388) ([Михаил Сурин](https://github.com/ClickHouse/ClickHouse/pull/2553)). -- Исправлена ошибка в индексе для таблиц MergeTree, если столбец первичного ключа находится внутри функции преобразования типов между знаковыми и беззнаковыми целыми числами одинакового размера ([\#2603](https://github.com/ClickHouse/ClickHouse/pull/2603)). -- Исправлена обработка выхода онлайн / оффлайн если `macros` используются, но их нет в файле конфигурации ([\#2570](https://github.com/ClickHouse/ClickHouse/pull/2570)). -- Исправлено переключение на базу данных по умолчанию при повторном подключении клиента ([\#2583](https://github.com/ClickHouse/ClickHouse/pull/2583)). -- Исправлена ошибка, возникшая при появлении `use_index_for_in_with_subqueries` настройка была отключена. - -#### Исправление безопасности: {#security-fix-1} - -- Отправка файлов больше не возможна при подключении к MySQL (`LOAD DATA LOCAL INFILE`). - -### ClickHouse релиз 1.1.54388, 2018-06-28 {#clickhouse-release-1-1-54388-2018-06-28} - -#### Новые средства: {#new-features-12} - -- Поддержка для the `ALTER TABLE t DELETE WHERE` запрос для реплицированных таблиц. Добавил тот `system.mutations` таблица для отслеживания хода выполнения запросов этого типа. -- Поддержка для the `ALTER TABLE t [REPLACE|ATTACH] PARTITION` запрос для таблиц \* MergeTree. -- Поддержка для the `TRUNCATE TABLE` запрос ([Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2260)) -- Несколько новый `SYSTEM` запросы к реплицируемым таблицам (`RESTART REPLICAS`, `SYNC REPLICA`, `[STOP|START] [MERGES|FETCHES|SENDS REPLICATED|REPLICATION QUEUES]`). -- Добавлена возможность записи в таблицу с помощью движка MySQL и соответствующей табличной функции ([Санди-ли](https://github.com/ClickHouse/ClickHouse/pull/2294)). -- Добавил тот `url()` функция таблицы и `URL` настольный двигатель ([Александр Сапин](https://github.com/ClickHouse/ClickHouse/pull/2501)). -- Добавил тот `windowFunnel` статистическая функция ([Санди-ли](https://github.com/ClickHouse/ClickHouse/pull/2352)). -- Новый `startsWith` и `endsWith` функции для строк ([Вадим Плахтинский](https://github.com/ClickHouse/ClickHouse/pull/2429)). -- То `numbers()` функция таблицы теперь позволяет указать смещение ([Зимний Чжан](https://github.com/ClickHouse/ClickHouse/pull/2535)). -- Пароль к нему `clickhouse-client` может быть введен в интерактивном режиме. -- Теперь журналы сервера можно отправлять в системный журнал ([Александр Крашенинников](https://github.com/ClickHouse/ClickHouse/pull/2459)). -- Поддержка входа в словари с общим источником библиотеки ([Александр Сапин](https://github.com/ClickHouse/ClickHouse/pull/2472)). -- Поддержка пользовательских разделителей CSV ([Иван Жуков](https://github.com/ClickHouse/ClickHouse/pull/2263)) -- Добавил тот `date_time_input_format` установка. Если вы переключите этот параметр на `'best_effort'`, Значения DateTime будут считываться в широком диапазоне форматов. -- Добавил тот `clickhouse-obfuscator` утилита для запутывания данных. Пример использования: публикация данных, используемых в тестах производительности. - -#### Экспериментальная возможность: {#experimental-features-2} - -- Добавлена возможность расчета `and` аргументы только там, где они нужны ([Анастасия Царькова](https://github.com/ClickHouse/ClickHouse/pull/2272)) -- JIT компиляция в машинный код теперь доступна для некоторых выражений ([Плес](https://github.com/ClickHouse/ClickHouse/pull/2277)). - -#### Устранение ошибок: {#bug-fixes-20} - -- Дубликаты больше не появляются для запроса с `DISTINCT` и `ORDER BY`. -- Запросы с помощью `ARRAY JOIN` и `arrayFilter` больше не возвращайте неверный результат. -- Исправлена ошибка при чтении столбца массива из вложенной структуры ([\#2066](https://github.com/ClickHouse/ClickHouse/issues/2066)). -- Исправлена ошибка при анализе запросов с предложением HAVING, например `HAVING tuple IN (...)`. -- Исправлена ошибка при анализе запросов с рекурсивными псевдонимами. -- Исправлена ошибка при чтении из ReplacingMergeTree с условием в PREWHERE, которое фильтрует все строки ([\#2525](https://github.com/ClickHouse/ClickHouse/issues/2525)). -- Настройки профиля пользователя не применялись при использовании сеансов в интерфейсе HTTP. -- Исправлено применение настроек из параметров командной строки в clickhouse-local. -- Клиентская библиотека ZooKeeper теперь использует тайм-аут сеанса, полученный от сервера. -- Исправлена ошибка в клиентской библиотеке ZooKeeper, когда клиент ждал ответа сервера дольше, чем тайм-аут. -- Исправлена обрезка деталей для запросов с условиями по ключевым столбцам разделов ([\#2342](https://github.com/ClickHouse/ClickHouse/issues/2342)). -- Слияния теперь возможны после `CLEAR COLUMN IN PARTITION` ([\#2315](https://github.com/ClickHouse/ClickHouse/issues/2315)). -- Исправлено отображение типов в функции таблицы ODBC ([Санди-ли](https://github.com/ClickHouse/ClickHouse/pull/2268)). -- Сравнение типов было исправлено для `DateTime` с часовым поясом и без него ([Александр Бочаров](https://github.com/ClickHouse/ClickHouse/pull/2400)). -- Исправлен синтаксический разбор и форматирование текста `CAST` оператор. -- Исправлена вставка в материализованный вид для механизма распределенных таблиц ([Babacar Diassé](https://github.com/ClickHouse/ClickHouse/pull/2411)). -- Исправлено состояние гонки при записи данных из `Kafka` двигатель к материализованным представлениям ([Янкуань Лю](https://github.com/ClickHouse/ClickHouse/pull/2448)). -- Исправлена ошибка SSRF в функции таблицы remote (). -- Исправлено поведение выхода из системы `clickhouse-client` в многострочном режиме ([\#2510](https://github.com/ClickHouse/ClickHouse/issues/2510)). - -#### Улучшения: {#improvements-11} - -- Фоновые задачи в реплицированных таблицах теперь выполняются в пуле потоков, а не в отдельных потоках ([Сильвиу Развивается](https://github.com/ClickHouse/ClickHouse/pull/1722)). -- Улучшена производительность сжатия LZ4. -- Более быстрый анализ запросов с большим количеством соединений и подзапросов. -- Кэш DNS теперь обновляется автоматически, когда возникает слишком много сетевых ошибок. -- Вставка таблицы больше не происходит, если вставка в один из материализованных видов невозможна из-за слишком большого количества деталей. -- Исправлено несоответствие в счетчиках событий `Query`, `SelectQuery`, и `InsertQuery`. -- Такие выражения, как `tuple IN (SELECT tuple)` разрешены, если типы кортежей совпадают. -- Сервер с реплицированными таблицами может запуститься, даже если вы еще не настроили ZooKeeper. -- При расчете количества доступных ядер ЦП теперь учитываются ограничения на контрольные группы ([Атри Шарма](https://github.com/ClickHouse/ClickHouse/pull/2325)). -- Добавлено меню для конфигурации каталогов в файл systemd конфиг ([Михаил Ширяев](https://github.com/ClickHouse/ClickHouse/pull/2421)). - -#### Изменения в сборке: {#build-changes-4} - -- Компилятор gcc8 можно использовать для сборки. -- Добавлена возможность построения llvm из подмодуля. -- Версия библиотеки librdkafka была обновлена с v0.11.4. -- Добавлена возможность использования системной библиотеки libcpuid. Версия библиотеки была обновлена до версии 0.4.0. -- Исправлена сборка с использованием библиотеки vectorclass ([Babacar Diassé](https://github.com/ClickHouse/ClickHouse/pull/2274)). -- Cmake теперь генерирует файлы для ninja по умолчанию (например, при использовании `-G Ninja`). -- Добавлена возможность использовать библиотеку libtinfo вместо libtermcap ([Георгий Кондратьев](https://github.com/ClickHouse/ClickHouse/pull/2519)). -- Исправлен конфликт заголовочных файлов в Fedora Rawhide ([\#2520](https://github.com/ClickHouse/ClickHouse/issues/2520)). - -#### Назад несовместимые изменения: {#backward-incompatible-changes-7} - -- Удален побег в `Vertical` и `Pretty*` форматы и удалил `VerticalRaw` формат. -- Если серверы с версией 1.1.54388 (или более поздней) и серверы с более старой версией используются одновременно в распределенном запросе, то запрос имеет следующее значение: `cast(x, 'Type')` выражение лица без лица `AS` ключевое слово и не имеет этого слова `cast` в верхнем регистре исключение будет выдано с сообщением типа `Not found column cast(0, 'UInt8') in block`. Решение: обновите сервер на всем кластере. - -### ClickHouse релиз 1.1.54385, 2018-06-01 {#clickhouse-release-1-1-54385-2018-06-01} - -#### Устранение ошибок: {#bug-fixes-21} - -- Исправлена ошибка,которая в некоторых случаях приводила к блокировке операций ZooKeeper. - -### ClickHouse релиз 1.1.54383, 2018-05-22 {#clickhouse-release-1-1-54383-2018-05-22} - -#### Устранение ошибок: {#bug-fixes-22} - -- Исправлено замедление очереди репликации, если таблица содержит много реплик. - -### ClickHouse релиз 1.1.54381, 2018-05-14 {#clickhouse-release-1-1-54381-2018-05-14} - -#### Устранение ошибок: {#bug-fixes-23} - -- Исправлена утечка узлов в ZooKeeper, когда ClickHouse теряет соединение с сервером ZooKeeper. - -### ClickHouse релиз 1.1.54380, 2018-04-21 {#clickhouse-release-1-1-54380-2018-04-21} - -#### Новые средства: {#new-features-13} - -- Добавлена функция таблицы `file(path, format, structure)`. Пример чтения байтов из `/dev/urandom`: ``` ln -s /dev/urandom /var/lib/clickhouse/user_files/random``clickhouse-client -q "SELECT * FROM file('random', 'RowBinary', 'd UInt8') LIMIT 10" ```. - -#### Улучшения: {#improvements-12} - -- Вложенные запросы могут быть обернуты в `()` скобки для повышения удобочитаемости запросов. Например: `(SELECT 1) UNION ALL (SELECT 1)`. -- Простой `SELECT` запросы от компании `system.processes` таблица не входит в состав `max_concurrent_queries` предел. - -#### Устранение ошибок: {#bug-fixes-24} - -- Исправлено некорректное поведение устройства `IN` оператор при выборе из `MATERIALIZED VIEW`. -- Исправлена некорректная фильтрация по индексу раздела в выражениях типа `partition_key_column IN (...)`. -- Исправлена невозможность выполнения `OPTIMIZE` запрос на реплику без лидера, если `REANAME` было исполнено на столе. -- Исправлена ошибка авторизации при выполнении `OPTIMIZE` или `ALTER` запросы к реплике, не являющейся лидером. -- Исправлено зависание `KILL QUERY`. -- Исправлена ошибка в клиентской библиотеке ZooKeeper, которая приводила к потере часов, замораживанию распределенной очереди DDL и замедлению работы очереди репликации, если она была непустой. `chroot` префикс используется в конфигурации ZooKeeper. - -#### Назад несовместимые изменения: {#backward-incompatible-changes-8} - -- Удалена поддержка таких выражений как `(a, b) IN (SELECT (a, b))` (вы можете использовать эквивалентное выражение `(a, b) IN (SELECT a, b)`). В предыдущих выпусках эти выражения приводили к неопределенным `WHERE` фильтрация или вызванные ошибки. - -### ClickHouse релиз 1.1.54378, 2018-04-16 {#clickhouse-release-1-1-54378-2018-04-16} - -#### Новые средства: {#new-features-14} - -- Уровень ведения журнала можно изменить без перезагрузки сервера. -- Добавил тот `SHOW CREATE DATABASE` запрос. -- То `query_id` может быть передан в `clickhouse-client` (локтевой зал). -- Новая настройка: `max_network_bandwidth_for_all_users`. -- Добавлена поддержка для `ALTER TABLE ... PARTITION ...` для `MATERIALIZED VIEW`. -- Добавлена информация о размере частей данных в несжатом виде в системной таблице. -- Поддержка межсерверного шифрования распределенных таблиц (`1` в конфигурации реплики in ``). -- Конфигурация уровня таблицы для `ReplicatedMergeTree` семья для того, чтобы свести к минимуму объем данных, хранящихся в Zookeeper: : `use_minimalistic_checksums_in_zookeeper = 1` -- Конфигурация системы `clickhouse-client` срочный. По умолчанию имена серверов теперь выводятся в приглашение. Отображаемое имя сервера может быть изменено. Он также отправлен в США. `X-ClickHouse-Display-Name` Заголовок HTTP (Кирилл Шваков). -- Несколько разделенных запятыми `topics` может быть указан для `Kafka` двигатель (Тобиас Адамсон) -- Когда запрос остановлен `KILL QUERY` или `replace_running_query`, клиент получает `Query was canceled` исключение вместо неполного результата. - -#### Улучшения: {#improvements-13} - -- `ALTER TABLE ... DROP/DETACH PARTITION` запросы выполняются в передней части очереди репликации. -- `SELECT ... FINAL` и `OPTIMIZE ... FINAL` может использоваться даже в том случае, если таблица содержит одну часть данных. -- A `query_log` таблица воссоздается на лету, если она была удалена вручную (Кирилл Шваков). -- То `lengthUTF8` функция работает быстрее (zhang2014). -- Улучшенная производительность синхронных вставок в `Distributed` таблицы (`insert_distributed_sync = 1`) при наличии очень большого количества осколков. -- Сервер принимает следующее: `send_timeout` и `receive_timeout` настройки от клиента и применяет их при подключении к клиенту (они применяются в обратном порядке: сокет сервера `send_timeout` устанавливается в положение `receive_timeout` ценность, полученная от клиента, и наоборот). -- Более надежное аварийное восстановление для асинхронной вставки в систему `Distributed` таблицы. -- Возвращаемый тип объекта `countEqual` функция изменяется от `UInt32` к `UInt64` (谢磊). - -#### Устранение ошибок: {#bug-fixes-25} - -- Исправлена ошибка с помощью `IN` когда левая сторона выражения является `Nullable`. -- Правильные результаты теперь возвращаются при использовании кортежей с `IN` когда некоторые компоненты кортежа находятся в индексе таблицы. -- То `max_execution_time` limit теперь корректно работает с распределенными запросами. -- Исправлены ошибки при вычислении размера составных столбцов в системе `system.columns` стол. -- Исправлена ошибка при создании временной таблицы `CREATE TEMPORARY TABLE IF NOT EXISTS.` -- Исправлены ошибки в работе `StorageKafka` (\#\#2075) -- Исправлены сбои сервера из-за недопустимых аргументов некоторых агрегатных функций. -- Исправлена ошибка, которая помешала `DETACH DATABASE` запрос от остановки фоновых задач для `ReplicatedMergeTree` таблицы. -- `Too many parts` состояние с меньшей вероятностью произойдет при вставке в агрегированные материализованные представления (\#\#2084). -- Исправлена рекурсивная обработка подстановок в конфигурации, если за подстановкой должна следовать другая подстановка на том же уровне. -- Исправлен синтаксис в файле метаданных при создании `VIEW` это использует запрос с `UNION ALL`. -- `SummingMergeTree` теперь корректно работает суммирование вложенных структур данных с помощью составного ключа. -- Исправлена возможность возникновения расового состояния при выборе лидера для участия в гонке. `ReplicatedMergeTree` таблицы. - -#### Изменения в сборке: {#build-changes-5} - -- Сборка поддерживает `ninja` вместо `make` и использует `ninja` по умолчанию для построения релизов. -- Переименованные пакеты: `clickhouse-server-base` в `clickhouse-common-static`; `clickhouse-server-common` в `clickhouse-server`; `clickhouse-common-dbg` в `clickhouse-common-static-dbg`. Для установки используйте `clickhouse-server clickhouse-client`. Пакеты со старыми именами по-прежнему будут загружаться в репозитории для обеспечения обратной совместимости. - -#### Назад несовместимые изменения: {#backward-incompatible-changes-9} - -- Удалена специальная интерпретация выражения IN, если массив указан с левой стороны. Ранее выражение `arr IN (set)` было истолковано как «at least one `arr` element belongs to the `set`». Чтобы получить такое же поведение в новой версии, напишите `arrayExists(x -> x IN (set), arr)`. -- Отключено неправильное использование опции сокета `SO_REUSEPORT`, который был неправильно включен по умолчанию в библиотеке Poco. Обратите внимание, что в Linux больше нет никаких причин одновременно указывать адреса `::` и `0.0.0.0` for listen – use just `::`, что позволяет прослушивать соединение как по IPv4, так и по IPv6 (с настройками конфигурации ядра по умолчанию). Вы также можете вернуться к поведению из предыдущих версий, указав `1` в конфигурации. - -### ClickHouse релиз 1.1.54370, 2018-03-16 {#clickhouse-release-1-1-54370-2018-03-16} - -#### Новые средства: {#new-features-15} - -- Добавил тот `system.macros` таблица и автоматическое обновление макросов при изменении конфигурационного файла. -- Добавил тот `SYSTEM RELOAD CONFIG` запрос. -- Добавил тот `maxIntersections(left_col, right_col)` агрегатная функция, возвращающая максимальное количество одновременно пересекающихся интервалов `[left; right]`. То `maxIntersectionsPosition(left, right)` функция возвращает начало строки «maximum» интервал. ([Майкл Фурмур](https://github.com/ClickHouse/ClickHouse/pull/2012)). - -#### Улучшения: {#improvements-14} - -- При вставке данных в `Replicated` таблица, меньше запросов делается к `ZooKeeper` (и большинство ошибок на уровне пользователя исчезли с экрана. `ZooKeeper` бревно). -- Добавлена возможность создавать псевдонимы для наборов данных. Пример: `WITH (1, 2, 3) AS set SELECT number IN set FROM system.numbers LIMIT 10`. - -#### Устранение ошибок: {#bug-fixes-26} - -- Исправлена ошибка `Illegal PREWHERE` ошибка при чтении из таблиц слияния для `Distributed`таблицы. -- Добавлены исправления, позволяющие запускать clickhouse-сервер в контейнерах Docker только для IPv4. -- Исправлено состояние гонки при считывании из системы `system.parts_columns tables.` -- Удалена двойная буферизация во время синхронной вставки в a `Distributed` таблица, которая могла бы вызвать тайм-аут соединения. -- Исправлена ошибка, приводившая к чрезмерно долгому ожиданию недоступной реплики перед началом работы. `SELECT` запрос. -- Исправлены неверные даты в программе `system.parts` стол. -- Исправлена ошибка, из-за которой невозможно было вставить данные в `Replicated` таблица если `chroot` был непустым в конфигурации системы. `ZooKeeper` скопление. -- Исправлен алгоритм вертикального слияния для пустого объекта `ORDER BY` стол. -- Восстановлена возможность использования словарей в запросах к удаленным таблицам, даже если эти словари отсутствуют на сервере-запросчике. Эта функциональность была потеряна в выпуске 1.1.54362. -- Восстановлено поведение для таких запросов, как `SELECT * FROM remote('server2', default.table) WHERE col IN (SELECT col2 FROM default.table)` когда правая сторона `IN` следует использовать пульт дистанционного управления `default.table` а не какой-нибудь местный. Это поведение было нарушено в версии 1.1.54358. -- Удалено постороннее протоколирование уровня ошибок `Not found column ... in block`. - -### Clickhouse Релиз 1.1.54362, 2018-03-11 {#clickhouse-release-1-1-54362-2018-03-11} - -#### Новые средства: {#new-features-16} - -- Агрегация без `GROUP BY` для пустого набора (например, `SELECT count(*) FROM table WHERE 0`) теперь возвращает результат с одной строкой с нулевыми значениями для агрегатных функций, в соответствии со стандартом SQL. Чтобы восстановить старое поведение (вернуть пустой результат), установите `empty_result_for_aggregation_by_empty_set` до 1. -- Добавлено преобразование типов для `UNION ALL`. Здесь разрешены разные псевдонимы `SELECT` должности в `UNION ALL`, в соответствии со стандартом SQL. -- Произвольные выражения поддерживаются в `LIMIT BY` статьи. Ранее можно было использовать только столбцы, полученные в результате `SELECT`. -- Индекс из `MergeTree` таблицы используются, когда `IN` применяется к кортежу выражений из столбцов первичного ключа. Пример: `WHERE (UserID, EventDate) IN ((123, '2000-01-01'), ...)` (Анастасия Царькова). -- Добавил тот `clickhouse-copier` инструмент для копирования между кластерами и пересчета данных (бета-версия). -- Добавлены последовательные функции хэширования: `yandexConsistentHash`, `jumpConsistentHash`, `sumburConsistentHash`. Они могут быть использованы в качестве ключа сегментирования для уменьшения объема сетевого трафика во время последующих повторных сегментирования. -- Добавленные функции: `arrayAny`, `arrayAll`, `hasAny`, `hasAll`, `arrayIntersect`, `arrayResize`. -- Добавил тот `arrayCumSum` функция (Хави Сантана). -- Добавил тот `parseDateTimeBestEffort`, `parseDateTimeBestEffortOrZero`, и `parseDateTimeBestEffortOrNull` функции для чтения DateTime из строки, содержащей текст в широком спектре возможных форматов. -- Данные могут быть частично перезагружены из внешних словарей во время обновления (загружаются только те записи, в которых значение указанного поля больше, чем в предыдущей загрузке) (Арсен Акопян). -- Добавил тот `cluster` табличная функция. Пример: `cluster(cluster_name, db, table)`. То `remote` табличная функция может принять имя кластера в качестве первого аргумента, если оно указано в качестве идентификатора. -- То `remote` и `cluster` функции таблицы можно использовать в `INSERT` запросы. -- Добавил тот `create_table_query` и `engine_full` виртуальные столбцы для `system.tables`стол. То `metadata_modification_time` колонка виртуальная. -- Добавил тот `data_path` и `metadata_path` колонны до `system.tables`и`system.databases` таблицы, а также добавил `path` колонка к столу `system.parts` и `system.parts_columns` таблицы. -- Добавлена дополнительная информация о слияниях в системе `system.part_log` стол. -- Для этого можно использовать произвольный ключ секционирования. `system.query_log` стол (Кирилл Шваков). -- То `SHOW TABLES` запрос теперь также показывает временные таблицы. Добавлены временные таблицы и `is_temporary` столбец `system.tables` (zhang2014). -- Добавлен `DROP TEMPORARY TABLE` и `EXISTS TEMPORARY TABLE` запросы (zhang2014). -- Поддержка `SHOW CREATE TABLE` для временных таблиц (zhang2014). -- Добавил тот `system_profile` параметр конфигурации для параметров, используемых внутренними процессами. -- Поддержка для загрузки `object_id` в качестве атрибута `MongoDB` словари (Павел Литвиненко). -- Чтение `null` в качестве значения по умолчанию при загрузке данных для внешнего словаря с помощью `MongoDB` источник (Павел Литвиненко). -- Чтение `DateTime` значения в системе `Values` форматирование из временной метки Unix без одинарных кавычек. -- Отказоустойчивость поддерживается в `remote` табличные функции для случаев, когда некоторые реплики отсутствуют в запрашиваемой таблице. -- Параметры конфигурации могут быть переопределены в командной строке при запуске `clickhouse-server`. Пример: `clickhouse-server -- --logger.level=information`. -- Реализовано следующее `empty` функция от `FixedString` аргумент: функция возвращает 1, если строка полностью состоит из нулевых байтов (zhang2014). -- Добавил тот `listen_try`параметр конфигурации для прослушивания хотя бы одного из прослушиваемых адресов без выхода из системы, если некоторые адреса не могут быть прослушаны (полезно для систем с отключенной поддержкой IPv4 или IPv6). -- Добавил тот `VersionedCollapsingMergeTree` настольный двигатель. -- Поддержка строк и произвольных числовых типов для `library` источник словаря. -- `MergeTree` таблицы можно использовать и без первичного ключа (необходимо указать `ORDER BY tuple()`). -- A `Nullable` тип может быть `CAST` не-`Nullable` введите если аргумент не является таковым `NULL`. -- `RENAME TABLE` может быть выполнена для `VIEW`. -- Добавил тот `throwIf` функция. -- Добавил тот `odbc_default_field_size` опция, которая позволяет расширить максимальный размер значения, загруженного из источника ODBC (по умолчанию это 1024). -- То `system.processes` стол и `SHOW PROCESSLIST` теперь у вас есть `is_cancelled` и `peak_memory_usage` столбцы. - -#### Улучшения: {#improvements-15} - -- Ограничения и квоты на результат больше не применяются к промежуточным данным для `INSERT SELECT` запросы или для `SELECT` подзапросы. -- Меньше ложных срабатываний `force_restore_data` при проверке состояния `Replicated` таблицы при запуске сервера. -- Добавил тот `allow_distributed_ddl` вариант. -- Недетерминированные функции не допускаются в выражениях для `MergeTree` ключи от стола. -- Файлы с заменами из `config.d` каталоги загружаются в алфавитном порядке. -- Улучшенная производительность системы `arrayElement` функция в случае постоянного многомерного массива с пустым массивом в качестве одного из элементов. Пример: `[[1], []][x]`. -- Теперь сервер запускается быстрее при использовании конфигурационных файлов с очень большими заменами (например, очень большими списками IP-сетей). -- При выполнении запроса функции с табличным значением выполняются один раз. Ранее, `remote` и `mysql` функции с табличным значением дважды выполняли один и тот же запрос для получения структуры таблицы с удаленного сервера. -- То `MkDocs` используется генератор документации. -- При попытке удалить столбец таблицы, который `DEFAULT`/`MATERIALIZED` выражения других столбцов зависят от того, возникает ли исключение (zhang2014). -- Добавлена возможность разбирать пустую строку в текстовых форматах как число 0 для `Float` тип данных. Эта функция была ранее доступна, но была потеряна в выпуске 1.1.54342. -- `Enum` значения могут быть использованы в `min`, `max`, `sum` и некоторые другие функции. В этих случаях он использует соответствующие числовые значения. Эта функция была ранее доступна, но была потеряна в выпуске 1.1.54337. -- Добавлен `max_expanded_ast_elements` чтобы ограничить размер AST после рекурсивного расширения псевдонимов. - -#### Устранение ошибок: {#bug-fixes-27} - -- Исправлены случаи, когда ненужные столбцы были удалены из подзапросов по ошибке или не были удалены из подзапросов, содержащих `UNION ALL`. -- Исправлена ошибка в слияниях для `ReplacingMergeTree` таблицы. -- Исправлены синхронные вставки в `Distributed` таблицы (`insert_distributed_sync = 1`). -- Исправлена обработка выхода онлайн / оффлайн для определенного использования `FULL` и `RIGHT JOIN` с повторяющимися столбцами в подзапросах. -- Исправлена ошибка segfault для некоторых видов использования `replace_running_query` и `KILL QUERY`. -- Исправлен порядок следования `source` и `last_exception` колонны в центре города `system.dictionaries` стол. -- Исправлена ошибка, когда `DROP DATABASE` запрос не удалил файл с метаданными. -- Исправлена ошибка `DROP DATABASE` запрос для `Dictionary` база данных. -- Исправлена низкая точность `uniqHLL12` и `uniqCombined` функции для кардинальностей, превышающих 100 миллионов единиц (Алексей Бочаров). -- Исправлено вычисление неявных значений по умолчанию при необходимости одновременного вычисления явных выражений по умолчанию в `INSERT` запросы (zhang2014). -- Исправлен редкий случай, когда запрос к a `MergeTree` стол не смог закончить (chenxing-xc). -- Исправлена ошибка, возникшая при запуске программы `CHECK` запрос для `Distributed` таблицы, если все осколки являются локальными (chenxing.xc). -- Исправлена небольшая регрессия производительности с функциями, использующими регулярные выражения. -- Исправлена регрессия производительности при создании многомерных массивов из сложных выражений. -- Исправлена ошибка, которая могла привести к дополнительному `FORMAT` раздел, который будет отображаться в `.sql` файл с метаданными. -- Исправлена ошибка, которая вызвала `max_table_size_to_drop` ограничение для применения при попытке удалить a `MATERIALIZED VIEW` глядя на явно заданную таблицу. -- Исправлена несовместимость со старыми клиентами (старые клиенты иногда отправляли данные вместе со старыми клиентами). `DateTime('timezone')` типа, которого они не понимают). -- Исправлена ошибка при чтении `Nested` элементы столбцов структур, которые были добавлены с помощью `ALTER` но это пусто для старых разделов, когда условия для этих столбцов переместились в `PREWHERE`. -- Исправлена ошибка при фильтрации таблиц по виртуальным `_table` столбцы в запросах к `Merge` таблицы. -- Исправлена ошибка при использовании `ALIAS` колонны внутри `Distributed` таблицы. -- Исправлена ошибка, которая делала невозможной динамическую компиляцию запросов с агрегатными функциями из `quantile` семья. -- Исправлено условие гонки в конвейере выполнения запросов, которое возникало в очень редких случаях при использовании `Merge` таблицы с большим количеством таблиц, а при использовании `GLOBAL` подзапросы. -- Исправлена ошибка при передаче массивов разных размеров в `arrayReduce` функция при использовании агрегатных функций из нескольких аргументов. -- Запрещено использование запросов с помощью `UNION ALL` в `MATERIALIZED VIEW`. -- Исправлена ошибка при инициализации программы. `part_log` системная таблица при запуске сервера (по умолчанию, `part_log` отключен). - -#### Назад несовместимые изменения: {#backward-incompatible-changes-10} - -- Удалил то `distributed_ddl_allow_replicated_alter` вариант. Это поведение включено по умолчанию. -- Удалил то `strict_insert_defaults` установка. Если вы использовали эту функцию, напишите нам `clickhouse-feedback@yandex-team.com`. -- Удалил то `UnsortedMergeTree` двигатель. - -### Clickhouse Релиз 1.1.54343, 2018-02-05 {#clickhouse-release-1-1-54343-2018-02-05} - -- Добавлена поддержка макросов для определения имен кластеров в распределенных DDL запросах и конструкторах распределенных таблиц: `CREATE TABLE distr ON CLUSTER '{cluster}' (...) ENGINE = Distributed('{cluster}', 'db', 'table')`. -- Теперь такие запросы, как `SELECT ... FROM table WHERE expr IN (subquery)` обрабатываются с помощью `table` индекс. -- Улучшена обработка дубликатов при вставке в реплицируемые таблицы, поэтому они больше не замедляют выполнение очереди репликации. - -### Clickhouse Релиз 1.1.54342, 2018-01-22 {#clickhouse-release-1-1-54342-2018-01-22} - -Этот выпуск содержит исправления ошибок для предыдущей версии 1.1.54337: - -- Исправлена регрессия в 1.1.54337: если пользователь по умолчанию имеет доступ только для чтения, то сервер отказывается запускаться с сообщением `Cannot create database in readonly mode`. -- Исправлена регрессия в 1.1.54337: в системах с systemd журналы всегда записываются в syslog независимо от конфигурации; сценарий watchdog все еще использует init.д. -- Исправлена регрессия в 1.1.54337: неправильная конфигурация по умолчанию в образе Docker. -- Исправлено недетерминированное поведение GraphiteMergeTree (вы можете увидеть его в сообщениях журнала `Data after merge is not byte-identical to the data on another replicas`). -- Исправлена ошибка, которая могла привести к несогласованным слияниям после оптимизации запроса к Реплицируемым таблицам (вы можете увидеть это в сообщениях журнала `Part ... intersects the previous part`). -- Буферные таблицы теперь работают правильно, когда материализованные столбцы присутствуют в целевой таблице (по zhang2014). -- Исправлена ошибка в реализации NULL. - -### Clickhouse Релиз 1.1.54337, 2018-01-18 {#clickhouse-release-1-1-54337-2018-01-18} - -#### Новые средства: {#new-features-17} - -- Добавлена поддержка хранения многомерных массивов и кортежей (`Tuple` тип данных) в таблицах. -- Поддержка функций таблицы для `DESCRIBE` и `INSERT` запросы. Добавлена поддержка вложенных запросов в `DESCRIBE`. Примеры: `DESC TABLE remote('host', default.hits)`; `DESC TABLE (SELECT 1)`; `INSERT INTO TABLE FUNCTION remote('host', default.hits)`. Поддержка `INSERT INTO TABLE` в дополнение к `INSERT INTO`. -- Улучшена поддержка часовых поясов. То `DateTime` тип данных может быть аннотирован с помощью часового пояса, который используется для синтаксического анализа и форматирования в текстовых форматах. Пример: `DateTime('Europe/Moscow')`. Когда часовые пояса указаны в функциях для `DateTime` аргументы, возвращаемый тип будет отслеживать часовой пояс, и значение будет отображаться, как и ожидалось. -- Добавлены функции `toTimeZone`, `timeDiff`, `toQuarter`, `toRelativeQuarterNum`. То `toRelativeHour`/`Minute`/`Second` функции могут принимать значение типа `Date` в качестве аргумента. То `now` имя функции чувствительно к регистру. -- Добавил тот `toStartOfFifteenMinutes` функция (Кирилл Шваков). -- Добавил тот `clickhouse format` инструмент для форматирования запросов. -- Добавил тот `format_schema_path` configuration parameter (Marek Vavruşa). It is used for specifying a schema in `Cap'n Proto` формат. Файлы схемы могут быть расположены только в указанном каталоге. -- Добавлена поддержка подстановок конфигураций (`incl` и `conf.d`) для настройки внешних словарей и моделей (Павел Якунин). -- Добавлена колонка с документацией для `system.settings` стол (Кирилл Шваков). -- Добавил тот `system.parts_columns` таблица с информацией о размерах столбцов в каждой части данных `MergeTree` таблицы. -- Добавил тот `system.models` таблица с информацией о загруженных данных `CatBoost` модели машинного обучения. -- Добавил тот `mysql` и `odbc` таблица функций и соответствующих `MySQL` и `ODBC` табличные движки для доступа к удаленным базам данных. Эта функциональность находится в стадии бета-тестирования. -- Добавлена возможность передачи аргумента типа `AggregateFunction` для `groupArray` агрегатная функция (таким образом, вы можете создать массив состояний некоторой агрегатной функции). -- Сняты ограничения на различные комбинации комбинаторов агрегатных функций. Например, вы можете использовать `avgForEachIf` так же как `avgIfForEach` агрегатные функции, которые имеют различное поведение. -- То `-ForEach` комбинатор агрегатных функций расширен для случая агрегатных функций с несколькими аргументами. -- Добавлена поддержка агрегатных функций `Nullable` аргументы даже в тех случаях, когда функция возвращает не --`Nullable` результат (добавлено с вкладом Сильвиу Карагеа). Пример: `groupArray`, `groupUniqArray`, `topK`. -- Добавил тот `max_client_network_bandwidth` для `clickhouse-client` (Кирилл Шваков). -- Пользователи с помощью `readonly = 2` setting are allowed to work with TEMPORARY tables (CREATE, DROP, INSERT…) (Kirill Shvakov). -- Добавлена поддержка использования нескольких потребителей с помощью `Kafka` двигатель. Расширенные параметры конфигурации для `Kafka` (Marek Vavruša). -- Добавил тот `intExp3` и `intExp4` функции. -- Добавил тот `sumKahan` статистическая функция. -- Добавлены функции to \* Number\* OrNull, где \* Number\* - это числовой тип. -- Добавлена поддержка для `WITH` положения для `INSERT SELECT` запрос (автор: zhang2014). -- Добавлены настройки: `http_connection_timeout`, `http_send_timeout`, `http_receive_timeout`. В частности, эти параметры используются для загрузки частей данных для репликации. Изменение этих параметров позволяет ускорить отработку отказа при перегрузке сети. -- Добавлена поддержка для `ALTER` для таблиц типа `Null` (Анастасия Царькова). -- То `reinterpretAsString` функция расширена для всех типов данных, которые хранятся последовательно в памяти. -- Добавил тот `--silent` вариант для самого `clickhouse-local` инструмент. Он подавляет печать информации о выполнении запроса в stderr. -- Добавлена поддержка считывания значений типа `Date` из текста в формате, где месяц и / или день месяца указывается с использованием одной цифры вместо двух цифр (Amos Bird). - -#### Оптимизация производительности: {#performance-optimizations} - -- Улучшена производительность агрегатных функций `min`, `max`, `any`, `anyLast`, `anyHeavy`, `argMin`, `argMax` из строковых аргументов. -- Улучшенная производительность функций `isInfinite`, `isFinite`, `isNaN`, `roundToExp2`. -- Улучшена производительность синтаксического анализа и форматирования `Date` и `DateTime` введите значения в текстовом формате. -- Улучшена производительность и точность синтаксического анализа чисел с плавающей запятой. -- Пониженное использование памяти для `JOIN` в том случае, когда левая и правая части имеют столбцы с одинаковыми именами, которые не содержатся в `USING` . -- Улучшена производительность агрегатных функций `varSamp`, `varPop`, `stddevSamp`, `stddevPop`, `covarSamp`, `covarPop`, `corr` за счет снижения вычислительной стабильности. Старые функции доступны под названиями `varSampStable`, `varPopStable`, `stddevSampStable`, `stddevPopStable`, `covarSampStable`, `covarPopStable`, `corrStable`. - -#### Устранение ошибок: {#bug-fixes-28} - -- Исправлена дедупликация данных после запуска a `DROP` или `DETACH PARTITION` запрос. В предыдущей версии удаление раздела и вставка тех же данных снова не работали, потому что вставленные блоки считались дубликатами. -- Исправлена ошибка, которая могла привести к неправильной интерпретации текста. `WHERE` пунктом `CREATE MATERIALIZED VIEW` запросы с помощью `POPULATE` . -- Исправлена ошибка в использовании `root_path` параметр в поле `zookeeper_servers` конфигурация. -- Исправлены непредвиденные результаты прохождения теста `Date` аргумент в пользу `toStartOfDay` . -- Исправлена ошибка `addMonths` и `subtractMonths` функции и арифметика для `INTERVAL n MONTH` в тех случаях, когда результат имеет предыдущий год. -- Добавлена отсутствующая поддержка для `UUID` тип данных для `DISTINCT` , `JOIN` , и `uniq` агрегатные функции и внешние словари (Евгений Иванов). Поддержка `UUID` он все еще не завершен. -- Исправлено `SummingMergeTree` поведение в тех случаях, когда строки суммируются до нуля. -- Различные исправления для `Kafka` engine (Marek Vavruša). -- Исправлено некорректное поведение устройства `Join` настольный движок (птица Амос). -- Исправлено некорректное поведение распределителя под FreeBSD и OS X. -- То `extractAll` функция теперь поддерживает пустые матчи. -- Исправлена ошибка, которая блокировала использование `libressl` вместо `openssl` . -- Исправлена ошибка `CREATE TABLE AS SELECT` запрос из временных таблиц. -- Исправлена неатомность обновления очереди репликации. Это может привести к тому, что реплики будут несинхронизированы до тех пор, пока сервер не перезагрузится. -- Исправлено возможное переполнение внутри `gcd` , `lcm` и `modulo` (`%` оператор) (Макс Скороход). -- `-preprocessed` файлы теперь создаются после изменения `umask` (`umask` можно изменить в конфигурации). -- Исправлена ошибка в фоновой проверке деталей (`MergeTreePartChecker` ) при использовании пользовательского ключа раздела. -- Исправлен разбор кортежей (значения `Tuple` тип данных) в текстовых форматах. -- Улучшены сообщения об ошибках о несовместимых типах, передаваемых в `multiIf` , `array` и некоторые другие функции. -- Переработанная поддержка для `Nullable` типы. Исправлены ошибки, которые могут привести к сбою сервера. Исправлены почти все другие ошибки, связанные с `NULL` поддержка: некорректное преобразование типов в вставьте выберите, недостаточная поддержка значения NULL в наличии и PREWHERE, `join_use_nulls` режим, типы, допускающие значения NULL в качестве аргументов `OR` оператор и т. д. -- Исправлены различные ошибки, связанные с внутренней семантикой типов данных. Примеры: ненужное суммирование `Enum` поля, тип в `SummingMergeTree` ; выравнивание `Enum` напечатать `Pretty` форматы и т. д. -- Более строгие проверки допустимых комбинаций составных столбцов. -- Исправлено переполнение при указании очень большого параметра для `FixedString` тип данных. -- Исправлена ошибка в системе `topK` агрегатная функция в общем случае. -- Добавлена недостающая проверка на равенство размеров массива в аргументах n-арных вариантов агрегатных функций с АНА - `-Array` комбинатор. -- Исправлена ошибка в работе `--pager` для `clickhouse-client` (автор: кс1322). -- Исправлена точность установки `exp10` функция. -- Исправлено поведение объекта `visitParamExtract` функция для лучшего соответствия документации. -- Исправлена ошибка при указании неверных типов данных. -- Исправлено поведение `DISTINCT` в том случае, когда все столбцы являются константами. -- Исправлено форматирование запроса в случае использования `tupleElement` функция со сложным постоянным выражением в качестве индекса элемента кортежа. -- Исправлена ошибка в работе `Dictionary` таблицы для `range_hashed` словари. -- Исправлена ошибка, приводившая к избыточным строкам в результате `FULL` и `RIGHT JOIN` (Эймос Берд). -- Исправлен сбой сервера при создании и удалении временных файлов в системе `config.d` каталоги во время перезагрузки конфигурации. -- Исправлена ошибка `SYSTEM DROP DNS CACHE` запрос: Кэш был очищен, но адреса узлов кластера не были обновлены. -- Исправлено поведение `MATERIALIZED VIEW` после выполнения `DETACH TABLE` for the table under the view (Marek Vavruša). - -#### Улучшения сборки: {#build-improvements-4} - -- То `pbuilder` инструмент используется для сборки. Процесс сборки практически полностью независим от среды узла сборки. -- Одна сборка используется для разных версий ОС. Пакеты и двоичные файлы были сделаны совместимыми с широким спектром систем Linux. -- Добавил тот `clickhouse-test` пакет. Он может быть использован для выполнения функциональных тестов. -- Исходный тарбол теперь можно опубликовать в репозитории. Он может быть использован для воспроизведения сборки без использования GitHub. -- Добавлена ограниченная интеграция с Travis CI. Из-за ограничений на время сборки в Travis тестируется только отладочная сборка и выполняется ограниченное подмножество тестов. -- Добавлена поддержка для `Cap'n'Proto` в сборке по умолчанию. -- Изменен формат источников документации с `Restricted Text` к `Markdown`. -- Добавлена поддержка для `systemd` (Владимир Смирнов). Он отключен по умолчанию из-за несовместимости с некоторыми образами ОС и может быть включен вручную. -- Для динамической генерации кода, `clang` и `lld` они встроены в систему `clickhouse` двоичный. Они также могут быть вызваны как `clickhouse clang` и `clickhouse lld` . -- Удалено использование расширений GNU из кода. Включил эту функцию `-Wextra` вариант. При строительстве с помощью `clang` значение по умолчанию равно `libc++` вместо `libstdc++`. -- Извлеченный `clickhouse_parsers` и `clickhouse_common_io` библиотеки для ускорения сборки различных инструментов. - -#### Назад несовместимые изменения: {#backward-incompatible-changes-11} - -- Формат для отметок в `Log` введите таблицы, которые содержат `Nullable` колонны были изменены обратно несовместимым образом. Если у вас есть эти таблицы, вы должны преобразовать их в следующие: `TinyLog` введите текст перед запуском новой версии сервера. Чтобы сделать это, замените `ENGINE = Log` с `ENGINE = TinyLog` в соответствующем разделе `.sql` файл в папке `metadata` каталог. Если ваш стол не имеет `Nullable` столбцы или если тип вашей таблицы не указан `Log`- тогда вам ничего не нужно делать. -- Удалил то `experimental_allow_extended_storage_definition_syntax` установка. Теперь эта функция включена по умолчанию. -- То `runningIncome` функция была переименована в `runningDifferenceStartingWithFirstvalue` избежать недоразумений. -- Удалил то `FROM ARRAY JOIN arr` синтаксис, когда соединение массива задается непосредственно после FROM без таблицы (Amos Bird). -- Удалил то `BlockTabSeparated` формат, который использовался исключительно в демонстрационных целях. -- Изменен формат состояния для агрегатных функций `varSamp`, `varPop`, `stddevSamp`, `stddevPop`, `covarSamp`, `covarPop`, `corr`. Если вы сохранили состояния этих агрегатных функций в таблицах (с помощью `AggregateFunction` тип данных или материализованные представления с соответствующими состояниями), пожалуйста, напишите нам clickhouse-feedback@yandex-team.com-да. -- В предыдущих версиях сервера существовала недокументированная функция: если агрегатная функция зависит от параметров, то вы все равно можете указать ее без параметров в типе данных AggregateFunction. Пример: `AggregateFunction(quantiles, UInt64)` вместо `AggregateFunction(quantiles(0.5, 0.9), UInt64)`. Эта особенность была утеряна. Хотя он был недокументирован, мы планируем снова поддержать его в будущих выпусках. -- Типы данных Enum не могут использоваться в агрегатных функциях min/max. Эта способность будет возвращена в следующем выпуске. - -#### Пожалуйста, обратите внимание при обновлении: {#please-note-when-upgrading} - -- При выполнении скользящего обновления в кластере в тот момент, когда некоторые реплики работают под управлением старой версии ClickHouse, а некоторые-под управлением новой версии, репликация временно прекращается и появляется сообщение `unknown parameter 'shard'` появляется в журнале регистрации. Репликация будет продолжена после обновления всех реплик кластера. -- Если на серверах кластера запущены разные версии ClickHouse, то вполне возможно, что распределенные запросы, использующие следующие функции, будут иметь неверные результаты: `varSamp`, `varPop`, `stddevSamp`, `stddevPop`, `covarSamp`, `covarPop`, `corr`. Вы должны обновить все узлы кластера. - -## [Список изменений на 2017 год](https://github.com/ClickHouse/ClickHouse/blob/master/docs/en/changelog/2017.md) {#changelog-for-2017} diff --git a/docs/ru/whats_new/changelog/2018.md b/docs/ru/whats_new/changelog/2018.md new file mode 120000 index 00000000000..675c07e8bbb --- /dev/null +++ b/docs/ru/whats_new/changelog/2018.md @@ -0,0 +1 @@ +en/whats_new/changelog/2018.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2019.md b/docs/ru/whats_new/changelog/2019.md deleted file mode 100644 index ea5bffd74c9..00000000000 --- a/docs/ru/whats_new/changelog/2019.md +++ /dev/null @@ -1,2072 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -## Релиз ClickHouse в19.17 {#clickhouse-release-v19-17} - -### Релиз ClickHouse в19.17.6.36, 2019-12-27 {#clickhouse-release-v19-17-6-36-2019-12-27} - -#### Исправление ошибок {#bug-fix} - -- Исправлено потенциальное переполнение буфера при распаковке. Злонамеренный пользователь может передавать сфабрикованные сжатые данные,которые могут вызвать чтение после буфера. Эту проблему обнаружил Эльдар Зайтов из команды информационной безопасности Яндекса. [\#8404](https://github.com/ClickHouse/ClickHouse/pull/8404) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена возможная ошибка сервера (`std::terminate`) когда сервер не может отправлять или записывать данные в формате JSON или XML со значениями строкового типа данных (которые требуют проверки UTF-8) или при сжатии результирующих данных с помощью алгоритма Brotli или в некоторых других редких случаях. [\#8384](https://github.com/ClickHouse/ClickHouse/pull/8384) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлены словари с исходным кодом из clickhouse `VIEW`, теперь чтение таких словарей не вызывает ошибки `There is no query`. [\#8351](https://github.com/ClickHouse/ClickHouse/pull/8351) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлена проверка, разрешен ли клиентский хост с помощью host\_regexp, указанного в users.XML. [\#8241](https://github.com/ClickHouse/ClickHouse/pull/8241), [\#8342](https://github.com/ClickHouse/ClickHouse/pull/8342) ([Виталий Баранов](https://github.com/vitlibar)) -- `RENAME TABLE` для распределенной таблицы теперь переименовывается папка, содержащая вставленные данные перед отправкой в сегменты. Это исправляет проблему с последовательными переименованиями `tableA->tableB`, `tableC->tableA`. [\#8306](https://github.com/ClickHouse/ClickHouse/pull/8306) ([тавплубикс](https://github.com/tavplubix)) -- `range_hashed` внешние словари, созданные запросами DDL, теперь допускают диапазоны произвольных числовых типов. [\#8275](https://github.com/ClickHouse/ClickHouse/pull/8275) ([алесапин](https://github.com/alesapin)) -- Исправлено `INSERT INTO table SELECT ... FROM mysql(...)` табличная функция. [\#8234](https://github.com/ClickHouse/ClickHouse/pull/8234) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена обработка выхода онлайн / оффлайн в `INSERT INTO TABLE FUNCTION file()` при вставке в файл, который не существует. Теперь в этом случае файл будет создан, а затем вставка будет обработана. [\#8177](https://github.com/ClickHouse/ClickHouse/pull/8177) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Исправлена ошибка bitmapAnd при пересечении агрегированного растрового изображения и скалярного растрового изображения. [\#8082](https://github.com/ClickHouse/ClickHouse/pull/8082) ([Юе Хуанг](https://github.com/moon03432)) -- Исправлена обработка выхода онлайн / оффлайн, когда `EXISTS` запрос был использован без `TABLE` или `DICTIONARY` квалификатор, совсем как `EXISTS t`. [\#8213](https://github.com/ClickHouse/ClickHouse/pull/8213) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Фиксированный тип возврата для функций `rand` и `randConstant` в случае ничтожного аргумента. Теперь функции всегда возвращаются `UInt32` и никогда `Nullable(UInt32)`. [\#8204](https://github.com/ClickHouse/ClickHouse/pull/8204) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлено `DROP DICTIONARY IF EXISTS db.dict`, теперь он не бросает исключение, если `db` его просто не существует. [\#8185](https://github.com/ClickHouse/ClickHouse/pull/8185) ([Виталий Баранов](https://github.com/vitlibar)) -- Если таблица не была полностью удалена из-за сбоя сервера, сервер попытается восстановить и загрузить ее [\#8176](https://github.com/ClickHouse/ClickHouse/pull/8176) ([тавплубикс](https://github.com/tavplubix)) -- Исправлен тривиальный запрос count для распределенной таблицы, если существует более двух локальных таблиц shard. [\#8164](https://github.com/ClickHouse/ClickHouse/pull/8164) ([小路](https://github.com/nicelulu)) -- Исправлена ошибка, приводившая к гонке данных в DB:: BlockStreamProfileInfo:: calculateRowsBeforeLimit() [\#8143](https://github.com/ClickHouse/ClickHouse/pull/8143) ([Александр казаков](https://github.com/Akazz)) -- Исправлено `ALTER table MOVE part` выполняется сразу же после слияния указанной детали, что может привести к перемещению детали, в которую данная деталь была объединена. Теперь он правильно перемещает указанную деталь. [\#8104](https://github.com/ClickHouse/ClickHouse/pull/8104) ([Владимир Чеботарев](https://github.com/excitoon)) -- Теперь выражения для словарей можно задавать в виде строк. Это полезно для вычисления атрибутов при извлечении данных из источников, отличных от ClickHouse, поскольку позволяет использовать синтаксис, отличающийся от ClickHouse, для этих выражений. [\#8098](https://github.com/ClickHouse/ClickHouse/pull/8098) ([алесапин](https://github.com/alesapin)) -- Исправлена очень редкая гонка в `clickhouse-copier` из-за переполнения в ZXid. [\#8088](https://github.com/ClickHouse/ClickHouse/pull/8088) ([Дин Сян Фэй](https://github.com/dingxiangfei2009)) -- Исправлена ошибка, когда после неудачного запроса (из-за «Too many simultaneous queries» например) он не будет читать информацию о внешних таблицах, а также - следующий запрос будет интерпретировать эту информацию как начало следующего запроса, вызывающего ошибку типа `Unknown packet from client`. [\#8084](https://github.com/ClickHouse/ClickHouse/pull/8084) ([Азат Хужин](https://github.com/azat)) -- Избежать разыменования null после «Unknown packet X from server» [\#8071](https://github.com/ClickHouse/ClickHouse/pull/8071) ([Азат Хужин](https://github.com/azat)) -- Восстановите поддержку всех локалей ICU, добавьте возможность применять параметры сортировки для постоянных выражений и добавьте имя языка в систему.таблица сортировки. [\#8051](https://github.com/ClickHouse/ClickHouse/pull/8051) ([алесапин](https://github.com/alesapin)) -- Количество потоков для чтения из `StorageFile` и `StorageHDFS` теперь он ограничен, чтобы не превысить лимит памяти. [\#7981](https://github.com/ClickHouse/ClickHouse/pull/7981) ([алесапин](https://github.com/alesapin)) -- Исправлено `CHECK TABLE` запрос для `*MergeTree` таблицы без ключа. [\#7979](https://github.com/ClickHouse/ClickHouse/pull/7979) ([алесапин](https://github.com/alesapin)) -- Удалил номер мутации из имени детали на тот случай, если мутаций не было. Это удаление улучшило совместимость с более старыми версиями. [\#8250](https://github.com/ClickHouse/ClickHouse/pull/8250) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка, что мутации пропускаются для некоторых присоединенных частей из-за их data\_version больше, чем версия мутации таблицы. [\#7812](https://github.com/ClickHouse/ClickHouse/pull/7812) ([Zhichang Ю](https://github.com/yuzhichang)) -- Разрешить запуск сервера с избыточными копиями деталей после их перемещения на другое устройство. [\#7810](https://github.com/ClickHouse/ClickHouse/pull/7810) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправлена ошибка «Sizes of columns doesn’t match» это может появиться при использовании столбцов агрегатной функции. [\#7790](https://github.com/ClickHouse/ClickHouse/pull/7790) ([Борис Гранво](https://github.com/bgranvea)) -- Теперь исключение будет сделано в случае использования с привязками рядом с LIMIT BY. И теперь его можно использовать сверху предел. [\#7637](https://github.com/ClickHouse/ClickHouse/pull/7637) ([Никита Михайлов](https://github.com/nikitamikhaylov)) -- Исправьте перезагрузку словаря, если она есть `invalidate_query`, который остановил обновления и некоторые исключения при предыдущих попытках обновления. [\#8029](https://github.com/ClickHouse/ClickHouse/pull/8029) ([алесапин](https://github.com/alesapin)) - -### Релиз ClickHouse в19.17.4.11, 2019-11-22 {#clickhouse-release-v19-17-4-11-2019-11-22} - -#### Назад Несовместимые Изменения {#backward-incompatible-change} - -- Использование столбца вместо AST для хранения скалярных результатов подзапросов для повышения производительности. Установка `enable_scalar_subquery_optimization` был добавлен в 19.17, и он был включен по умолчанию. Это приводит к таким ошибкам, как [этот](https://github.com/ClickHouse/ClickHouse/issues/7851) во время обновления до 19.17.2 или 19.17.3 с предыдущих версий. Этот параметр был отключен по умолчанию в 19.17.4, чтобы сделать возможным обновление с 19.16 и более старых версий без ошибок. [\#7392](https://github.com/ClickHouse/ClickHouse/pull/7392) ([Амос Птица](https://github.com/amosbird)) - -#### Новая функция {#new-feature} - -- Добавьте возможность создавать словари с запросами DDL. [\#7360](https://github.com/ClickHouse/ClickHouse/pull/7360) ([алесапин](https://github.com/alesapin)) -- Сделай `bloom_filter` тип поддержки индекса `LowCardinality` и `Nullable` [\#7363](https://github.com/ClickHouse/ClickHouse/issues/7363) [\#7561](https://github.com/ClickHouse/ClickHouse/pull/7561) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Функция add `isValidJSON` чтобы проверить, что переданная строка является допустимым json. [\#5910](https://github.com/ClickHouse/ClickHouse/issues/5910) [\#7293](https://github.com/ClickHouse/ClickHouse/pull/7293) ([Вдимир](https://github.com/Vdimir)) -- Осуществлять `arrayCompact` функция [\#7328](https://github.com/ClickHouse/ClickHouse/pull/7328) ([Меморандум](https://github.com/Joeywzr)) -- Созданная функция `hex` для десятичных чисел. Это работает так `hex(reinterpretAsString())`, но не удаляет последние нулевые байты. [\#7355](https://github.com/ClickHouse/ClickHouse/pull/7355) ([Михаил Коротов](https://github.com/millb)) -- Добавь `arrayFill` и `arrayReverseFill` функции, которые заменяют элементы другими элементами спереди/сзади от них в массиве. [\#7380](https://github.com/ClickHouse/ClickHouse/pull/7380) ([hcz](https://github.com/hczhcz)) -- Добавь `CRC32IEEE()`/`CRC64()` поддержка [\#7480](https://github.com/ClickHouse/ClickHouse/pull/7480) ([Азат Хужин](https://github.com/azat)) -- Осуществлять `char` функция, аналогичная одной в [в MySQL](https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_char) [\#7486](https://github.com/ClickHouse/ClickHouse/pull/7486) ([сундили](https://github.com/sundy-li)) -- Добавь `bitmapTransform` функция. Он преобразует массив значений в растровом изображении в другой массив значений, в результате чего получается новое растровое изображение [\#7598](https://github.com/ClickHouse/ClickHouse/pull/7598) ([Zhichang Ю](https://github.com/yuzhichang)) -- Реализованный `javaHashUTF16LE()` функция [\#7651](https://github.com/ClickHouse/ClickHouse/pull/7651) ([ачимбаб](https://github.com/achimbab)) -- Добавь `_shard_num` виртуальный столбец для распределенного движка [\#7624](https://github.com/ClickHouse/ClickHouse/pull/7624) ([Азат Хужин](https://github.com/azat)) - -#### Экспериментальная возможность {#experimental-feature} - -- Поддержка процессоров (новый конвейер выполнения запросов) в `MergeTree`. [\#7181](https://github.com/ClickHouse/ClickHouse/pull/7181) ([Николай Кочетов](https://github.com/KochetovNicolai)) - -#### Исправление ошибок {#bug-fix-1} - -- Исправить неправильный парсинг float в `Values` [\#7817](https://github.com/ClickHouse/ClickHouse/issues/7817) [\#7870](https://github.com/ClickHouse/ClickHouse/pull/7870) ([тавплубикс](https://github.com/tavplubix)) -- Исправьте редкий тупик, который может произойти, когда trace\_log включен. [\#7838](https://github.com/ClickHouse/ClickHouse/pull/7838) ([Филимонов](https://github.com/filimonov)) -- Предотвратите дублирование сообщений при создании таблицы Кафки, в которой есть любой MVs, выбирающий из нее [\#7265](https://github.com/ClickHouse/ClickHouse/pull/7265) ([Иван](https://github.com/abyss7)) -- Поддержка `Array(LowCardinality(Nullable(String)))` в `IN`. Разрешает [\#7364](https://github.com/ClickHouse/ClickHouse/issues/7364) [\#7366](https://github.com/ClickHouse/ClickHouse/pull/7366) ([ачимбаб](https://github.com/achimbab)) -- Добавить обработку данных `SQL_TINYINT` и `SQL_BIGINT`, и исправьте обработку `SQL_FLOAT` типы источников данных в ODBC мост. [\#7491](https://github.com/ClickHouse/ClickHouse/pull/7491) ([Денис Глазачев](https://github.com/traceon)) -- Исправить агрегации (`avg` и квантили) над пустыми десятичными столбцами [\#7431](https://github.com/ClickHouse/ClickHouse/pull/7431) ([Андрей Коняев](https://github.com/akonyaev90)) -- Чинить `INSERT` в распределенный с `MATERIALIZED` столбцы [\#7377](https://github.com/ClickHouse/ClickHouse/pull/7377) ([Азат Хужин](https://github.com/azat)) -- Сделай `MOVE PARTITION` работайте, если некоторые части раздела уже находятся на целевом диске или томе [\#7434](https://github.com/ClickHouse/ClickHouse/pull/7434) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправлена ошибка, из-за которой жесткие ссылки не создавались во время мутаций в `ReplicatedMergeTree` в конфигурациях с несколькими дисками. [\#7558](https://github.com/ClickHouse/ClickHouse/pull/7558) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправлена ошибка с мутацией на MergeTree, когда вся часть остается неизменной, а лучшее место находится на другом диске [\#7602](https://github.com/ClickHouse/ClickHouse/pull/7602) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправлена ошибка с `keep_free_space_ratio` не считывается с конфигурации дисков [\#7645](https://github.com/ClickHouse/ClickHouse/pull/7645) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправлена ошибка с таблицей содержит только `Tuple` столбцы или столбцы со сложными путями. Исправления [7541](https://github.com/ClickHouse/ClickHouse/issues/7541). [\#7545](https://github.com/ClickHouse/ClickHouse/pull/7545) ([алесапин](https://github.com/alesapin)) -- Не учитывайте память для буферного движка в ограничении max\_memory\_usage [\#7552](https://github.com/ClickHouse/ClickHouse/pull/7552) ([Азат Хужин](https://github.com/azat)) -- Исправлена окончательная отметка использования в `MergeTree` таблицы, заказанные по `tuple()`. В редких случаях это может привести к тому, что `Can't adjust last granule` ошибка при выборе. [\#7639](https://github.com/ClickHouse/ClickHouse/pull/7639) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена ошибка в мутациях, которые имеют предикат с действиями, требующими контекста (например, функции для json), что может привести к сбоям или странным исключениям. [\#7664](https://github.com/ClickHouse/ClickHouse/pull/7664) ([алесапин](https://github.com/alesapin)) -- Исправлено несоответствие экранирования имен баз данных и таблиц `data/` и `shadow/` справочники [\#7575](https://github.com/ClickHouse/ClickHouse/pull/7575) ([Александр Бурмак](https://github.com/Alex-Burmak)) -- Support duplicated keys in RIGHT\|FULL JOINs, e.g. `ON t.x = u.x AND t.x = u.y`. Исправьте сбой в этом случае. [\#7586](https://github.com/ClickHouse/ClickHouse/pull/7586) ([Артем Зуйков](https://github.com/4ertus2)) -- Чинить `Not found column in block` при соединении по выражению с правым или полным соединением. [\#7641](https://github.com/ClickHouse/ClickHouse/pull/7641) ([Артем Зуйков](https://github.com/4ertus2)) -- Еще одна попытка исправить бесконечный цикл в `PrettySpace` формат [\#7591](https://github.com/ClickHouse/ClickHouse/pull/7591) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Исправлена ошибка в работе `concat` функция, когда все аргументы были `FixedString` такого же размера. [\#7635](https://github.com/ClickHouse/ClickHouse/pull/7635) ([алесапин](https://github.com/alesapin)) -- Исправлено исключение в случае использования 1 аргумента при определении хранилищ S3, URL и HDFS. [\#7618](https://github.com/ClickHouse/ClickHouse/pull/7618) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправлена область действия InterpreterSelectQuery для представлений с запросом [\#7601](https://github.com/ClickHouse/ClickHouse/pull/7601) ([Азат Хужин](https://github.com/azat)) - -#### Улучшение {#improvement} - -- `Nullable` столбцы признал и NULL-значения будут корректно обработаны в ODBC-мост [\#7402](https://github.com/ClickHouse/ClickHouse/pull/7402) ([Василий Немков](https://github.com/Enmk)) -- Напишите текущий пакет для распределенной отправки атомарно [\#7600](https://github.com/ClickHouse/ClickHouse/pull/7600) ([Азат Хужин](https://github.com/azat)) -- Вызовите исключение, если мы не можем обнаружить таблицу для имени столбца в запросе. [\#7358](https://github.com/ClickHouse/ClickHouse/pull/7358) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавь `merge_max_block_size` установка `MergeTreeSettings` [\#7412](https://github.com/ClickHouse/ClickHouse/pull/7412) ([Артем Зуйков](https://github.com/4ertus2)) -- Запросы с помощью `HAVING` и без него `GROUP BY` предположим, что группа по константе. Так, `SELECT 1 HAVING 1` теперь возвращает результат. [\#7496](https://github.com/ClickHouse/ClickHouse/pull/7496) ([Амос Птица](https://github.com/amosbird)) -- Поддержка синтаксического анализа `(X,)` как Кортеж похож на python. [\#7501](https://github.com/ClickHouse/ClickHouse/pull/7501), [\#7562](https://github.com/ClickHouse/ClickHouse/pull/7562) ([Амос Птица](https://github.com/amosbird)) -- Сделай `range` функциональное поведение почти как у питона. [\#7518](https://github.com/ClickHouse/ClickHouse/pull/7518) ([сундили](https://github.com/sundy-li)) -- Добавь `constraints` столбцы в таблицу `system.settings` [\#7553](https://github.com/ClickHouse/ClickHouse/pull/7553) ([Виталий Баранов](https://github.com/vitlibar)) -- Лучший нулевой формат для обработчика tcp, так что его можно использовать `select ignore() from table format Null` для измерения производительности через clickhouse-клиент [\#7606](https://github.com/ClickHouse/ClickHouse/pull/7606) ([Амос Птица](https://github.com/amosbird)) -- Такие запросы, как `CREATE TABLE ... AS (SELECT (1, 2))` разбираются правильно [\#7542](https://github.com/ClickHouse/ClickHouse/pull/7542) ([hcz](https://github.com/hczhcz)) - -#### Улучшение производительности {#performance-improvement} - -- Улучшена производительность агрегирования по коротким строковым ключам. [\#6243](https://github.com/ClickHouse/ClickHouse/pull/6243) ([Александр Кузьменков](https://github.com/akuzm), [Амос Птица](https://github.com/amosbird)) -- Выполните еще один проход синтаксического анализа / анализа выражений, чтобы получить потенциальную оптимизацию после того, как постоянные предикаты будут свернуты. [\#7497](https://github.com/ClickHouse/ClickHouse/pull/7497) ([Амос Птица](https://github.com/amosbird)) -- Использовать для хранения мета-информации, чтобы оценить тривиально `SELECT count() FROM table;` [\#7510](https://github.com/ClickHouse/ClickHouse/pull/7510) ([Амос Птица](https://github.com/amosbird), [Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Векторизация обработки `arrayReduce` аналогично агрегатору `addBatch`. [\#7608](https://github.com/ClickHouse/ClickHouse/pull/7608) ([Амос Птица](https://github.com/amosbird)) -- Незначительные улучшения в производительности `Kafka` потребление [\#7475](https://github.com/ClickHouse/ClickHouse/pull/7475) ([Иван](https://github.com/abyss7)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement} - -- Добавьте поддержку кросс-компиляции в архитектуру процессора AARCH64. Сценарий рефакторинга упаковщика. [\#7370](https://github.com/ClickHouse/ClickHouse/pull/7370) [\#7539](https://github.com/ClickHouse/ClickHouse/pull/7539) ([Иван](https://github.com/abyss7)) -- Распакуйте цепочки инструментов darwin-x86\_64 и linux-aarch64 в смонтированный том Docker при сборке пакетов [\#7534](https://github.com/ClickHouse/ClickHouse/pull/7534) ([Иван](https://github.com/abyss7)) -- Обновление образа Docker для двоичного упаковщика [\#7474](https://github.com/ClickHouse/ClickHouse/pull/7474) ([Иван](https://github.com/abyss7)) -- Исправлены ошибки компиляции на MacOS Catalina [\#7585](https://github.com/ClickHouse/ClickHouse/pull/7585) ([Эрнест Полетаев](https://github.com/ernestp)) -- Некоторые рефакторинги в логике анализа запросов: разделение сложного класса на несколько простых. [\#7454](https://github.com/ClickHouse/ClickHouse/pull/7454) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена сборка без подмодулей [\#7295](https://github.com/ClickHouse/ClickHouse/pull/7295) ([proller](https://github.com/proller)) -- Лучше `add_globs` в файлах CMake [\#7418](https://github.com/ClickHouse/ClickHouse/pull/7418) ([Амос Птица](https://github.com/amosbird)) -- Удалить жестко закодированные пути в `unwind` цель [\#7460](https://github.com/ClickHouse/ClickHouse/pull/7460) ([Константин Подшумок](https://github.com/podshumok)) -- Разрешить использовать формат mysql без ssl [\#7524](https://github.com/ClickHouse/ClickHouse/pull/7524) ([proller](https://github.com/proller)) - -#### Другой {#other} - -- Добавлена грамматика ANTLR4 для диалекта ClickHouse SQL [\#7595](https://github.com/ClickHouse/ClickHouse/issues/7595) [\#7596](https://github.com/ClickHouse/ClickHouse/pull/7596) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -## Релиз ClickHouse в19.16 {#clickhouse-release-v19-16} - -#### Релиз Clickhouse в19.16.14.65, 2020-03-25 {#clickhouse-release-v19-16-14-65-2020-03-25} - -- Исправлена ошибка в пакетных вычислениях тернарных логических операций по нескольким аргументам (более 10). [\#8718](https://github.com/ClickHouse/ClickHouse/pull/8718) ([Александр казаков](https://github.com/Akazz)) Это исправление было возвращено в версию 19.16 по специальному запросу Altinity. - -#### Релиз Clickhouse в19.16.14.65, 2020-03-05 {#clickhouse-release-v19-16-14-65-2020-03-05} - -- Исправлена несовместимость распределенных подзапросов с более старыми версиями CH. Исправления [\#7851](https://github.com/ClickHouse/ClickHouse/issues/7851) - [(tabplubix)](https://github.com/tavplubix) -- При выполнении `CREATE` запрос, сложите постоянные выражения в аргументах механизма хранения. Замените пустое имя базы данных текущей базой данных. Исправления [\#6508](https://github.com/ClickHouse/ClickHouse/issues/6508), [\#3492](https://github.com/ClickHouse/ClickHouse/issues/3492). Также исправлена проверка наличия локального адреса в системе `ClickHouseDictionarySource`. - [\#9262](https://github.com/ClickHouse/ClickHouse/pull/9262) [(tabplubix)](https://github.com/tavplubix) -- Теперь фон сливается воедино `*MergeTree` семейство движков таблиц более точно сохраняет порядок объема политики хранения. - [\#8549](https://github.com/ClickHouse/ClickHouse/pull/8549) ([Владимир Чеботарев](https://github.com/excitoon)) -- Предотвращение потери данных в `Kafka` в редких случаях, когда исключение происходит после чтения суффикса, но до фиксации. Исправления [\#9378](https://github.com/ClickHouse/ClickHouse/issues/9378). Связанный: [\#7175](https://github.com/ClickHouse/ClickHouse/issues/7175) - [\#9507](https://github.com/ClickHouse/ClickHouse/pull/9507) [(Филимонов)](https://github.com/filimonov) -- Исправлена ошибка, приводящая к завершению работы сервера при попытке использовать / drop `Kafka` таблица создана с неверными параметрами. Исправления [\#9494](https://github.com/ClickHouse/ClickHouse/issues/9494). Включает [\#9507](https://github.com/ClickHouse/ClickHouse/issues/9507). - [\#9513](https://github.com/ClickHouse/ClickHouse/pull/9513) [(Филимонов)](https://github.com/filimonov) -- Разрешить использование `MaterializedView` с подзапросами выше `Kafka` таблицы. - [\#8197](https://github.com/ClickHouse/ClickHouse/pull/8197) ([Филимонов](https://github.com/filimonov)) - -#### Новая функция {#new-feature-1} - -- Добавь `deduplicate_blocks_in_dependent_materialized_views` возможность управления поведением идемпотентных вставок в таблицы с материализованными представлениями. Эта новая функция была добавлена в релиз исправления ошибок по специальному запросу от Altinity. - [\#9070](https://github.com/ClickHouse/ClickHouse/pull/9070) [(урыхи)](https://github.com/urykhy) - -### Релиз ClickHouse в19.16.2.2, 2019-10-30 {#clickhouse-release-v19-16-2-2-2019-10-30} - -#### Назад Несовместимые Изменения {#backward-incompatible-change-1} - -- Добавьте недостающую проверку arity для count/countif. - [\#7095](https://github.com/ClickHouse/ClickHouse/issues/7095) - [\#7298](https://github.com/ClickHouse/ClickHouse/pull/7298) ([Вдимир](https://github.com/Vdimir)) -- Удаление устаревших `asterisk_left_columns_only` настройка (по умолчанию она была отключена). - [\#7335](https://github.com/ClickHouse/ClickHouse/pull/7335) ([Артем - Зуйков](https://github.com/4ertus2)) -- Строки формата для формата данных шаблона теперь задаются в файлах. - [\#7118](https://github.com/ClickHouse/ClickHouse/pull/7118) - ([тавплубикс](https://github.com/tavplubix)) - -#### Новая функция {#new-feature-2} - -- Введите uniqCombined64 () для вычисления мощности, большей, чем UINT\_MAX. - [\#7213](https://github.com/ClickHouse/ClickHouse/pull/7213), - [\#7222](https://github.com/ClickHouse/ClickHouse/pull/7222) ([Азат - Хужин](https://github.com/azat)) -- Поддержка индексов Bloom filter для столбцов массива. - [\#6984](https://github.com/ClickHouse/ClickHouse/pull/6984) - ([ачимбаб](https://github.com/achimbab)) -- Добавление функции `getMacro(name)` это возвращает строку со значением соответствующего `` - из конфигурации сервера. [\#7240](https://github.com/ClickHouse/ClickHouse/pull/7240) - ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Установите два параметра конфигурации для словаря, основанного на источнике HTTP: `credentials` и - `http-headers`. [\#7092](https://github.com/ClickHouse/ClickHouse/pull/7092) ([Гийом - Тассери](https://github.com/YiuRULE)) -- Добавьте новый ProfileEvent `Merge` это подсчитывает количество запущенных фоновых слияний. - [\#7093](https://github.com/ClickHouse/ClickHouse/pull/7093) ([Михаил - Коротов](https://github.com/millb)) -- Добавьте функцию fullHostName, которая возвращает полное доменное имя. - [\#7263](https://github.com/ClickHouse/ClickHouse/issues/7263) - [\#7291](https://github.com/ClickHouse/ClickHouse/pull/7291) ([сундили](https://github.com/sundy-li)) -- Функция add `arraySplit` и `arrayReverseSplit` которые разделяют массив на «cut off» - условия. Они полезны при обработке временных последовательностей. - [\#7294](https://github.com/ClickHouse/ClickHouse/pull/7294) ([hcz](https://github.com/hczhcz)) -- Добавьте новые функции, возвращающие массив всех сопоставленных индексов в семействе функций multiMatch. - [\#7299](https://github.com/ClickHouse/ClickHouse/pull/7299) ([Данила - Кутенин](https://github.com/danlark1)) -- Добавление нового компонента Database engine `Lazy` то есть оптимизирован для хранения большого количества мелких логов - таблицы. [\#7171](https://github.com/ClickHouse/ClickHouse/pull/7171) ([Никита - Васильев](https://github.com/nikvas0)) -- Добавьте агрегатные функции groupBitmapAnd, - Or, - Xor для растровых столбцов. [\#7109](https://github.com/ClickHouse/ClickHouse/pull/7109) ([Чжичан - Ю](https://github.com/yuzhichang)) -- Добавьте комбинаторы агрегатных функций-OrNull и-OrDefault, которые возвращают значение null - или значения по умолчанию, когда агрегировать нечего. - [\#7331](https://github.com/ClickHouse/ClickHouse/pull/7331) - ([hcz](https://github.com/hczhcz)) -- Представьте пользовательский разделенный формат данных, который поддерживает пользовательское экранирование и - правила разграничения. [\#7118](https://github.com/ClickHouse/ClickHouse/pull/7118) - ([тавплубикс](https://github.com/tavplubix)) -- Поддержка Redis в качестве источника внешнего словаря. [\#4361](https://github.com/ClickHouse/ClickHouse/pull/4361) [\#6962](https://github.com/ClickHouse/ClickHouse/pull/6962) ([comunodi](https://github.com/comunodi), [Антон - Попов](https://github.com/CurtizJ)) - -#### Исправление ошибок {#bug-fix-2} - -- Исправьте неправильный результат запроса, если он есть `WHERE IN (SELECT ...)` раздел и `optimize_read_in_order` является - использованный. [\#7371](https://github.com/ClickHouse/ClickHouse/pull/7371) ([Антон - Попов](https://github.com/CurtizJ)) -- Отключен плагин аутентификации MariaDB, который зависит от файлов вне проекта. - [\#7140](https://github.com/ClickHouse/ClickHouse/pull/7140) ([Юрий Владимирович - Баранов](https://github.com/yurriy)) -- Исправить исключение `Cannot convert column ... because it is constant but values of constants are different in source and result` что редко может произойти, когда функции `now()`, `today()`, - `yesterday()`, `randConstant()` не использовать. - [\#7156](https://github.com/ClickHouse/ClickHouse/pull/7156) ([Николай - Кочетов](https://github.com/KochetovNicolai)) -- Исправлена проблема с использованием HTTP, оставьте в живых тайм-аут вместо TCP оставить в живых тайм-аут. - [\#7351](https://github.com/ClickHouse/ClickHouse/pull/7351) ([Василий - Немков](https://github.com/Enmk)) -- Исправлена ошибка сегментации в groupBitmapOr (проблема [\#7109](https://github.com/ClickHouse/ClickHouse/issues/7109)). - [\#7289](https://github.com/ClickHouse/ClickHouse/pull/7289) ([Чжичан - Ю](https://github.com/yuzhichang)) -- Для материализованных представлений фиксация для Кафки вызывается после того, как все данные были записаны. - [\#7175](https://github.com/ClickHouse/ClickHouse/pull/7175) ([Иван](https://github.com/abyss7)) -- Исправлена ошибка `duration_ms` значение в `system.part_log` стол. Это было в десять раз хуже. - [\#7172](https://github.com/ClickHouse/ClickHouse/pull/7172) ([Владимир - Чеботарев](https://github.com/excitoon)) -- Быстрое исправление для устранения сбоя в таблице LIVE VIEW и повторного включения всех тестов LIVE VIEW. - [\#7201](https://github.com/ClickHouse/ClickHouse/pull/7201) - ([взаказников](https://github.com/vzakaznikov)) -- Правильно сериализовать значение NULL значений в мин/макс показатели MergeTree части. - [\#7234](https://github.com/ClickHouse/ClickHouse/pull/7234) ([Александр - Кузьменков](https://github.com/akuzm)) -- Не ставьте виртуальные столбцы .метаданные sql при создании таблицы в виде `CREATE TABLE AS`. - [\#7183](https://github.com/ClickHouse/ClickHouse/pull/7183) ([Иван](https://github.com/abyss7)) -- Исправлена ошибка сегментации в `ATTACH PART` запрос. - [\#7185](https://github.com/ClickHouse/ClickHouse/pull/7185) - ([алесапин](https://github.com/alesapin)) -- Исправьте неправильный результат для некоторых запросов, задаваемых оптимизацией empty в подзапросах и empty - INNER/RIGHT JOIN. [\#7284](https://github.com/ClickHouse/ClickHouse/pull/7284) ([Николай - Кочетов](https://github.com/KochetovNicolai)) -- Исправление ошибок в системах живой вид getHeader() метод. - [\#7271](https://github.com/ClickHouse/ClickHouse/pull/7271) - ([взаказников](https://github.com/vzakaznikov)) - -#### Улучшение {#improvement-1} - -- Добавьте сообщение в случае ожидания queue\_wait\_max\_ms. - [\#7390](https://github.com/ClickHouse/ClickHouse/pull/7390) ([Азат - Хужин](https://github.com/azat)) -- Выполнена установка `s3_min_upload_part_size` уровень таблицы. - [\#7059](https://github.com/ClickHouse/ClickHouse/pull/7059) ([Владимир - Чеботарев](https://github.com/excitoon)) -- Проверьте TTL в StorageFactory. [\#7304](https://github.com/ClickHouse/ClickHouse/pull/7304) - ([сундили](https://github.com/sundy-li)) -- Сквош левых блоков в частичном объединении слиянием (оптимизация). - [\#7122](https://github.com/ClickHouse/ClickHouse/pull/7122) ([Артем - Зуйков](https://github.com/4ertus2)) -- Не допускайте недетерминированных функций в мутациях реплицируемых движков таблиц, поскольку это - может привести к несогласованности между репликами. - [\#7247](https://github.com/ClickHouse/ClickHouse/pull/7247) ([Александр - Казаков](https://github.com/Akazz)) -- Отключите отслеживание памяти при преобразовании трассировки стека исключений в строку. Это может предотвратить потерю - сообщений об ошибках типа `Memory limit exceeded` на сервере, который вызвал `Attempt to read after eof` исключение для клиента. [\#7264](https://github.com/ClickHouse/ClickHouse/pull/7264) - ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Различные улучшения формата. Разрешает - [\#6033](https://github.com/ClickHouse/ClickHouse/issues/6033), - [\#2633](https://github.com/ClickHouse/ClickHouse/issues/2633), - [\#6611](https://github.com/ClickHouse/ClickHouse/issues/6611), - [\#6742](https://github.com/ClickHouse/ClickHouse/issues/6742) - [\#7215](https://github.com/ClickHouse/ClickHouse/pull/7215) - ([тавплубикс](https://github.com/tavplubix)) -- ClickHouse игнорирует значения в правой части оператора IN, которые не могут быть преобразованы в левую - side type. Make it work properly for compound types – Array and Tuple. - [\#7283](https://github.com/ClickHouse/ClickHouse/pull/7283) ([Александр - Кузьменков](https://github.com/akuzm)) -- Поддержка отсутствует Неравенство для следующих присоединиться. Можно объединить менее-или-равный вариант и строгий - больше и меньше вариантов для столбцов, следующих на синтаксис. - [\#7282](https://github.com/ClickHouse/ClickHouse/pull/7282) ([Артем - Зуйков](https://github.com/4ertus2)) -- Оптимизируйте частичное объединение слиянием. [\#7070](https://github.com/ClickHouse/ClickHouse/pull/7070) - ([Артем Зуйков](https://github.com/4ertus2)) -- Не используйте больше, чем 98К памяти в функции uniqCombined. - [\#7236](https://github.com/ClickHouse/ClickHouse/pull/7236), - [\#7270](https://github.com/ClickHouse/ClickHouse/pull/7270) ([Азат - Хужин](https://github.com/azat)) -- Промыть части правой соединительной таблицы на диске в PartialMergeJoin (если их недостаточно - память). Загружайте данные обратно, когда это необходимо. [\#7186](https://github.com/ClickHouse/ClickHouse/pull/7186) - ([Артем Зуйков](https://github.com/4ertus2)) - -#### Улучшение производительности {#performance-improvement-1} - -- Ускорьте joinGet с аргументами const, избегая дублирования данных. - [\#7359](https://github.com/ClickHouse/ClickHouse/pull/7359) ([Амос - Птица](https://github.com/amosbird)) -- Возвращайтесь раньше, если подзапрос пуст. - [\#7007](https://github.com/ClickHouse/ClickHouse/pull/7007) ([小路](https://github.com/nicelulu)) -- Оптимизируйте синтаксический анализ SQL-выражения в значениях. - [\#6781](https://github.com/ClickHouse/ClickHouse/pull/6781) - ([тавплубикс](https://github.com/tavplubix)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-1} - -- Отключите некоторые вклады для кросс-компиляции в Mac OS. - [\#7101](https://github.com/ClickHouse/ClickHouse/pull/7101) ([Иван](https://github.com/abyss7)) -- Добавьте недостающую ссылку с PocoXML для clickhouse\_common\_io. - [\#7200](https://github.com/ClickHouse/ClickHouse/pull/7200) ([Азат - Хужин](https://github.com/azat)) -- Примите несколько аргументов тестового фильтра в clickhouse-test. - [\#7226](https://github.com/ClickHouse/ClickHouse/pull/7226) ([Александр - Кузьменков](https://github.com/akuzm)) -- Включите musl и jemalloc для ARM. [\#7300](https://github.com/ClickHouse/ClickHouse/pull/7300) - ([Амос Птица](https://github.com/amosbird)) -- Добавлен `--client-option` параметр to `clickhouse-test` чтобы передать клиенту дополнительные параметры. - [\#7277](https://github.com/ClickHouse/ClickHouse/pull/7277) ([Николай - Кочетов](https://github.com/KochetovNicolai)) -- Сохраните существующие конфигурации при обновлении пакета rpm. - [\#7103](https://github.com/ClickHouse/ClickHouse/pull/7103) - ([Филимонов](https://github.com/filimonov)) -- Исправление ошибок, обнаруженных ПВС. [\#7153](https://github.com/ClickHouse/ClickHouse/pull/7153) ([Артем - Зуйков](https://github.com/4ertus2)) -- Исправьте сборку для Дарвина. [\#7149](https://github.com/ClickHouse/ClickHouse/pull/7149) - ([Иван](https://github.com/abyss7)) -- совместимость с glibc 2.29. [\#7142](https://github.com/ClickHouse/ClickHouse/pull/7142) ([Амос - Птица](https://github.com/amosbird)) -- Убедитесь, что dh\_clean не касается потенциальных исходных файлов. - [\#7205](https://github.com/ClickHouse/ClickHouse/pull/7205) ([Амос - Птица](https://github.com/amosbird)) -- Попытка избежать конфликта при обновлении с altinity rpm - он имеет конфигурационный файл, упакованный отдельно - в clickhouse-server-common. [\#7073](https://github.com/ClickHouse/ClickHouse/pull/7073) - ([Филимонов](https://github.com/filimonov)) -- Оптимизируйте некоторые заголовочные файлы для более быстрого восстановления. - [\#7212](https://github.com/ClickHouse/ClickHouse/pull/7212), - [\#7231](https://github.com/ClickHouse/ClickHouse/pull/7231) ([Александр - Кузьменков](https://github.com/akuzm)) -- Добавьте тесты производительности для Date и DateTime. [\#7332](https://github.com/ClickHouse/ClickHouse/pull/7332) ([Василий - Немков](https://github.com/Enmk)) -- Исправьте некоторые тесты, которые содержали недетерминированные мутации. - [\#7132](https://github.com/ClickHouse/ClickHouse/pull/7132) ([Александр - Казаков](https://github.com/Akazz)) -- Добавьте сборку с MemorySanitizer в CI. [\#7066](https://github.com/ClickHouse/ClickHouse/pull/7066) - ([Александр Кузьменков](https://github.com/akuzm)) -- Избегайте использования неинициализированных значений в MetricsTransmitter. - [\#7158](https://github.com/ClickHouse/ClickHouse/pull/7158) ([Азат - Хужин](https://github.com/azat)) -- Исправьте некоторые проблемы в полях, найденных MemorySanitizer. - [\#7135](https://github.com/ClickHouse/ClickHouse/pull/7135), - [\#7179](https://github.com/ClickHouse/ClickHouse/pull/7179) ([Александр - Кузьменков](https://github.com/akuzm)), [\#7376](https://github.com/ClickHouse/ClickHouse/pull/7376) - ([Амос Птица](https://github.com/amosbird)) -- Исправьте неопределенное поведение в murmurhash32. [\#7388](https://github.com/ClickHouse/ClickHouse/pull/7388) ([Амос - Птица](https://github.com/amosbird)) -- Исправьте неопределенное поведение в StoragesInfoStream. [\#7384](https://github.com/ClickHouse/ClickHouse/pull/7384) - ([тавплубикс](https://github.com/tavplubix)) -- Исправлено сворачивание постоянных выражений для внешних движков баз данных (MySQL, ODBC, JDBC). В предыдущих случаях - версии он не работал для нескольких постоянных выражений и вообще не работал для даты, - Дата-время и UUID. Это исправление [\#7245](https://github.com/ClickHouse/ClickHouse/issues/7245) - [\#7252](https://github.com/ClickHouse/ClickHouse/pull/7252) - ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправление ошибки гонки данных ThreadSanitizer в режиме реального времени при обращении к переменной no\_users\_thread. - [\#7353](https://github.com/ClickHouse/ClickHouse/pull/7353) - ([взаказников](https://github.com/vzakaznikov)) -- Избавьтесь от символов malloc в libcommon - [\#7134](https://github.com/ClickHouse/ClickHouse/pull/7134), - [\#7065](https://github.com/ClickHouse/ClickHouse/pull/7065) ([Амос - Птица](https://github.com/amosbird)) -- Добавьте глобальный флаг ENABLE\_LIBRARIES для отключения всех библиотек. - [\#7063](https://github.com/ClickHouse/ClickHouse/pull/7063) - ([proller](https://github.com/proller)) - -#### Очистка кода {#code-cleanup} - -- Обобщите репозиторий конфигурации для подготовки к DDL для словарей. [\#7155](https://github.com/ClickHouse/ClickHouse/pull/7155) - ([алесапин](https://github.com/alesapin)) -- Парсер для словарей DDL без всякой семантики. - [\#7209](https://github.com/ClickHouse/ClickHouse/pull/7209) - ([алесапин](https://github.com/alesapin)) -- Разделите ParserCreateQuery на различные более мелкие Парсеры. - [\#7253](https://github.com/ClickHouse/ClickHouse/pull/7253) - ([алесапин](https://github.com/alesapin)) -- Небольшой рефакторинг и переименование рядом с внешними словарями. - [\#7111](https://github.com/ClickHouse/ClickHouse/pull/7111) - ([алесапин](https://github.com/alesapin)) -- Рефакторинг некоторого кода для подготовки к управлению доступом на основе ролей. [\#7235](https://github.com/ClickHouse/ClickHouse/pull/7235) ([Виталий - Баранов](https://github.com/vitlibar)) -- Некоторые улучшения в коде DatabaseOrdinary. - [\#7086](https://github.com/ClickHouse/ClickHouse/pull/7086) ([Никита - Васильев](https://github.com/nikvas0)) -- Не используйте итераторы в методах find () и emplace () хэш-таблиц. - [\#7026](https://github.com/ClickHouse/ClickHouse/pull/7026) ([Александр - Кузьменков](https://github.com/akuzm)) -- Исправьте getMultipleValuesFromConfig в случае, если корень параметра не пуст. [\#7374](https://github.com/ClickHouse/ClickHouse/pull/7374) - ([Михаил Коротов](https://github.com/millb)) -- Удалите часть copy-paste (TemporaryFile и TemporaryFileStream) - [\#7166](https://github.com/ClickHouse/ClickHouse/pull/7166) ([Артем - Зуйков](https://github.com/4ertus2)) -- Немного улучшена читаемость кода (`MergeTreeData::getActiveContainingPart`). - [\#7361](https://github.com/ClickHouse/ClickHouse/pull/7361) ([Владимир - Чеботарев](https://github.com/excitoon)) -- Дождитесь всех запланированных заданий, которые используют локальные объекты, если `ThreadPool::schedule(...)` бросает - исключение. Переименовать `ThreadPool::schedule(...)` к `ThreadPool::scheduleOrThrowOnError(...)` и - исправьте комментарии, чтобы сделать очевидным, что он может бросить. - [\#7350](https://github.com/ClickHouse/ClickHouse/pull/7350) - ([тавплубикс](https://github.com/tavplubix)) - -## ClickHouse релиз 19.15 {#clickhouse-release-19-15} - -### ClickHouse релиз 19.15.4.10, 2019-10-31 {#clickhouse-release-19-15-4-10-2019-10-31} - -#### Исправление ошибок {#bug-fix-3} - -- Добавлена обработка SQL\_TINYINT и SQL\_BIGINT, а также исправлена обработка типов источников данных SQL\_FLOAT в Мосте ODBC. - [\#7491](https://github.com/ClickHouse/ClickHouse/pull/7491) ([Денис Глазачев](https://github.com/traceon)) -- Разрешается иметь некоторые части на целевом диске или Томе в разделе перемещения. - [\#7434](https://github.com/ClickHouse/ClickHouse/pull/7434) ([Владимир Чеботарев](https://github.com/excitoon)) -- Фиксированное значение NULL-значений в столбцы, допускающие значения null через ODBC-мост. - [\#7402](https://github.com/ClickHouse/ClickHouse/pull/7402) ([Василий Немков](https://github.com/Enmk)) -- Исправлена вставка в распределенный нелокальный узел с материализованными столбцами. - [\#7377](https://github.com/ClickHouse/ClickHouse/pull/7377) ([Азат Хужин](https://github.com/azat)) -- Исправлена функция getMultipleValuesFromConfig. - [\#7374](https://github.com/ClickHouse/ClickHouse/pull/7374) ([Михаил Коротов](https://github.com/millb)) -- Исправлена проблема с использованием HTTP, оставьте в живых тайм-аут вместо TCP оставить в живых тайм-аут. - [\#7351](https://github.com/ClickHouse/ClickHouse/pull/7351) ([Василий Немков](https://github.com/Enmk)) -- Дождитесь завершения всех заданий по исключению (исправлены редкие сегменты). - [\#7350](https://github.com/ClickHouse/ClickHouse/pull/7350) ([тавплубикс](https://github.com/tavplubix)) -- Не нажимайте на MVs при вставке в таблицу Кафки. - [\#7265](https://github.com/ClickHouse/ClickHouse/pull/7265) ([Иван](https://github.com/abyss7)) -- Отключите отслеживание памяти для стека исключений. - [\#7264](https://github.com/ClickHouse/ClickHouse/pull/7264) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлен неверный код при преобразовании запроса для внешней базы данных. - [\#7252](https://github.com/ClickHouse/ClickHouse/pull/7252) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Избегайте использования неинициализированных значений в MetricsTransmitter. - [\#7158](https://github.com/ClickHouse/ClickHouse/pull/7158) ([Азат Хужин](https://github.com/azat)) -- Добавлен пример конфигурации с макросами для тестов ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.15.3.6, 2019-10-09 {#clickhouse-release-19-15-3-6-2019-10-09} - -#### Исправление ошибок {#bug-fix-4} - -- Исправлена ошибка bad\_variant в хэшированном словаре. - ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка с ошибкой сегментации в запросе ATTACH PART. - ([алесапин](https://github.com/alesapin)) -- Расчет фиксированного времени в `MergeTreeData`. - ([Владимир Чеботарев](https://github.com/excitoon)) -- Посвятите себя Кафке явно после того, как написание будет завершено. - [\#7175](https://github.com/ClickHouse/ClickHouse/pull/7175) ([Иван](https://github.com/abyss7)) -- Правильно сериализовать значение NULL значений в мин/макс показатели MergeTree части. - [\#7234](https://github.com/ClickHouse/ClickHouse/pull/7234) ([Александр Кузьменков](https://github.com/akuzm)) - -### ClickHouse релиз 19.15.2.2, 2019-10-01 {#clickhouse-release-19-15-2-2-2019-10-01} - -#### Новая функция {#new-feature-3} - -- Многоуровневое хранение: поддержка использования нескольких томов хранения для таблиц с движком MergeTree. Можно хранить свежие данные на SSD и автоматически перемещать старые данные на жесткий диск. ([пример](https://clickhouse.github.io/clickhouse-presentations/meetup30/new_features/#12)). [\#4918](https://github.com/ClickHouse/ClickHouse/pull/4918) ([Игр](https://github.com/ObjatieGroba)) [\#6489](https://github.com/ClickHouse/ClickHouse/pull/6489) ([алесапин](https://github.com/alesapin)) -- Добавить функцию таблицы `input` для считывания входящих данных в `INSERT SELECT` запрос. [\#5450](https://github.com/ClickHouse/ClickHouse/pull/5450) ([паласоник1](https://github.com/palasonic1)) [\#6832](https://github.com/ClickHouse/ClickHouse/pull/6832) ([Антон Попов](https://github.com/CurtizJ)) -- Добавить а `sparse_hashed` компоновка словаря, которая функционально эквивалентна `hashed` макет, но более эффективен для работы с памятью. Он использует примерно в два раза меньше памяти за счет более медленного извлечения значений. [\#6894](https://github.com/ClickHouse/ClickHouse/pull/6894) ([Азат Хужин](https://github.com/azat)) -- Реализована возможность определения списка пользователей для доступа к словарям. Используется только текущая подключенная база данных. [\#6907](https://github.com/ClickHouse/ClickHouse/pull/6907) ([Гийом Тассери](https://github.com/YiuRULE)) -- Добавь `LIMIT` опцион на `SHOW` запрос. [\#6944](https://github.com/ClickHouse/ClickHouse/pull/6944) ([Филипп Мальковский](https://github.com/malkfilipp)) -- Добавь `bitmapSubsetLimit(bitmap, range_start, limit)` функция, возвращающая подмножество наименьшего числа `limit` значения в наборе, который не меньше, чем `range_start`. [\#6957](https://github.com/ClickHouse/ClickHouse/pull/6957) ([Zhichang Ю](https://github.com/yuzhichang)) -- Добавь `bitmapMin` и `bitmapMax` функции. [\#6970](https://github.com/ClickHouse/ClickHouse/pull/6970) ([Zhichang Ю](https://github.com/yuzhichang)) -- Функция add `repeat` относится к [выпуск-6648](https://github.com/ClickHouse/ClickHouse/issues/6648) [\#6999](https://github.com/ClickHouse/ClickHouse/pull/6999) ([Флинн](https://github.com/ucasFL)) - -#### Экспериментальная возможность {#experimental-feature-1} - -- Реализуйте (в памяти) вариант соединения слиянием, который не изменяет текущий конвейер. Результат частично сортируется по ключу слияния. Набор `partial_merge_join = 1` чтобы использовать эту функцию. Соединение слиянием все еще находится в разработке. [\#6940](https://github.com/ClickHouse/ClickHouse/pull/6940) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавь `S3` функция двигателя и таблицы. Он все еще находится в разработке (пока нет поддержки аутентификации). [\#5596](https://github.com/ClickHouse/ClickHouse/pull/5596) ([Владимир Чеботарев](https://github.com/excitoon)) - -#### Улучшение {#improvement-2} - -- Каждое сообщение, прочитанное от Кафки, вставляется атомарно. Это решает почти все известные проблемы с двигателем Kafka. [\#6950](https://github.com/ClickHouse/ClickHouse/pull/6950) ([Иван](https://github.com/abyss7)) -- Улучшения для отработки отказа распределенных запросов. Сократите время восстановления, также оно теперь конфигурируемо и может быть увидено в `system.clusters`. [\#6399](https://github.com/ClickHouse/ClickHouse/pull/6399) ([Василий Немков](https://github.com/Enmk)) -- Поддержка числовых значений для перечислений непосредственно в `IN` раздел. \#6766 [\#6941](https://github.com/ClickHouse/ClickHouse/pull/6941) ([dimarub2000](https://github.com/dimarub2000)) -- Поддержка (опционально, по умолчанию отключен) перенаправляет на URL хранение. [\#6914](https://github.com/ClickHouse/ClickHouse/pull/6914) ([maqroll](https://github.com/maqroll)) -- Добавьте информационное сообщение, когда клиент с более старой версией подключается к серверу. [\#6893](https://github.com/ClickHouse/ClickHouse/pull/6893) ([Филипп Мальковский](https://github.com/malkfilipp)) -- Удалите максимальное ограничение времени ожидания обратного отсчета для отправки данных в распределенных таблицах [\#6895](https://github.com/ClickHouse/ClickHouse/pull/6895) ([Азат Хужин](https://github.com/azat)) -- Добавьте возможность отправлять графиту события профиля (счетчики) с кумулятивными значениями. Его можно включить в разделе `` в серверах `config.xml`. [\#6969](https://github.com/ClickHouse/ClickHouse/pull/6969) ([Азат Хужин](https://github.com/azat)) -- Добавить автоматическое приведение типа `T` к `LowCardinality(T)` при вставке данных в столбец типа `LowCardinality(T)` в родном формате через HTTP. [\#6891](https://github.com/ClickHouse/ClickHouse/pull/6891) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Добавить возможность использования функции `hex` без использования `reinterpretAsString` для `Float32`, `Float64`. [\#7024](https://github.com/ClickHouse/ClickHouse/pull/7024) ([Михаил Коротов](https://github.com/millb)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-2} - -- Добавьте gdb-индекс в двоичный файл clickhouse с отладочной информацией. Это ускорит время запуска системы. `gdb`. [\#6947](https://github.com/ClickHouse/ClickHouse/pull/6947) ([алесапин](https://github.com/alesapin)) -- Ускорить деб упаковки с исправленными помощью dpkg-деб, которая использует `pigz`. [\#6960](https://github.com/ClickHouse/ClickHouse/pull/6960) ([алесапин](https://github.com/alesapin)) -- Набор `enable_fuzzing = 1` чтобы включить инструментирование libfuzzer всего кода проекта. [\#7042](https://github.com/ClickHouse/ClickHouse/pull/7042) ([kyprizel](https://github.com/kyprizel)) -- Добавить сплит построить тест в КИ. [\#7061](https://github.com/ClickHouse/ClickHouse/pull/7061) ([алесапин](https://github.com/alesapin)) -- Добавьте сборку с MemorySanitizer в CI. [\#7066](https://github.com/ClickHouse/ClickHouse/pull/7066) ([Александр Кузьменков](https://github.com/akuzm)) -- Заменять `libsparsehash` с `sparsehash-c11` [\#6965](https://github.com/ClickHouse/ClickHouse/pull/6965) ([Азат Хужин](https://github.com/azat)) - -#### Исправление ошибок {#bug-fix-5} - -- Исправлено снижение производительности индексного анализа по сложным ключам на больших таблицах. Это исправляет \#6924. [\#7075](https://github.com/ClickHouse/ClickHouse/pull/7075) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена логическая ошибка, вызывающая segfaults при выборе из Кафки пустой темы. [\#6909](https://github.com/ClickHouse/ClickHouse/pull/6909) ([Иван](https://github.com/abyss7)) -- Исправлено слишком раннее закрытие соединения MySQL `MySQLBlockInputStream.cpp`. [\#6882](https://github.com/ClickHouse/ClickHouse/pull/6882) ([Clément Rodriguez](https://github.com/clemrodriguez)) -- Возвращена поддержка очень старых ядер Linux (исправление [\#6841](https://github.com/ClickHouse/ClickHouse/issues/6841)) [\#6853](https://github.com/ClickHouse/ClickHouse/pull/6853) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить возможную потерю данных в `insert select` запрос в случае пустого блока во входном потоке. \#6834 \#6862 [\#6911](https://github.com/ClickHouse/ClickHouse/pull/6911) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправление для функции `АrrayEnumerateUniqRanked` с пустыми массивами в парах [\#6928](https://github.com/ClickHouse/ClickHouse/pull/6928) ([proller](https://github.com/proller)) -- Исправьте сложные запросы с помощью соединений массивов и глобальных подзапросов. [\#6934](https://github.com/ClickHouse/ClickHouse/pull/6934) ([Иван](https://github.com/abyss7)) -- Чинить `Unknown identifier` ошибка в порядке ПО и группировка ПО с несколькими соединениями [\#7022](https://github.com/ClickHouse/ClickHouse/pull/7022) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлено `MSan` предупреждение при выполнении функции с помощью `LowCardinality` аргумент. [\#7062](https://github.com/ClickHouse/ClickHouse/pull/7062) ([Николай Кочетов](https://github.com/KochetovNicolai)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-2} - -- Изменен формат сериализации состояний растровых \* агрегатных функций для повышения производительности. Сериализованные состояния растрового изображения\* из предыдущих версий не могут быть прочитаны. [\#6908](https://github.com/ClickHouse/ClickHouse/pull/6908) ([Zhichang Ю](https://github.com/yuzhichang)) - -## ClickHouse релиз 19.14 {#clickhouse-release-19-14} - -### ClickHouse релиз 19.14.7.15, 2019-10-02 {#clickhouse-release-19-14-7-15-2019-10-02} - -#### Исправление ошибок {#bug-fix-6} - -- Этот релиз также содержит все исправления ошибок от 19.11.12.69. -- Исправлена совместимость для распределенных запросов между 19.14 и более ранними версиями. Это исправление [\#7068](https://github.com/ClickHouse/ClickHouse/issues/7068). [\#7069](https://github.com/ClickHouse/ClickHouse/pull/7069) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.14.6.12, 2019-09-19 {#clickhouse-release-19-14-6-12-2019-09-19} - -#### Исправление ошибок {#bug-fix-7} - -- Исправление для функции `АrrayEnumerateUniqRanked` с пустыми массивами в парах. [\#6928](https://github.com/ClickHouse/ClickHouse/pull/6928) ([proller](https://github.com/proller)) -- Исправлено имя подзапроса в запросах с `ARRAY JOIN` и `GLOBAL IN subquery` с псевдонимом. Используйте псевдоним подзапроса для внешнего имени таблицы, если оно указано. [\#6934](https://github.com/ClickHouse/ClickHouse/pull/6934) ([Иван](https://github.com/abyss7)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-3} - -- Чинить [хлопанье](https://clickhouse-test-reports.s3.yandex.net/6944/aab95fd5175a513413c7395a73a82044bdafb906/functional_stateless_tests_(debug).html) тест `00715_fetch_merged_or_mutated_part_zookeeper` переписывая его в оболочку скриптов, потому что он должен ждать, пока мутации применятся. [\#6977](https://github.com/ClickHouse/ClickHouse/pull/6977) ([Александр казаков](https://github.com/Akazz)) -- Исправлены системные и MemSan сбой в функции `groupUniqArray` с аргументом массива emtpy. Это было вызвано размещением пустых `PaddedPODArray` в хэш-таблицу нулевая ячейка, потому что конструктор для нулевого значения ячейки не вызывался. [\#6937](https://github.com/ClickHouse/ClickHouse/pull/6937) ([Амос Птица](https://github.com/amosbird)) - -### ClickHouse релиз 19.14.3.3, 2019-09-10 {#clickhouse-release-19-14-3-3-2019-09-10} - -#### Новая функция {#new-feature-4} - -- `WITH FILL` модификатор для `ORDER BY`. (продолжение работы [\#5069](https://github.com/ClickHouse/ClickHouse/issues/5069)) [\#6610](https://github.com/ClickHouse/ClickHouse/pull/6610) ([Антон Попов](https://github.com/CurtizJ)) -- `WITH TIES` модификатор для `LIMIT`. (продолжение работы [\#5069](https://github.com/ClickHouse/ClickHouse/issues/5069)) [\#6610](https://github.com/ClickHouse/ClickHouse/pull/6610) ([Антон Попов](https://github.com/CurtizJ)) -- Разобрать некотируемых `NULL` буквальное значение NULL (если настройки `format_csv_unquoted_null_literal_as_null=1`). Инициализируйте нулевые поля значениями по умолчанию, если тип данных этого поля не является нулевым (если задано значение `input_format_null_as_default=1`). [\#5990](https://github.com/ClickHouse/ClickHouse/issues/5990) [\#6055](https://github.com/ClickHouse/ClickHouse/pull/6055) ([тавплубикс](https://github.com/tavplubix)) -- Поддержка подстановочных знаков в путях табличных функций `file` и `hdfs`. Если путь содержит подстановочные знаки, то таблица будет доступна только для чтения. Пример использования: `select * from hdfs('hdfs://hdfs1:9000/some_dir/another_dir/*/file{0..9}{0..9}')` и `select * from file('some_dir/{some_file,another_file,yet_another}.tsv', 'TSV', 'value UInt32')`. [\#6092](https://github.com/ClickHouse/ClickHouse/pull/6092) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Новый `system.metric_log` таблица, в которой хранятся значения `system.events` и `system.metrics` с заданным интервалом времени. [\#6363](https://github.com/ClickHouse/ClickHouse/issues/6363) [\#6467](https://github.com/ClickHouse/ClickHouse/pull/6467) ([Никита Михайлов](https://github.com/nikitamikhaylov)) [\#6530](https://github.com/ClickHouse/ClickHouse/pull/6530) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Разрешить запись текстовых журналов ClickHouse в `system.text_log` стол. [\#6037](https://github.com/ClickHouse/ClickHouse/issues/6037) [\#6103](https://github.com/ClickHouse/ClickHouse/pull/6103) ([Никита Михайлов](https://github.com/nikitamikhaylov)) [\#6164](https://github.com/ClickHouse/ClickHouse/pull/6164) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Показывать частные символы в трассировках стека (это делается с помощью синтаксического анализа таблиц символов файлов ELF). Добавлена информация о файле и номере строки в трассировках стека, если присутствует отладочная информация. Ускоренный поиск имени символа с индексацией символов, присутствующих в программе. Добавлены новые функции SQL для самоанализа: `demangle` и `addressToLine`. Переименованная функция `symbolizeAddress` к `addressToSymbol` для последовательности. Функция `addressToSymbol` вернет искалеченное имя по соображениям производительности и вам придется подать заявку `demangle`. Добавлена настройка `allow_introspection_functions` который по умолчанию отключен. [\#6201](https://github.com/ClickHouse/ClickHouse/pull/6201) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Табличная функция `values` (имя не чувствительно к регистру). Это позволяет читать из `VALUES` список предложенных в [\#5984](https://github.com/ClickHouse/ClickHouse/issues/5984). Пример: `SELECT * FROM VALUES('a UInt64, s String', (1, 'one'), (2, 'two'), (3, 'three'))`. [\#6217](https://github.com/ClickHouse/ClickHouse/issues/6217). [\#6209](https://github.com/ClickHouse/ClickHouse/pull/6209) ([dimarub2000](https://github.com/dimarub2000)) -- Добавлена возможность изменять настройки хранения. Синтаксис: `ALTER TABLE MODIFY SETTING = `. [\#6366](https://github.com/ClickHouse/ClickHouse/pull/6366) [\#6669](https://github.com/ClickHouse/ClickHouse/pull/6669) [\#6685](https://github.com/ClickHouse/ClickHouse/pull/6685) ([алесапин](https://github.com/alesapin)) -- Опора для снятия отсоединенных деталей. Синтаксис: `ALTER TABLE DROP DETACHED PART ''`. [\#6158](https://github.com/ClickHouse/ClickHouse/pull/6158) ([тавплубикс](https://github.com/tavplubix)) -- Ограничения таблицы. Позволяет добавить ограничение к определению таблицы,которое будет проверяться при вставке. [\#5273](https://github.com/ClickHouse/ClickHouse/pull/5273) ([Глеб Новиков](https://github.com/NanoBjorn)) [\#6652](https://github.com/ClickHouse/ClickHouse/pull/6652) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Суппорт для каскадных материализованных представлений. [\#6324](https://github.com/ClickHouse/ClickHouse/pull/6324) ([Амос Птица](https://github.com/amosbird)) -- Включите профилировщик запросов по умолчанию, чтобы один раз в секунду выполнять выборку каждого потока выполнения запроса. [\#6283](https://github.com/ClickHouse/ClickHouse/pull/6283) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Входной формат `ORC`. [\#6454](https://github.com/ClickHouse/ClickHouse/pull/6454) [\#6703](https://github.com/ClickHouse/ClickHouse/pull/6703) ([аконяев90](https://github.com/akonyaev90)) -- Добавлены две новые функции: `sigmoid` и `tanh` (которые полезны для приложений машинного обучения). [\#6254](https://github.com/ClickHouse/ClickHouse/pull/6254) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Функция `hasToken(haystack, token)`, `hasTokenCaseInsensitive(haystack, token)` чтобы проверить, находится ли данный токен в стоге сена. Токен-это подстрока максимальной длины между двумя не буквенно-цифровыми символами ASCII (или границами стога сена). Токен должен быть постоянной строкой. Поддерживается специализацией индекса tokenbf\_v1. [\#6596](https://github.com/ClickHouse/ClickHouse/pull/6596), [\#6662](https://github.com/ClickHouse/ClickHouse/pull/6662) ([Василий Немков](https://github.com/Enmk)) -- Новая функция `neighbor(value, offset[, default_value])`. Позволяет достичь значения prev / next внутри столбца в блоке данных. [\#5925](https://github.com/ClickHouse/ClickHouse/pull/5925) ([Алекс Краш](https://github.com/alex-krash)) [6685365ab8c5b74f9650492c88a012596eb1b0c6](https://github.com/ClickHouse/ClickHouse/commit/6685365ab8c5b74f9650492c88a012596eb1b0c6) [341e2e4587a18065c2da1ca888c73389f48ce36c](https://github.com/ClickHouse/ClickHouse/commit/341e2e4587a18065c2da1ca888c73389f48ce36c) [Алексей Миловидов](https://github.com/alexey-milovidov) -- Создал функцию `currentUser()`, возвращая логин авторизованного пользователя. Добавлен псевдоним `user()` для совместимости с MySQL. [\#6470](https://github.com/ClickHouse/ClickHouse/pull/6470) ([Алекс Краш](https://github.com/alex-krash)) -- Новые агрегатные функции `quantilesExactInclusive` и `quantilesExactExclusive` которые были предложены в [\#5885](https://github.com/ClickHouse/ClickHouse/issues/5885). [\#6477](https://github.com/ClickHouse/ClickHouse/pull/6477) ([dimarub2000](https://github.com/dimarub2000)) -- Функция `bitmapRange(bitmap, range_begin, range_end)` который возвращает новый набор с заданным диапазоном (не включает в себя `range_end`). [\#6314](https://github.com/ClickHouse/ClickHouse/pull/6314) ([Zhichang Ю](https://github.com/yuzhichang)) -- Функция `geohashesInBox(longitude_min, latitude_min, longitude_max, latitude_max, precision)` что создает массив прецизионных длинных строк геохаш-боксов, покрывающих заданную площадь. [\#6127](https://github.com/ClickHouse/ClickHouse/pull/6127) ([Василий Немков](https://github.com/Enmk)) -- Реализуйте поддержку запроса INSERT с помощью `Kafka` таблицы. [\#6012](https://github.com/ClickHouse/ClickHouse/pull/6012) ([Иван](https://github.com/abyss7)) -- Добавлена поддержка для `_partition` и `_timestamp` виртуальные колонки для движка Кафки. [\#6400](https://github.com/ClickHouse/ClickHouse/pull/6400) ([Иван](https://github.com/abyss7)) -- Возможность удаления конфиденциальных данных из `query_log`, журналы серверов, список процессов с правилами на основе регулярных выражений. [\#5710](https://github.com/ClickHouse/ClickHouse/pull/5710) ([Филимонов](https://github.com/filimonov)) - -#### Экспериментальная возможность {#experimental-feature-2} - -- Формат входных и выходных данных `Template`. Он позволяет указать строку пользовательского формата для ввода и вывода. [\#4354](https://github.com/ClickHouse/ClickHouse/issues/4354) [\#6727](https://github.com/ClickHouse/ClickHouse/pull/6727) ([тавплубикс](https://github.com/tavplubix)) -- Реализация проекта `LIVE VIEW` таблицы, которые были первоначально предложены в [\#2898](https://github.com/ClickHouse/ClickHouse/pull/2898), подготовленные в [\#3925](https://github.com/ClickHouse/ClickHouse/issues/3925), а затем обновляется в [\#5541](https://github.com/ClickHouse/ClickHouse/issues/5541). Видеть [\#5541](https://github.com/ClickHouse/ClickHouse/issues/5541) для детального описания. [\#5541](https://github.com/ClickHouse/ClickHouse/issues/5541) ([взаказников](https://github.com/vzakaznikov)) [\#6425](https://github.com/ClickHouse/ClickHouse/pull/6425) ([Николай Кочетов](https://github.com/KochetovNicolai)) [\#6656](https://github.com/ClickHouse/ClickHouse/pull/6656) ([взаказников](https://github.com/vzakaznikov)) Заметить что `LIVE VIEW` функция может быть удалена в следующих версиях. - -#### Исправление ошибок {#bug-fix-8} - -- Этот релиз также содержит все исправления ошибок от 19.13 и 19.11. -- Исправьте ошибку сегментации, когда в таблице есть индексы пропуска и происходит вертикальное слияние. [\#6723](https://github.com/ClickHouse/ClickHouse/pull/6723) ([алесапин](https://github.com/alesapin)) -- Исправьте ТТЛ для каждого столбца с нетривиальными значениями по умолчанию для столбцов. Ранее в случае принудительного слияния TTL с `OPTIMIZE ... FINAL` запрос, истекшие значения были заменены типом defaults вместо заданных пользователем значений столбца defaults. [\#6796](https://github.com/ClickHouse/ClickHouse/pull/6796) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена проблема дублирования сообщений Кафки при обычном перезапуске сервера. [\#6597](https://github.com/ClickHouse/ClickHouse/pull/6597) ([Иван](https://github.com/abyss7)) -- Исправлена бесконечная петля при чтении сообщений Кафки. Не приостанавливайте/возобновляйте потребительскую подписку вообще - в противном случае она может быть приостановлена на неопределенный срок в некоторых сценариях. [\#6354](https://github.com/ClickHouse/ClickHouse/pull/6354) ([Иван](https://github.com/abyss7)) -- Чинить `Key expression contains comparison between inconvertible types` исключение в `bitmapContains` функция. [\#6136](https://github.com/ClickHouse/ClickHouse/issues/6136) [\#6146](https://github.com/ClickHouse/ClickHouse/issues/6146) [\#6156](https://github.com/ClickHouse/ClickHouse/pull/6156) ([dimarub2000](https://github.com/dimarub2000)) -- Исправлена обработка выхода онлайн / оффлайн с поддержкой `optimize_skip_unused_shards` и пропал ключ от осколков. [\#6384](https://github.com/ClickHouse/ClickHouse/pull/6384) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлен неправильный код в мутациях, которые могут привести к повреждению памяти. Исправлена обработка выхода онлайн / оффлайн чтения адреса `0x14c0` это может произойти из-за совпадения `DROP TABLE` и `SELECT` от `system.parts` или `system.parts_columns`. Фиксированное состояние расы при подготовке запросов мутаций. Исправлена тупиковая ситуация, вызванная `OPTIMIZE` реплицированных таблиц и параллельных операций модификации, таких как ALTERs. [\#6514](https://github.com/ClickHouse/ClickHouse/pull/6514) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Убраны лишние подробный вход в интерфейс для MySQL [\#6389](https://github.com/ClickHouse/ClickHouse/pull/6389) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Возвращает возможность разбора логических настроек из ‘true’ и ‘false’ в конфигурационном файле. [\#6278](https://github.com/ClickHouse/ClickHouse/pull/6278) ([алесапин](https://github.com/alesapin)) -- Исправить сбой в работе `quantile` и `median` функции `Nullable(Decimal128)`. [\#6378](https://github.com/ClickHouse/ClickHouse/pull/6378) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлен возможный неполный результат возвращаемый компанией `SELECT` запрос с помощью `WHERE` условие о первичном ключе содержало преобразование в тип Float. Это было вызвано неправильной проверкой монотонности в `toFloat` функция. [\#6248](https://github.com/ClickHouse/ClickHouse/issues/6248) [\#6374](https://github.com/ClickHouse/ClickHouse/pull/6374) ([dimarub2000](https://github.com/dimarub2000)) -- Проверять `max_expanded_ast_elements` установка для мутаций. Ясные мутации после `TRUNCATE TABLE`. [\#6205](https://github.com/ClickHouse/ClickHouse/pull/6205) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправьте результаты соединения для ключевых столбцов при использовании с `join_use_nulls`. Прикрепите значения null вместо столбцов по умолчанию. [\#6249](https://github.com/ClickHouse/ClickHouse/pull/6249) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка пропуска индексов с вертикальным слиянием и alter. Исправить для `Bad size of marks file` исключение. [\#6594](https://github.com/ClickHouse/ClickHouse/issues/6594) [\#6713](https://github.com/ClickHouse/ClickHouse/pull/6713) ([алесапин](https://github.com/alesapin)) -- Исправлена редкая ошибка в `ALTER MODIFY COLUMN` и вертикальное слияние, когда одна из Объединенных/измененных частей пуста (0 строк) [\#6746](https://github.com/ClickHouse/ClickHouse/issues/6746) [\#6780](https://github.com/ClickHouse/ClickHouse/pull/6780) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка в преобразовании `LowCardinality` напечатать `AggregateFunctionFactory`. Это исправление [\#6257](https://github.com/ClickHouse/ClickHouse/issues/6257). [\#6281](https://github.com/ClickHouse/ClickHouse/pull/6281) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправить неправильное поведение и возможные вылеты в `topK` и `topKWeighted` агрегированные функции. [\#6404](https://github.com/ClickHouse/ClickHouse/pull/6404) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлен небезопасный код вокруг `getIdentifier` функция. [\#6401](https://github.com/ClickHouse/ClickHouse/issues/6401) [\#6409](https://github.com/ClickHouse/ClickHouse/pull/6409) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка в протоколе MySQL wire (используется при подключении к ClickHouse form MySQL client). Вызвано переполнением буфера кучи в `PacketPayloadWriteBuffer`. [\#6212](https://github.com/ClickHouse/ClickHouse/pull/6212) ([Юрий Баранов](https://github.com/yurriy)) -- Исправлена утечка памяти внутри `bitmapSubsetInRange` функция. [\#6819](https://github.com/ClickHouse/ClickHouse/pull/6819) ([Zhichang Ю](https://github.com/yuzhichang)) -- Исправлена редкая ошибка, когда мутация выполнялась после изменения детализации. [\#6816](https://github.com/ClickHouse/ClickHouse/pull/6816) ([алесапин](https://github.com/alesapin)) -- Разрешить сообщение protobuf со всеми полями по умолчанию. [\#6132](https://github.com/ClickHouse/ClickHouse/pull/6132) ([Виталий Баранов](https://github.com/vitlibar)) -- Устраните ошибку с помощью `nullIf` функция, когда мы посылаем `NULL` аргумент по второму аргументу. [\#6446](https://github.com/ClickHouse/ClickHouse/pull/6446) ([Гийом Тассери](https://github.com/YiuRULE)) -- Исправлена редкая ошибка с неправильным выделением/освобождением памяти в сложных ключевых словарях кэша со строковыми полями, что приводит к бесконечному потреблению памяти (похоже на утечку памяти). Ошибка воспроизводится, когда размер строки был равен степени два, начиная с восьми (8, 16, 32 и т. д.). [\#6447](https://github.com/ClickHouse/ClickHouse/pull/6447) ([алесапин](https://github.com/alesapin)) -- Исправлено кодирование горилл на небольших последовательностях, которое вызывало исключение `Cannot write after end of buffer`. [\#6398](https://github.com/ClickHouse/ClickHouse/issues/6398) [\#6444](https://github.com/ClickHouse/ClickHouse/pull/6444) ([Василий Немков](https://github.com/Enmk)) -- Разрешить использовать не обнуляемые типы В соединениях с `join_use_nulls` включен. [\#6705](https://github.com/ClickHouse/ClickHouse/pull/6705) ([Артем Зуйков](https://github.com/4ertus2)) -- Отключать `Poco::AbstractConfiguration` подстановки в запрос `clickhouse-client`. [\#6706](https://github.com/ClickHouse/ClickHouse/pull/6706) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Избегайте тупиковых ситуаций в `REPLACE PARTITION`. [\#6677](https://github.com/ClickHouse/ClickHouse/pull/6677) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- С помощью `arrayReduce` для постоянных аргументов может привести к обработка выхода онлайн / оффлайн. [\#6242](https://github.com/ClickHouse/ClickHouse/issues/6242) [\#6326](https://github.com/ClickHouse/ClickHouse/pull/6326) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте несогласованные детали, которые могут появиться, если реплика была восстановлена после этого `DROP PARTITION`. [\#6522](https://github.com/ClickHouse/ClickHouse/issues/6522) [\#6523](https://github.com/ClickHouse/ClickHouse/pull/6523) ([тавплубикс](https://github.com/tavplubix)) -- Исправлено зависание `JSONExtractRaw` функция. [\#6195](https://github.com/ClickHouse/ClickHouse/issues/6195) [\#6198](https://github.com/ClickHouse/ClickHouse/pull/6198) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка с неправильной сериализацией индексов пропуска и агрегацией с адаптивной детализацией. [\#6594](https://github.com/ClickHouse/ClickHouse/issues/6594). [\#6748](https://github.com/ClickHouse/ClickHouse/pull/6748) ([алесапин](https://github.com/alesapin)) -- Чинить `WITH ROLLUP` и `WITH CUBE` модификаторы `GROUP BY` с двухуровневой агрегацией. [\#6225](https://github.com/ClickHouse/ClickHouse/pull/6225) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена ошибка с написанием вторичных индексных меток с адаптивной детализацией. [\#6126](https://github.com/ClickHouse/ClickHouse/pull/6126) ([алесапин](https://github.com/alesapin)) -- Исправьте порядок инициализации при запуске сервера. С `StorageMergeTree::background_task_handle` инициализируется в `startup()` то `MergeTreeBlockOutputStream::write()` возможно, вы попытаетесь использовать его перед инициализацией. Просто проверьте, инициализирован ли он. [\#6080](https://github.com/ClickHouse/ClickHouse/pull/6080) ([Иван](https://github.com/abyss7)) -- Очистка буфера данных от предыдущей операции чтения, которая была завершена с ошибкой. [\#6026](https://github.com/ClickHouse/ClickHouse/pull/6026) ([Николай](https://github.com/bopohaa)) -- Исправлена ошибка с включением адаптивной детализации при создании новой реплики для реплицированной таблицы \* MergeTree. [\#6394](https://github.com/ClickHouse/ClickHouse/issues/6394) [\#6452](https://github.com/ClickHouse/ClickHouse/pull/6452) ([алесапин](https://github.com/alesapin)) -- Исправлена возможная ошибка при запуске сервера в случае возникновения исключения `libunwind` во время исключения при доступе к неинициализированному `ThreadStatus` структура. [\#6456](https://github.com/ClickHouse/ClickHouse/pull/6456) ([Никита Михайлов](https://github.com/nikitamikhaylov)) -- Исправить сбой в работе `yandexConsistentHash` функция. Найдено с помощью теста fuzz. [\#6304](https://github.com/ClickHouse/ClickHouse/issues/6304) [\#6305](https://github.com/ClickHouse/ClickHouse/pull/6305) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена возможность зависания запросов, когда сервер перегружен и глобальный пул потоков становится почти полным. Это имеет более высокие шансы произойти в кластерах с большим количеством сегментов (сотни), поскольку распределенные запросы выделяют поток для каждого соединения с каждым сегментом. Например, эта проблема может возникнуть, если кластер из 330 сегментов обрабатывает 30 параллельных распределенных запросов. Эта проблема затрагивает все версии, начиная с версии 19.2. [\#6301](https://github.com/ClickHouse/ClickHouse/pull/6301) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Фиксированная логика работы `arrayEnumerateUniqRanked` функция. [\#6423](https://github.com/ClickHouse/ClickHouse/pull/6423) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка segfault при декодировании таблицы символов. [\#6603](https://github.com/ClickHouse/ClickHouse/pull/6603) ([Амос Птица](https://github.com/amosbird)) -- Исправлено неуместное исключение в приведении `LowCardinality(Nullable)` to not-Nullable column in case if it doesn't contain Nulls (e.g. in query like `SELECT CAST(CAST('Hello' AS LowCardinality(Nullable(String))) AS String)`. [\#6094](https://github.com/ClickHouse/ClickHouse/issues/6094) [\#6119](https://github.com/ClickHouse/ClickHouse/pull/6119) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Удалено дополнительное цитирование описания в `system.settings` стол. [\#6696](https://github.com/ClickHouse/ClickHouse/issues/6696) [\#6699](https://github.com/ClickHouse/ClickHouse/pull/6699) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Избегайте возможных тупиков в работе `TRUNCATE` из реплицированной таблицы. [\#6695](https://github.com/ClickHouse/ClickHouse/pull/6695) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте чтение в порядке сортировки ключа. [\#6189](https://github.com/ClickHouse/ClickHouse/pull/6189) ([Антон Попов](https://github.com/CurtizJ)) -- Чинить `ALTER TABLE ... UPDATE` запрос для таблиц с `enable_mixed_granularity_parts=1`. [\#6543](https://github.com/ClickHouse/ClickHouse/pull/6543) ([алесапин](https://github.com/alesapin)) -- Исправить ошибку, открытую [\#4405](https://github.com/ClickHouse/ClickHouse/pull/4405) (начиная с 19.4.0). Воспроизводится в запросах к распределенным таблицам через таблицы MergeTree, когда мы не запрашиваем никаких столбцов (`SELECT 1`). [\#6236](https://github.com/ClickHouse/ClickHouse/pull/6236) ([алесапин](https://github.com/alesapin)) -- Исправлено переполнение при целочисленном делении знакового типа на беззнаковый. Поведение было точно таким же, как в языке C или C++ (целочисленные правила продвижения), что может быть удивительно. Обратите внимание, что переполнение все еще возможно при делении большого числа со знаком на большое число без знака или наоборот (но этот случай менее обычен). Эта проблема существовала во всех версиях сервера. [\#6214](https://github.com/ClickHouse/ClickHouse/issues/6214) [\#6233](https://github.com/ClickHouse/ClickHouse/pull/6233) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Ограничьте максимальное время сна для дросселирования, когда `max_execution_speed` или `max_execution_speed_bytes` заданный. Исправлены ложные ошибки, такие как `Estimated query execution time (inf seconds) is too long`. [\#5547](https://github.com/ClickHouse/ClickHouse/issues/5547) [\#6232](https://github.com/ClickHouse/ClickHouse/pull/6232) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлены проблемы, связанные с использованием `MATERIALIZED` столбцы и псевдонимы в `MaterializedView`. [\#448](https://github.com/ClickHouse/ClickHouse/issues/448) [\#3484](https://github.com/ClickHouse/ClickHouse/issues/3484) [\#3450](https://github.com/ClickHouse/ClickHouse/issues/3450) [\#2878](https://github.com/ClickHouse/ClickHouse/issues/2878) [\#2285](https://github.com/ClickHouse/ClickHouse/issues/2285) [\#3796](https://github.com/ClickHouse/ClickHouse/pull/3796) ([Амос Птица](https://github.com/amosbird)) [\#6316](https://github.com/ClickHouse/ClickHouse/pull/6316) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Чинить `FormatFactory` поведение для входных потоков, которые не реализованы в качестве процессора. [\#6495](https://github.com/ClickHouse/ClickHouse/pull/6495) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлена опечатка. [\#6631](https://github.com/ClickHouse/ClickHouse/pull/6631) ([Алексей Рындин](https://github.com/alexryndin)) -- Опечатка в сообщении об ошибке (is - \> are). [\#6839](https://github.com/ClickHouse/ClickHouse/pull/6839) ([Денис Журавлев](https://github.com/den-crane)) -- Исправлена ошибка при разборе списка столбцов из строки, Если тип содержал запятую (эта проблема была актуальна для `File`, `URL`, `HDFS` хранения) [\#6217](https://github.com/ClickHouse/ClickHouse/issues/6217). [\#6209](https://github.com/ClickHouse/ClickHouse/pull/6209) ([dimarub2000](https://github.com/dimarub2000)) - -#### Исправление безопасности {#security-fix} - -- Этот релиз также содержит все исправления безопасности ошибок от 19.13 и 19.11. -- Исправлена возможность сфабрикованного запроса вызвать сбой сервера из-за переполнения стека в синтаксическом анализаторе SQL. Исправлена возможность переполнения стека в таблицах слияния и распределения, материализованных представлениях и условиях безопасности на уровне строк, включающих подзапросы. [\#6433](https://github.com/ClickHouse/ClickHouse/pull/6433) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшение {#improvement-3} - -- Правильная реализация троичной логики для `AND/OR`. [\#6048](https://github.com/ClickHouse/ClickHouse/pull/6048) ([Александр казаков](https://github.com/Akazz)) -- Теперь значения и строки с истекшим сроком действия TTL будут удалены после этого `OPTIMIZE ... FINAL` query from old parts without TTL infos or with outdated TTL infos, e.g. after `ALTER ... MODIFY TTL` запрос. Добавленные запросы `SYSTEM STOP/START TTL MERGES` чтобы запретить / разрешить назначать слияния с TTL и фильтровать просроченные значения во всех слияниях. [\#6274](https://github.com/ClickHouse/ClickHouse/pull/6274) ([Антон Попов](https://github.com/CurtizJ)) -- Возможность изменить расположение файла истории ClickHouse для использования клиентом `CLICKHOUSE_HISTORY_FILE` ОКР. [\#6840](https://github.com/ClickHouse/ClickHouse/pull/6840) ([Филимонов](https://github.com/filimonov)) -- Удалять `dry_run` флаг от `InterpreterSelectQuery`. … [\#6375](https://github.com/ClickHouse/ClickHouse/pull/6375) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Поддержка `ASOF JOIN` с `ON` раздел. [\#6211](https://github.com/ClickHouse/ClickHouse/pull/6211) ([Артем Зуйков](https://github.com/4ertus2)) -- Улучшенная поддержка индексов пропуска для мутаций и репликации. Поддержка `MATERIALIZE/CLEAR INDEX ... IN PARTITION` запрос. `UPDATE x = x` пересчитывает все индексы, использующие столбец `x`. [\#5053](https://github.com/ClickHouse/ClickHouse/pull/5053) ([Никита Васильев](https://github.com/nikvas0)) -- Разрешить `ATTACH` живые представления (например, при запуске сервера) независимо от того, чтобы `allow_experimental_live_view` установка. [\#6754](https://github.com/ClickHouse/ClickHouse/pull/6754) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Для трассировок стека, собранных профилировщиком запросов, не включайте кадры стека, созданные самим профилировщиком запросов. [\#6250](https://github.com/ClickHouse/ClickHouse/pull/6250) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Теперь функции таблицы `values`, `file`, `url`, `hdfs` есть поддержка столбцов псевдонимов. [\#6255](https://github.com/ClickHouse/ClickHouse/pull/6255) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Создайте исключение, если `config.d` файл не имеет соответствующего корневого элемента в качестве файла конфигурации. [\#6123](https://github.com/ClickHouse/ClickHouse/pull/6123) ([dimarub2000](https://github.com/dimarub2000)) -- Распечатайте дополнительную информацию в сообщении об исключении для `no space left on device`. [\#6182](https://github.com/ClickHouse/ClickHouse/issues/6182), [\#6252](https://github.com/ClickHouse/ClickHouse/issues/6252) [\#6352](https://github.com/ClickHouse/ClickHouse/pull/6352) ([тавплубикс](https://github.com/tavplubix)) -- При определении осколков а `Distributed` таблица, которая будет покрыта запросом на чтение (для `optimize_skip_unused_shards` = 1) ClickHouse теперь проверяет условия от обоих `prewhere` и `where` предложения оператора select. [\#6521](https://github.com/ClickHouse/ClickHouse/pull/6521) ([Александр казаков](https://github.com/Akazz)) -- Включенный `SIMDJSON` для машин без AVX2, но с набором инструкций SSE 4.2 и PCLMUL. [\#6285](https://github.com/ClickHouse/ClickHouse/issues/6285) [\#6320](https://github.com/ClickHouse/ClickHouse/pull/6320) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- ClickHouse может работать на файловых системах без `O_DIRECT` поддержка (например, ZFS и BtrFS) без дополнительной настройки. [\#4449](https://github.com/ClickHouse/ClickHouse/issues/4449) [\#6730](https://github.com/ClickHouse/ClickHouse/pull/6730) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Поддержка push down предиката для окончательного подзапроса. [\#6120](https://github.com/ClickHouse/ClickHouse/pull/6120) ([TCeason](https://github.com/TCeason)) [\#6162](https://github.com/ClickHouse/ClickHouse/pull/6162) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Лучше `JOIN ON` извлечение ключей [\#6131](https://github.com/ClickHouse/ClickHouse/pull/6131) ([Артем Зуйков](https://github.com/4ertus2)) -- Обновление `SIMDJSON`. [\#6285](https://github.com/ClickHouse/ClickHouse/issues/6285). [\#6306](https://github.com/ClickHouse/ClickHouse/pull/6306) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Оптимизируйте выбор самого маленького столбца для `SELECT count()` запрос. [\#6344](https://github.com/ClickHouse/ClickHouse/pull/6344) ([Амос Птица](https://github.com/amosbird)) -- Добавлен `strict` параметр в `windowFunnel()`. Когда `strict` устанавливается, то `windowFunnel()` применяет условия только для уникальных значений. [\#6548](https://github.com/ClickHouse/ClickHouse/pull/6548) ([ачимбаб](https://github.com/achimbab)) -- Более безопасный интерфейс `mysqlxx::Pool`. [\#6150](https://github.com/ClickHouse/ClickHouse/pull/6150) ([авасилиев](https://github.com/avasiliev)) -- Параметры размер строки при выполнении с помощью `--help` опция теперь соответствует размеру терминала. [\#6590](https://github.com/ClickHouse/ClickHouse/pull/6590) ([dimarub2000](https://github.com/dimarub2000)) -- Отключать «read in order» оптимизация для агрегации без ключей. [\#6599](https://github.com/ClickHouse/ClickHouse/pull/6599) ([Антон Попов](https://github.com/CurtizJ)) -- Код состояния HTTP для `INCORRECT_DATA` и `TYPE_MISMATCH` коды ошибок были изменены по умолчанию `500 Internal Server Error` к `400 Bad Request`. [\#6271](https://github.com/ClickHouse/ClickHouse/pull/6271) ([Александр Родин](https://github.com/a-rodin)) -- Переместить объект соединения из `ExpressionAction` в `AnalyzedJoin`. `ExpressionAnalyzer` и `ExpressionAction` не знаю о чем `Join` больше никаких занятий. Его логика скрыта за `AnalyzedJoin` iface защитный. [\#6801](https://github.com/ClickHouse/ClickHouse/pull/6801) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена возможная взаимоблокировка распределенных запросов, когда один из сегментов является localhost, но запрос отправляется через сетевое соединение. [\#6759](https://github.com/ClickHouse/ClickHouse/pull/6759) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Изменена семантика нескольких таблиц `RENAME` чтобы избежать возможных тупиков. [\#6757](https://github.com/ClickHouse/ClickHouse/issues/6757). [\#6756](https://github.com/ClickHouse/ClickHouse/pull/6756) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Переписан сервер совместимости MySQL, чтобы предотвратить загрузку полной полезной нагрузки пакета в память. Снижение потребления памяти для каждого соединения примерно до `2 * DBMS_DEFAULT_BUFFER_SIZE` (буферы чтения/записи). [\#5811](https://github.com/ClickHouse/ClickHouse/pull/5811) ([Юрий Баранов](https://github.com/yurriy)) -- Переместите логику интерпретации псевдонимов AST из синтаксического анализатора, который не должен ничего знать о семантике запросов. [\#6108](https://github.com/ClickHouse/ClickHouse/pull/6108) ([Артем Зуйков](https://github.com/4ertus2)) -- Чуть более безопасный разбор данных `NamesAndTypesList`. [\#6408](https://github.com/ClickHouse/ClickHouse/issues/6408). [\#6410](https://github.com/ClickHouse/ClickHouse/pull/6410) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `clickhouse-copier`: Разрешить использование `where_condition` из конфигурации с `partition_key` псевдоним в запросе для проверки существования раздела (ранее он использовался только при чтении запросов данных). [\#6577](https://github.com/ClickHouse/ClickHouse/pull/6577) ([proller](https://github.com/proller)) -- Добавлен необязательный аргумент сообщения в поле `throwIf`. ([\#5772](https://github.com/ClickHouse/ClickHouse/issues/5772)) [\#6329](https://github.com/ClickHouse/ClickHouse/pull/6329) ([Вдимир](https://github.com/Vdimir)) -- Исключение сервера, полученное при отправке данных вставки, теперь обрабатывается и в клиенте. [\#5891](https://github.com/ClickHouse/ClickHouse/issues/5891) [\#6711](https://github.com/ClickHouse/ClickHouse/pull/6711) ([dimarub2000](https://github.com/dimarub2000)) -- Добавлена метрика `DistributedFilesToInsert` это показывает общее количество файлов в файловой системе, выбранных для отправки на удаленные серверы распределенными таблицами. Это число суммируется по всем осколкам. [\#6600](https://github.com/ClickHouse/ClickHouse/pull/6600) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Переместите большинство соединений подготовьте логику из `ExpressionAction/ExpressionAnalyzer` к `AnalyzedJoin`. [\#6785](https://github.com/ClickHouse/ClickHouse/pull/6785) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправить Цан [предупреждение](https://clickhouse-test-reports.s3.yandex.net/6399/c1c1d1daa98e199e620766f1bd06a5921050a00d/functional_stateful_tests_(thread).html) ‘lock-order-inversion’. [\#6740](https://github.com/ClickHouse/ClickHouse/pull/6740) ([Василий Немков](https://github.com/Enmk)) -- Улучшенные информационные сообщения об отсутствии возможностей Linux. Протоколирование фатальных ошибок с помощью «fatal» уровень, который будет легче найти в `system.text_log`. [\#6441](https://github.com/ClickHouse/ClickHouse/pull/6441) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Когда включить сброс временных данных на диск, чтобы ограничить использование памяти во время `GROUP BY`, `ORDER BY`, он не проверял свободное место на диске. Исправление добавить новую настройку `min_free_disk_space`, когда свободное место на диске будет меньше порогового значения, запрос остановится и бросит `ErrorCodes::NOT_ENOUGH_SPACE`. [\#6678](https://github.com/ClickHouse/ClickHouse/pull/6678) ([Вэйцин Сюй](https://github.com/weiqxu)) [\#6691](https://github.com/ClickHouse/ClickHouse/pull/6691) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Удален рекурсивной записи по теме. Это не имеет смысла, потому что потоки используются повторно между запросами. `SELECT` запрос может получить Блокировку в одном потоке, удерживать блокировку в другом потоке и выходить из первого потока. В то же время, первый поток может быть повторно использован `DROP` запрос. Это приведет к ложным результатам «Attempt to acquire exclusive lock recursively» сообщения. [\#6771](https://github.com/ClickHouse/ClickHouse/pull/6771) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Расщеплять `ExpressionAnalyzer.appendJoin()`. Подготовьте место в `ExpressionAnalyzer` для `MergeJoin`. [\#6524](https://github.com/ClickHouse/ClickHouse/pull/6524) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавлен `mysql_native_password` плагин аутентификации для сервера совместимости MySQL. [\#6194](https://github.com/ClickHouse/ClickHouse/pull/6194) ([Юрий Баранов](https://github.com/yurriy)) -- Меньшее количество `clock_gettime` вызовы; исправлена совместимость ABI между debug/release in `Allocator` (незначительный вопрос). [\#6197](https://github.com/ClickHouse/ClickHouse/pull/6197) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Подвиньте `collectUsedColumns` от `ExpressionAnalyzer` к `SyntaxAnalyzer`. `SyntaxAnalyzer` делает `required_source_columns` теперь он сам по себе. [\#6416](https://github.com/ClickHouse/ClickHouse/pull/6416) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавить настройку `joined_subquery_requires_alias` чтобы требовать псевдонимы для подселектов и табличных функций в `FROM` that more than one table is present (i.e. queries with JOINs). [\#6733](https://github.com/ClickHouse/ClickHouse/pull/6733) ([Артем Зуйков](https://github.com/4ertus2)) -- Извлекать `GetAggregatesVisitor` класс от `ExpressionAnalyzer`. [\#6458](https://github.com/ClickHouse/ClickHouse/pull/6458) ([Артем Зуйков](https://github.com/4ertus2)) -- `system.query_log`: изменение типа данных `type` столбец `Enum`. [\#6265](https://github.com/ClickHouse/ClickHouse/pull/6265) ([Никита Михайлов](https://github.com/nikitamikhaylov)) -- Статическое соединение `sha256_password` плагин аутентификации. [\#6512](https://github.com/ClickHouse/ClickHouse/pull/6512) ([Юрий Баранов](https://github.com/yurriy)) -- Избегайте дополнительной зависимости для настройки `compile` работать. В предыдущих версиях пользователь может получить ошибку типа `cannot open crti.o`, `unable to find library -lc` и т.д. [\#6309](https://github.com/ClickHouse/ClickHouse/pull/6309) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Дополнительная проверка входных данных, которые могут быть получены от вредоносной реплики. [\#6303](https://github.com/ClickHouse/ClickHouse/pull/6303) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Сейчас `clickhouse-obfuscator` файл доступен в формате `clickhouse-client` пакет. В предыдущих версиях он был доступен как `clickhouse obfuscator` (с пробелами). [\#5816](https://github.com/ClickHouse/ClickHouse/issues/5816) [\#6609](https://github.com/ClickHouse/ClickHouse/pull/6609) ([dimarub2000](https://github.com/dimarub2000)) -- Исправлена взаимоблокировка, когда у нас есть по крайней мере два запроса, которые читают по крайней мере две таблицы в разном порядке, и еще один запрос, который выполняет операцию DDL на одной из таблиц. Исправлена еще одна очень редкая тупиковая ситуация. [\#6764](https://github.com/ClickHouse/ClickHouse/pull/6764) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлен `os_thread_ids` столбец `system.processes` и `system.query_log` для улучшения возможностей отладки. [\#6763](https://github.com/ClickHouse/ClickHouse/pull/6763) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Обходной путь для ошибок расширения PHP mysqlnd, которые возникают, когда `sha256_password` используется в качестве плагина аутентификации по умолчанию (описано в разделе [\#6031](https://github.com/ClickHouse/ClickHouse/issues/6031)). [\#6113](https://github.com/ClickHouse/ClickHouse/pull/6113) ([Юрий Баранов](https://github.com/yurriy)) -- Удалите ненужное место с измененными столбцами nullability. [\#6693](https://github.com/ClickHouse/ClickHouse/pull/6693) ([Артем Зуйков](https://github.com/4ertus2)) -- Установите значение по умолчанию: `queue_max_wait_ms` до нуля, потому что текущее значение (пять секунд) не имеет никакого смысла. Есть редкие обстоятельства, когда эта настройка имеет какое-либо применение. Добавлены настройки `replace_running_query_max_wait_ms`, `kafka_max_wait_ms` и `connection_pool_max_wait_ms` для устранения двусмысленности. [\#6692](https://github.com/ClickHouse/ClickHouse/pull/6692) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Извлекать `SelectQueryExpressionAnalyzer` от `ExpressionAnalyzer`. Оставьте последний вариант для запросов, не связанных с выбором. [\#6499](https://github.com/ClickHouse/ClickHouse/pull/6499) ([Артем Зуйков](https://github.com/4ertus2)) -- Удалено дублирование входных и выходных форматов. [\#6239](https://github.com/ClickHouse/ClickHouse/pull/6239) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Позволяет пользователю переопределить `poll_interval` и `idle_connection_timeout` настройки при подключении. [\#6230](https://github.com/ClickHouse/ClickHouse/pull/6230) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `MergeTree` теперь есть дополнительная опция `ttl_only_drop_parts` (отключено по умолчанию), чтобы избежать частичной обрезки деталей, чтобы они полностью выпадали, когда все строки в детали истекли. [\#6191](https://github.com/ClickHouse/ClickHouse/pull/6191) ([Сергей Владыкин](https://github.com/svladykin)) -- Тип проверяет наличие заданных индексных функций. Бросьте исключение, если функция получила неправильный тип. Это устраняет тестирования с помощью утилиты. [\#6511](https://github.com/ClickHouse/ClickHouse/pull/6511) ([Никита Васильев](https://github.com/nikvas0)) - -#### Улучшение производительности {#performance-improvement-2} - -- Оптимизируйте запросы с помощью `ORDER BY expressions` пункт, где `expressions` есть совпадающий префикс с ключом сортировки в `MergeTree` таблицы. Эта оптимизация управляется с помощью `optimize_read_in_order` установка. [\#6054](https://github.com/ClickHouse/ClickHouse/pull/6054) [\#6629](https://github.com/ClickHouse/ClickHouse/pull/6629) ([Антон Попов](https://github.com/CurtizJ)) -- Позволяет использовать несколько резьб при загрузке и демонтаже деталей. [\#6372](https://github.com/ClickHouse/ClickHouse/issues/6372) [\#6074](https://github.com/ClickHouse/ClickHouse/issues/6074) [\#6438](https://github.com/ClickHouse/ClickHouse/pull/6438) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Реализован пакетный вариант обновления состояний агрегатной функции. Это может привести к повышению производительности. [\#6435](https://github.com/ClickHouse/ClickHouse/pull/6435) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- С помощью `FastOps` библиотека для функций `exp`, `log`, `sigmoid`, `tanh`. FastOps-это быстрая векторная математическая библиотека от Михаила Парахина (технический директор Яндекса). Улучшенная производительность `exp` и `log` функции более чем в 6 раз. Функция `exp` и `log` от `Float32` аргумент вернется `Float32` (в предыдущих версиях они всегда возвращаются `Float64`). Сейчас `exp(nan)` может вернуться `inf`. Результат работы `exp` и `log` функции могут быть не самым близким машинным представимым числом к истинному ответу. [\#6254](https://github.com/ClickHouse/ClickHouse/pull/6254) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) Используя вариант Данилы Кутенина, чтобы сделать fastops работающими [\#6317](https://github.com/ClickHouse/ClickHouse/pull/6317) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Отключить последовательную оптимизацию ключа для `UInt8/16`. [\#6298](https://github.com/ClickHouse/ClickHouse/pull/6298) [\#6701](https://github.com/ClickHouse/ClickHouse/pull/6701) ([акузм](https://github.com/akuzm)) -- Улучшенная производительность `simdjson` библиотека, избавившись от динамического распределения в `ParsedJson::Iterator`. [\#6479](https://github.com/ClickHouse/ClickHouse/pull/6479) ([Виталий Баранов](https://github.com/vitlibar)) -- Предаварийные страницы при выделении памяти с помощью `mmap()`. [\#6667](https://github.com/ClickHouse/ClickHouse/pull/6667) ([акузм](https://github.com/akuzm)) -- Исправлена ошибка производительности в `Decimal` сравнение. [\#6380](https://github.com/ClickHouse/ClickHouse/pull/6380) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-4} - -- Удалите компилятор (экземпляр шаблона времени выполнения), потому что мы выиграли его производительность. [\#6646](https://github.com/ClickHouse/ClickHouse/pull/6646) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлен тест производительности, чтобы показать ухудшение производительности в gcc-9 более изолированным способом. [\#6302](https://github.com/ClickHouse/ClickHouse/pull/6302) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена функция таблицы `numbers_mt`, который является многопоточным вариантом `numbers`. Обновленные тесты производительности с хэш-функциями. [\#6554](https://github.com/ClickHouse/ClickHouse/pull/6554) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Режим сравнения в `clickhouse-benchmark` [\#6220](https://github.com/ClickHouse/ClickHouse/issues/6220) [\#6343](https://github.com/ClickHouse/ClickHouse/pull/6343) ([dimarub2000](https://github.com/dimarub2000)) -- Самое лучшее усилие для печати следов стека. Также добавить `SIGPROF` в качестве отладочного сигнала для печати трассировки стека запущенного потока. [\#6529](https://github.com/ClickHouse/ClickHouse/pull/6529) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Каждая функция в своем собственном файле, часть 10. [\#6321](https://github.com/ClickHouse/ClickHouse/pull/6321) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Удалить два раза константный `TABLE_IS_READ_ONLY`. [\#6566](https://github.com/ClickHouse/ClickHouse/pull/6566) ([Филимонов](https://github.com/filimonov)) -- Изменения форматирования для `StringHashMap` PR [\#5417](https://github.com/ClickHouse/ClickHouse/issues/5417). [\#6700](https://github.com/ClickHouse/ClickHouse/pull/6700) ([акузм](https://github.com/akuzm)) -- Лучший подзапрос для создания соединения в `ExpressionAnalyzer`. [\#6824](https://github.com/ClickHouse/ClickHouse/pull/6824) ([Артем Зуйков](https://github.com/4ertus2)) -- Удалить ненужное состояние (найденных с помощью PVS-студия). [\#6775](https://github.com/ClickHouse/ClickHouse/pull/6775) ([акузм](https://github.com/akuzm)) -- Разделите интерфейс хэш-таблицы для `ReverseIndex`. [\#6672](https://github.com/ClickHouse/ClickHouse/pull/6672) ([акузм](https://github.com/akuzm)) -- Рефакторинг настроек. [\#6689](https://github.com/ClickHouse/ClickHouse/pull/6689) ([алесапин](https://github.com/alesapin)) -- Добавить комментарии для `set` индексные функции. [\#6319](https://github.com/ClickHouse/ClickHouse/pull/6319) ([Никита Васильев](https://github.com/nikvas0)) -- Увеличьте оценку OOM в отладочной версии на Linux. [\#6152](https://github.com/ClickHouse/ClickHouse/pull/6152) ([акузм](https://github.com/akuzm)) -- HDFS HA теперь работает в debug build. [\#6650](https://github.com/ClickHouse/ClickHouse/pull/6650) ([Вэйцин Сюй](https://github.com/weiqxu)) -- Добавлен тест на `transform_query_for_external_database`. [\#6388](https://github.com/ClickHouse/ClickHouse/pull/6388) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте тест для нескольких материализованных представлений для таблицы Кафки. [\#6509](https://github.com/ClickHouse/ClickHouse/pull/6509) ([Иван](https://github.com/abyss7)) -- Сделайте лучшую схему сборки. [\#6500](https://github.com/ClickHouse/ClickHouse/pull/6500) ([Иван](https://github.com/abyss7)) -- Исправлено `test_external_dictionaries` интеграция в случае, если она была выполнена под некорневым пользователем. [\#6507](https://github.com/ClickHouse/ClickHouse/pull/6507) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Ошибка воспроизводится, когда общий размер записанных пакетов превышает `DBMS_DEFAULT_BUFFER_SIZE`. [\#6204](https://github.com/ClickHouse/ClickHouse/pull/6204) ([Юрий Баранов](https://github.com/yurriy)) -- Добавлен тест для `RENAME` состояние гонки таблицы [\#6752](https://github.com/ClickHouse/ClickHouse/pull/6752) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Избегайте гонки данных по настройкам в `KILL QUERY`. [\#6753](https://github.com/ClickHouse/ClickHouse/pull/6753) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте интеграционный тест для обработки ошибок с помощью словаря кэша. [\#6755](https://github.com/ClickHouse/ClickHouse/pull/6755) ([Виталий Баранов](https://github.com/vitlibar)) -- Отключите синтаксический анализ объектных файлов ELF на Mac OS, потому что это не имеет никакого смысла. [\#6578](https://github.com/ClickHouse/ClickHouse/pull/6578) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Попытайтесь сделать генератор списка изменений лучше. [\#6327](https://github.com/ClickHouse/ClickHouse/pull/6327) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавление `-Wshadow` перейти к ССЗ. [\#6325](https://github.com/ClickHouse/ClickHouse/pull/6325) ([kreuzerkrieg](https://github.com/kreuzerkrieg)) -- Удален устаревший код для `mimalloc` поддержка. [\#6715](https://github.com/ClickHouse/ClickHouse/pull/6715) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `zlib-ng` определяет возможности x86 и сохраняет эту информацию в глобальных переменных. Это делается в вызове defalteInit, который может быть выполнен разными потоками одновременно. Чтобы избежать многопоточной записи, сделайте это при запуске библиотеки. [\#6141](https://github.com/ClickHouse/ClickHouse/pull/6141) ([акузм](https://github.com/akuzm)) -- Регрессионный тест на ошибку, которая в соединении была исправлена в [\#5192](https://github.com/ClickHouse/ClickHouse/issues/5192). [\#6147](https://github.com/ClickHouse/ClickHouse/pull/6147) ([Бахтиер Рузиев](https://github.com/theruziev)) -- Исправлен отчет MSan. [\#6144](https://github.com/ClickHouse/ClickHouse/pull/6144) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте хлопающий тест TTL. [\#6782](https://github.com/ClickHouse/ClickHouse/pull/6782) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена гонка ложных данных в `MergeTreeDataPart::is_frozen` поле. [\#6583](https://github.com/ClickHouse/ClickHouse/pull/6583) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлены тайм-ауты в тесте fuzz. В предыдущей версии ему удалось найти ложное зависание в запросе `SELECT * FROM numbers_mt(gccMurmurHash(''))`. [\#6582](https://github.com/ClickHouse/ClickHouse/pull/6582) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлены отладочные проверки для `static_cast` из колонн. [\#6581](https://github.com/ClickHouse/ClickHouse/pull/6581) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Поддержка Oracle Linux в официальных пакетах RPM. [\#6356](https://github.com/ClickHouse/ClickHouse/issues/6356) [\#6585](https://github.com/ClickHouse/ClickHouse/pull/6585) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Изменен JSON perftests с `once` к `loop` тип. [\#6536](https://github.com/ClickHouse/ClickHouse/pull/6536) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- `odbc-bridge.cpp` определяет `main()` поэтому он не должен быть включен в состав `clickhouse-lib`. [\#6538](https://github.com/ClickHouse/ClickHouse/pull/6538) ([Оривей Деш](https://github.com/orivej)) -- Тест на аварийное включение `FULL|RIGHT JOIN` с нулями в ключах правого стола. [\#6362](https://github.com/ClickHouse/ClickHouse/pull/6362) ([Артем Зуйков](https://github.com/4ertus2)) -- На всякий случай добавлен тест на ограничение по расширению псевдонимов. [\#6442](https://github.com/ClickHouse/ClickHouse/pull/6442) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Переключился с `boost::filesystem` к `std::filesystem` при необходимости. [\#6253](https://github.com/ClickHouse/ClickHouse/pull/6253) [\#6385](https://github.com/ClickHouse/ClickHouse/pull/6385) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлены пакеты RPM на веб-сайт. [\#6251](https://github.com/ClickHouse/ClickHouse/pull/6251) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте тест для фиксированного `Unknown identifier` исключение в `IN` раздел. [\#6708](https://github.com/ClickHouse/ClickHouse/pull/6708) ([Артем Зуйков](https://github.com/4ertus2)) -- Упрощать `shared_ptr_helper` потому что люди сталкиваются с трудностями понимания этого. [\#6675](https://github.com/ClickHouse/ClickHouse/pull/6675) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлены тесты производительности для исправленных кодеков Gorilla и DoubleDelta. [\#6179](https://github.com/ClickHouse/ClickHouse/pull/6179) ([Василий Немков](https://github.com/Enmk)) -- Разделите интеграционный тест `test_dictionaries` в 4 отдельных теста. [\#6776](https://github.com/ClickHouse/ClickHouse/pull/6776) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправить предупреждение PVS-Studio в `PipelineExecutor`. [\#6777](https://github.com/ClickHouse/ClickHouse/pull/6777) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Разрешить использовать `library` источник словаря с ASan. [\#6482](https://github.com/ClickHouse/ClickHouse/pull/6482) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена возможность генерировать список изменений из списка PR. [\#6350](https://github.com/ClickHouse/ClickHouse/pull/6350) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Заприте дверь `TinyLog` хранение при чтении. [\#6226](https://github.com/ClickHouse/ClickHouse/pull/6226) ([акузм](https://github.com/akuzm)) -- Проверить неработающие ссылки в ИЦ. [\#6634](https://github.com/ClickHouse/ClickHouse/pull/6634) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Увеличьте тайм-аут для «stack overflow» тест, потому что это может занять много времени в отладочной сборке. [\#6637](https://github.com/ClickHouse/ClickHouse/pull/6637) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена проверка на наличие двойных пробелов. [\#6643](https://github.com/ClickHouse/ClickHouse/pull/6643) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Чинить `new/delete` отслеживание памяти при сборке с помощью дезинфицирующих средств. Слежка не совсем ясна. Это только предотвращает исключения ограничения памяти в тестах. [\#6450](https://github.com/ClickHouse/ClickHouse/pull/6450) ([Артем Зуйков](https://github.com/4ertus2)) -- Включите обратную проверку неопределенных символов при связывании. [\#6453](https://github.com/ClickHouse/ClickHouse/pull/6453) ([Иван](https://github.com/abyss7)) -- Избежать восстановления `hyperscan` каждый день. [\#6307](https://github.com/ClickHouse/ClickHouse/pull/6307) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен отчет утилиты в `ProtobufWriter`. [\#6163](https://github.com/ClickHouse/ClickHouse/pull/6163) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Не разрешайте использовать query profiler с дезинфицирующими средствами, потому что он не совместим. [\#6769](https://github.com/ClickHouse/ClickHouse/pull/6769) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте тест для перезагрузки словаря после сбоя по таймеру. [\#6114](https://github.com/ClickHouse/ClickHouse/pull/6114) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправить несоответствие `PipelineExecutor::prepareProcessor` тип аргумента. [\#6494](https://github.com/ClickHouse/ClickHouse/pull/6494) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Добавлен тест на плохие URI. [\#6493](https://github.com/ClickHouse/ClickHouse/pull/6493) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлены дополнительные проверки для `CAST` функция. Это должно получить больше информации о неисправности сегментации в нечетком тесте. [\#6346](https://github.com/ClickHouse/ClickHouse/pull/6346) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Добавлен `gcc-9` поддержка для `docker/builder` контейнер, который создает образ локально. [\#6333](https://github.com/ClickHouse/ClickHouse/pull/6333) ([Глеб Новиков](https://github.com/NanoBjorn)) -- Тест для первичного ключа с помощью `LowCardinality(String)`. [\#5044](https://github.com/ClickHouse/ClickHouse/issues/5044) [\#6219](https://github.com/ClickHouse/ClickHouse/pull/6219) ([dimarub2000](https://github.com/dimarub2000)) -- Исправлены тесты, связанные с медленной печатью трассировок стека. [\#6315](https://github.com/ClickHouse/ClickHouse/pull/6315) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте тестовый случай для аварийного входа `groupUniqArray` фиксированной в [\#6029](https://github.com/ClickHouse/ClickHouse/pull/6029). [\#4402](https://github.com/ClickHouse/ClickHouse/issues/4402) [\#6129](https://github.com/ClickHouse/ClickHouse/pull/6129) ([акузм](https://github.com/akuzm)) -- Фиксированные индексы мутаций тестов. [\#6645](https://github.com/ClickHouse/ClickHouse/pull/6645) ([Никита Васильев](https://github.com/nikvas0)) -- В тесте производительности не считывайте журнал запросов для запросов, которые мы не выполняли. [\#6427](https://github.com/ClickHouse/ClickHouse/pull/6427) ([акузм](https://github.com/akuzm)) -- Материализованное представление теперь может быть создано с любыми типами низкой мощности независимо от настройки о подозрительных типах низкой мощности. [\#6428](https://github.com/ClickHouse/ClickHouse/pull/6428) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Обновленные тесты для `send_logs_level` установка. [\#6207](https://github.com/ClickHouse/ClickHouse/pull/6207) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлена сборка под gcc-8.2. [\#6196](https://github.com/ClickHouse/ClickHouse/pull/6196) ([Макс Ахмедов](https://github.com/zlobober)) -- Исправлена сборка с помощью внутреннего libc++. [\#6724](https://github.com/ClickHouse/ClickHouse/pull/6724) ([Иван](https://github.com/abyss7)) -- Исправлена общая сборка с помощью `rdkafka` библиотека [\#6101](https://github.com/ClickHouse/ClickHouse/pull/6101) ([Иван](https://github.com/abyss7)) -- Исправления для сборки Mac OS (неполные). [\#6390](https://github.com/ClickHouse/ClickHouse/pull/6390) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) [\#6429](https://github.com/ClickHouse/ClickHouse/pull/6429) ([Алексей-Зайцев](https://github.com/alex-zaitsev)) -- Чинить «splitted» строить. [\#6618](https://github.com/ClickHouse/ClickHouse/pull/6618) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Другие исправления сборки: [\#6186](https://github.com/ClickHouse/ClickHouse/pull/6186) ([Амос Птица](https://github.com/amosbird)) [\#6486](https://github.com/ClickHouse/ClickHouse/pull/6486) [\#6348](https://github.com/ClickHouse/ClickHouse/pull/6348) ([vxider](https://github.com/Vxider)) [\#6744](https://github.com/ClickHouse/ClickHouse/pull/6744) ([Иван](https://github.com/abyss7)) [\#6016](https://github.com/ClickHouse/ClickHouse/pull/6016) [\#6421](https://github.com/ClickHouse/ClickHouse/pull/6421) [\#6491](https://github.com/ClickHouse/ClickHouse/pull/6491) ([proller](https://github.com/proller)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-3} - -- Удалены редко используемые функции таблица `catBoostPool` и хранение `CatBoostPool`. Если вы использовали эту функцию таблицы, пожалуйста, напишите письмо по адресу `clickhouse-feedback@yandex-team.com`. Обратите внимание, что интеграция CatBoost остается и будет поддерживаться. [\#6279](https://github.com/ClickHouse/ClickHouse/pull/6279) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Отключать `ANY RIGHT JOIN` и `ANY FULL JOIN` по умолчанию. Набор `any_join_distinct_right_table_keys` настройка для их включения. [\#5126](https://github.com/ClickHouse/ClickHouse/issues/5126) [\#6351](https://github.com/ClickHouse/ClickHouse/pull/6351) ([Артем Зуйков](https://github.com/4ertus2)) - -## ClickHouse релиз 19.13 {#clickhouse-release-19-13} - -### ClickHouse релиз 19.13.6.51, 2019-10-02 {#clickhouse-release-19-13-6-51-2019-10-02} - -#### Исправление ошибок {#bug-fix-9} - -- Этот релиз также содержит все исправления ошибок от 19.11.12.69. - -### ClickHouse релиз 19.13.5.44, 2019-09-20 {#clickhouse-release-19-13-5-44-2019-09-20} - -#### Исправление ошибок {#bug-fix-10} - -- Этот релиз также содержит все исправления ошибок от 19.14.6.12. -- Исправлено возможное несогласованное состояние таблицы при выполнении `DROP` запрос для реплицированной таблицы в то время как zookeeper недоступен. [\#6045](https://github.com/ClickHouse/ClickHouse/issues/6045) [\#6413](https://github.com/ClickHouse/ClickHouse/pull/6413) ([Никита Михайлов](https://github.com/nikitamikhaylov)) -- Исправление для гонки данных в StorageMerge [\#6717](https://github.com/ClickHouse/ClickHouse/pull/6717) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, появившаяся в профайлером запрос, который приводит к бесконечному приему от гнезда. [\#6386](https://github.com/ClickHouse/ClickHouse/pull/6386) ([алесапин](https://github.com/alesapin)) -- Исправлена чрезмерная загрузка процессора во время выполнения `JSONExtractRaw` функция над логическим значением. [\#6208](https://github.com/ClickHouse/ClickHouse/pull/6208) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправляет регрессию при нажатии на материализованный вид. [\#6415](https://github.com/ClickHouse/ClickHouse/pull/6415) ([Иван](https://github.com/abyss7)) -- Табличная функция `url` если бы эта уязвимость позволяла злоумышленнику вводить произвольные HTTP-заголовки в запрос. Эта проблема была обнаружена [Никита Тихомиров](https://github.com/NSTikhomirov). [\#6466](https://github.com/ClickHouse/ClickHouse/pull/6466) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлять бесполезно `AST` проверьте установленный индекс. [\#6510](https://github.com/ClickHouse/ClickHouse/issues/6510) [\#6651](https://github.com/ClickHouse/ClickHouse/pull/6651) ([Никита Васильев](https://github.com/nikvas0)) -- Исправлен парсинг данных `AggregateFunction` значения, встроенные в запрос. [\#6575](https://github.com/ClickHouse/ClickHouse/issues/6575) [\#6773](https://github.com/ClickHouse/ClickHouse/pull/6773) ([Zhichang Ю](https://github.com/yuzhichang)) -- Исправлено неправильное поведение `trim` функции семьи. [\#6647](https://github.com/ClickHouse/ClickHouse/pull/6647) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.13.4.32, 2019-09-10 {#clickhouse-release-19-13-4-32-2019-09-10} - -#### Исправление ошибок {#bug-fix-11} - -- Этот релиз также содержит все исправления безопасности ошибок от 19.11.9.52 и 19.11.10.54. -- Фиксированная гонка данных в `system.parts` стол и `ALTER` запрос. [\#6245](https://github.com/ClickHouse/ClickHouse/issues/6245) [\#6513](https://github.com/ClickHouse/ClickHouse/pull/6513) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено несовпадение заголовков в потоках, произошедшее при чтении из пустой распределенной таблицы с sample и prewhere. [\#6167](https://github.com/ClickHouse/ClickHouse/issues/6167) ([Лисян Цянь](https://github.com/fancyqlx)) [\#6823](https://github.com/ClickHouse/ClickHouse/pull/6823) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлена ошибка при использовании `IN` предложение с подзапросом с кортежем. [\#6125](https://github.com/ClickHouse/ClickHouse/issues/6125) [\#6550](https://github.com/ClickHouse/ClickHouse/pull/6550) ([тавплубикс](https://github.com/tavplubix)) -- Исправьте случай с одинаковыми именами столбцов в `GLOBAL JOIN ON` раздел. [\#6181](https://github.com/ClickHouse/ClickHouse/pull/6181) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка при приведении типов к `Decimal` это не поддерживает его. Вместо этого бросьте исключение. [\#6297](https://github.com/ClickHouse/ClickHouse/pull/6297) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлен сбой в работе `extractAll()` функция. [\#6644](https://github.com/ClickHouse/ClickHouse/pull/6644) ([Артем Зуйков](https://github.com/4ertus2)) -- Преобразование запроса для `MySQL`, `ODBC`, `JDBC` функции таблицы теперь работают правильно для `SELECT WHERE` запросы с несколькими `AND` выражения. [\#6381](https://github.com/ClickHouse/ClickHouse/issues/6381) [\#6676](https://github.com/ClickHouse/ClickHouse/pull/6676) ([dimarub2000](https://github.com/dimarub2000)) -- Добавлены предыдущие проверки деклараций для интеграции MySQL 8. [\#6569](https://github.com/ClickHouse/ClickHouse/pull/6569) ([Рафаэль Давид Тиноко](https://github.com/rafaeldtinoco)) - -#### Исправление безопасности {#security-fix-1} - -- Исправлены две уязвимости в кодеках на этапе декомпрессии (злоумышленник может сфабриковать сжатые данные, что приведет к переполнению буфера при декомпрессии). [\#6670](https://github.com/ClickHouse/ClickHouse/pull/6670) ([Артем Зуйков](https://github.com/4ertus2)) - -### ClickHouse релиз 19.13.3.26, 2019-08-22 {#clickhouse-release-19-13-3-26-2019-08-22} - -#### Исправление ошибок {#bug-fix-12} - -- Чинить `ALTER TABLE ... UPDATE` запрос для таблиц с `enable_mixed_granularity_parts=1`. [\#6543](https://github.com/ClickHouse/ClickHouse/pull/6543) ([алесапин](https://github.com/alesapin)) -- Исправьте NPE при использовании предложения IN с подзапросом с кортежем. [\#6125](https://github.com/ClickHouse/ClickHouse/issues/6125) [\#6550](https://github.com/ClickHouse/ClickHouse/pull/6550) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена проблема, что если устаревшая реплика становится живой, она все еще может содержать части данных, которые были удалены разделом DROP. [\#6522](https://github.com/ClickHouse/ClickHouse/issues/6522) [\#6523](https://github.com/ClickHouse/ClickHouse/pull/6523) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена проблема с синтаксическим анализом CSV [\#6426](https://github.com/ClickHouse/ClickHouse/issues/6426) [\#6559](https://github.com/ClickHouse/ClickHouse/pull/6559) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена гонка данных в системе.таблица деталей и запрос ALTER. Это исправление [\#6245](https://github.com/ClickHouse/ClickHouse/issues/6245). [\#6513](https://github.com/ClickHouse/ClickHouse/pull/6513) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен неправильный код в мутациях, которые могут привести к повреждению памяти. Исправлена обработка выхода онлайн / оффлайн чтения адреса `0x14c0` это может произойти из-за совпадения `DROP TABLE` и `SELECT` от `system.parts` или `system.parts_columns`. Фиксированное состояние расы при подготовке запросов мутаций. Исправлена тупиковая ситуация, вызванная `OPTIMIZE` реплицированных таблиц и параллельных операций модификации, таких как ALTERs. [\#6514](https://github.com/ClickHouse/ClickHouse/pull/6514) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена возможная потеря данных после этого `ALTER DELETE` запрос на таблицу с пропущенным индексом. [\#6224](https://github.com/ClickHouse/ClickHouse/issues/6224) [\#6282](https://github.com/ClickHouse/ClickHouse/pull/6282) ([Никита Васильев](https://github.com/nikvas0)) - -#### Исправление безопасности {#security-fix-2} - -- Если злоумышленник имеет доступ на запись в ZooKeeper и может запустить пользовательский сервер, доступный из сети, где работает ClickHouse, он может создать пользовательский вредоносный сервер, который будет действовать как реплика ClickHouse, и зарегистрировать его в ZooKeeper. Когда другая реплика будет извлекать часть данных из вредоносной реплики, она может заставить clickhouse-сервер выполнить запись в произвольный путь на файловой системе. Найдено Эльдаром Зайтовым, специалистом по информационной безопасности Яндекса. [\#6247](https://github.com/ClickHouse/ClickHouse/pull/6247) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.13.2.19, 2019-08-14 {#clickhouse-release-19-13-2-19-2019-08-14} - -#### Новая функция {#new-feature-5} - -- Профилировщик выборки на уровне запроса. [Пример](https://gist.github.com/alexey-milovidov/92758583dd41c24c360fdb8d6a4da194). [\#4247](https://github.com/ClickHouse/ClickHouse/issues/4247) ([лаплаб](https://github.com/laplab)) [\#6124](https://github.com/ClickHouse/ClickHouse/pull/6124) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) [\#6250](https://github.com/ClickHouse/ClickHouse/pull/6250) [\#6283](https://github.com/ClickHouse/ClickHouse/pull/6283) [\#6386](https://github.com/ClickHouse/ClickHouse/pull/6386) -- Разрешить указывать список столбцов с помощью `COLUMNS('regexp')` выражение, которое работает как более сложный вариант `*` звездочка. [\#5951](https://github.com/ClickHouse/ClickHouse/pull/5951) ([мфриденталь](https://github.com/mfridental)), ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `CREATE TABLE AS table_function()` теперь возможный [\#6057](https://github.com/ClickHouse/ClickHouse/pull/6057) ([dimarub2000](https://github.com/dimarub2000)) -- Adam optimizer для стохастического градиентного спуска используется по умолчанию в `stochasticLinearRegression()` и `stochasticLogisticRegression()` агрегатные функции, потому что он показывает хорошее качество почти без какой-либо настройки. [\#6000](https://github.com/ClickHouse/ClickHouse/pull/6000) ([Quid37](https://github.com/Quid37)) -- Added functions for working with the сustom week number [\#5212](https://github.com/ClickHouse/ClickHouse/pull/5212) ([Энди Янг](https://github.com/andyyzh)) -- `RENAME` запросы теперь работают со всеми хранилищами. [\#5953](https://github.com/ClickHouse/ClickHouse/pull/5953) ([Иван](https://github.com/abyss7)) -- Теперь клиент получает журналы с сервера с любым желаемым уровнем настройки `send_logs_level` независимо от уровня журнала, указанного в настройках сервера. [\#5964](https://github.com/ClickHouse/ClickHouse/pull/5964) ([Никита Михайлов](https://github.com/nikitamikhaylov)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-4} - -- Установка `input_format_defaults_for_omitted_fields` по умолчанию он включен. Вставки в распределенные таблицы требуют, чтобы этот параметр был одинаковым в кластере (его необходимо установить перед развертыванием обновления). Он позволяет вычислять сложные выражения по умолчанию для пропущенных полей в `JSONEachRow` и `CSV*` форматы. Это должно быть ожидаемое поведение, но может привести к незначительной разнице в производительности. [\#6043](https://github.com/ClickHouse/ClickHouse/pull/6043) ([Артем Зуйков](https://github.com/4ertus2)), [\#5625](https://github.com/ClickHouse/ClickHouse/pull/5625) ([акузм](https://github.com/akuzm)) - -#### Экспериментальная возможность {#experimental-features} - -- Новый конвейер обработки запросов. Воспользуйся `experimental_use_processors=1` возможность включить его. Используй для своих собственных проблем. [\#4914](https://github.com/ClickHouse/ClickHouse/pull/4914) ([Николай Кочетов](https://github.com/KochetovNicolai)) - -#### Исправление ошибок {#bug-fix-13} - -- Интеграция Кафки была исправлена в этой версии. -- Исправлено `DoubleDelta` кодирование данных `Int64` для больших `DoubleDelta` значения, улучшенные `DoubleDelta` кодирование случайных данных для `Int32`. [\#5998](https://github.com/ClickHouse/ClickHouse/pull/5998) ([Василий Немков](https://github.com/Enmk)) -- Исправлена завышенная оценка стоимости `max_rows_to_read` если установка `merge_tree_uniform_read_distribution` имеет значение 0. [\#6019](https://github.com/ClickHouse/ClickHouse/pull/6019) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшение {#improvement-4} - -- Создает исключение, если `config.d` файл не имеет соответствующего корневого элемента в качестве файла конфигурации [\#6123](https://github.com/ClickHouse/ClickHouse/pull/6123) ([dimarub2000](https://github.com/dimarub2000)) - -#### Улучшение производительности {#performance-improvement-3} - -- Оптимизировать `count()`. Теперь он использует самый маленький столбец (если это возможно). [\#6028](https://github.com/ClickHouse/ClickHouse/pull/6028) ([Амос Птица](https://github.com/amosbird)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-5} - -- Отчет об использовании памяти в тестах производительности. [\#5899](https://github.com/ClickHouse/ClickHouse/pull/5899) ([акузм](https://github.com/akuzm)) -- Исправление построения с внешним `libcxx` [\#6010](https://github.com/ClickHouse/ClickHouse/pull/6010) ([Иван](https://github.com/abyss7)) -- Исправить общую сборку с помощью `rdkafka` библиотека [\#6101](https://github.com/ClickHouse/ClickHouse/pull/6101) ([Иван](https://github.com/abyss7)) - -## ClickHouse релиз 19.11 {#clickhouse-release-19-11} - -### ClickHouse релиз 19.11.13.74, 2019-11-01 {#clickhouse-release-19-11-13-74-2019-11-01} - -#### Исправление ошибок {#bug-fix-14} - -- Исправлена редкая авария в системе `ALTER MODIFY COLUMN` и вертикальное слияние, когда одна из Объединенных/измененных частей пуста (0 строк). [\#6780](https://github.com/ClickHouse/ClickHouse/pull/6780) ([алесапин](https://github.com/alesapin)) -- Ручное обновление данных `SIMDJSON`. Это устраняет возможные наводнения в stderr файлы с поддельными диагностическими сообщениями в формате JSON. [\#7548](https://github.com/ClickHouse/ClickHouse/pull/7548) ([Александр казаков](https://github.com/Akazz)) -- Исправлена ошибка с `mrk` расширение файла для мутаций ([алесапин](https://github.com/alesapin)) - -### ClickHouse релиз 19.11.12.69, 2019-10-02 {#clickhouse-release-19-11-12-69-2019-10-02} - -#### Исправление ошибок {#bug-fix-15} - -- Исправлено снижение производительности индексного анализа по сложным ключам на больших таблицах. Это исправление [\#6924](https://github.com/ClickHouse/ClickHouse/issues/6924). [\#7075](https://github.com/ClickHouse/ClickHouse/pull/7075) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Избегайте редких SIGSEGV при отправке данных в таблицах с распределенным движком (`Failed to send batch: file with index XXXXX is absent`). [\#7032](https://github.com/ClickHouse/ClickHouse/pull/7032) ([Азат Хужин](https://github.com/azat)) -- Чинить `Unknown identifier` с несколькими соединениями. Это исправление [\#5254](https://github.com/ClickHouse/ClickHouse/issues/5254). [\#7022](https://github.com/ClickHouse/ClickHouse/pull/7022) ([Артем Зуйков](https://github.com/4ertus2)) - -### ClickHouse релиз 19.11.11.57, 2019-09-13 {#clickhouse-release-19-11-11-57-2019-09-13} - -- Исправлена логическая ошибка, вызывающая segfaults при выборе из Кафки пустой темы. [\#6902](https://github.com/ClickHouse/ClickHouse/issues/6902) [\#6909](https://github.com/ClickHouse/ClickHouse/pull/6909) ([Иван](https://github.com/abyss7)) -- Исправление для функции `АrrayEnumerateUniqRanked` с пустыми массивами в парах. [\#6928](https://github.com/ClickHouse/ClickHouse/pull/6928) ([proller](https://github.com/proller)) - -### ClickHouse релиз 19.11.10.54, 2019-09-10 {#clickhouse-release-19-11-10-54-2019-09-10} - -#### Исправление ошибок {#bug-fix-16} - -- Сохраняйте смещения для сообщений Кафки вручную, чтобы иметь возможность фиксировать их все сразу для всех разделов. Исправляет потенциальное дублирование в «one consumer - many partitions» сценарий. [\#6872](https://github.com/ClickHouse/ClickHouse/pull/6872) ([Иван](https://github.com/abyss7)) - -### ClickHouse релиз 19.11.9.52, 2019-09-6 {#clickhouse-release-19-11-9-52-2019-09-6} - -- Улучшена обработка ошибок в словарях кэша. [\#6737](https://github.com/ClickHouse/ClickHouse/pull/6737) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправлена ошибка в функции `arrayEnumerateUniqRanked`. [\#6779](https://github.com/ClickHouse/ClickHouse/pull/6779) ([proller](https://github.com/proller)) -- Чинить `JSONExtract` функция при извлечении `Tuple` из JSON. [\#6718](https://github.com/ClickHouse/ClickHouse/pull/6718) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправлена возможная потеря данных после этого `ALTER DELETE` запрос на таблицу с пропущенным индексом. [\#6224](https://github.com/ClickHouse/ClickHouse/issues/6224) [\#6282](https://github.com/ClickHouse/ClickHouse/pull/6282) ([Никита Васильев](https://github.com/nikvas0)) -- Исправлена проверка производительности. [\#6392](https://github.com/ClickHouse/ClickHouse/pull/6392) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Паркет: исправьте чтение логических столбцов. [\#6579](https://github.com/ClickHouse/ClickHouse/pull/6579) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено неправильное поведение `nullIf` функция для постоянных аргументов. [\#6518](https://github.com/ClickHouse/ClickHouse/pull/6518) ([Гийом Тассери](https://github.com/YiuRULE)) [\#6580](https://github.com/ClickHouse/ClickHouse/pull/6580) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена проблема дублирования сообщений Кафки при обычном перезапуске сервера. [\#6597](https://github.com/ClickHouse/ClickHouse/pull/6597) ([Иван](https://github.com/abyss7)) -- Исправлена ошибка, когда долго `ALTER UPDATE` или `ALTER DELETE` может помешать запуску регулярных слияний. Предотвратите выполнение мутаций, если нет достаточного количества свободных потоков. [\#6502](https://github.com/ClickHouse/ClickHouse/issues/6502) [\#6617](https://github.com/ClickHouse/ClickHouse/pull/6617) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена ошибка при обработке данных «timezone» в файле конфигурации сервера. [\#6709](https://github.com/ClickHouse/ClickHouse/pull/6709) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте тесты Кафки. [\#6805](https://github.com/ClickHouse/ClickHouse/pull/6805) ([Иван](https://github.com/abyss7)) - -#### Исправление безопасности {#security-fix-3} - -- Если злоумышленник имеет доступ на запись в ZooKeeper и может запустить пользовательский сервер, доступный из сети, где работает ClickHouse, он может создать пользовательский вредоносный сервер, который будет действовать как реплика ClickHouse, и зарегистрировать его в ZooKeeper. Когда другая реплика будет извлекать часть данных из вредоносной реплики, она может заставить clickhouse-сервер выполнить запись в произвольный путь на файловой системе. Найдено Эльдаром Зайтовым, специалистом по информационной безопасности Яндекса. [\#6247](https://github.com/ClickHouse/ClickHouse/pull/6247) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.11.8.46, 2019-08-22 {#clickhouse-release-19-11-8-46-2019-08-22} - -#### Исправление ошибок {#bug-fix-17} - -- Чинить `ALTER TABLE ... UPDATE` запрос для таблиц с `enable_mixed_granularity_parts=1`. [\#6543](https://github.com/ClickHouse/ClickHouse/pull/6543) ([алесапин](https://github.com/alesapin)) -- Исправьте NPE при использовании предложения IN с подзапросом с кортежем. [\#6125](https://github.com/ClickHouse/ClickHouse/issues/6125) [\#6550](https://github.com/ClickHouse/ClickHouse/pull/6550) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена проблема, что если устаревшая реплика становится живой, она все еще может содержать части данных, которые были удалены разделом DROP. [\#6522](https://github.com/ClickHouse/ClickHouse/issues/6522) [\#6523](https://github.com/ClickHouse/ClickHouse/pull/6523) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена проблема с синтаксическим анализом CSV [\#6426](https://github.com/ClickHouse/ClickHouse/issues/6426) [\#6559](https://github.com/ClickHouse/ClickHouse/pull/6559) ([тавплубикс](https://github.com/tavplubix)) -- Исправлена гонка данных в системе.таблица деталей и запрос ALTER. Это исправление [\#6245](https://github.com/ClickHouse/ClickHouse/issues/6245). [\#6513](https://github.com/ClickHouse/ClickHouse/pull/6513) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен неправильный код в мутациях, которые могут привести к повреждению памяти. Исправлена обработка выхода онлайн / оффлайн чтения адреса `0x14c0` это может произойти из-за совпадения `DROP TABLE` и `SELECT` от `system.parts` или `system.parts_columns`. Фиксированное состояние расы при подготовке запросов мутаций. Исправлена тупиковая ситуация, вызванная `OPTIMIZE` реплицированных таблиц и параллельных операций модификации, таких как ALTERs. [\#6514](https://github.com/ClickHouse/ClickHouse/pull/6514) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.11.7.40, 2019-08-14 {#clickhouse-release-19-11-7-40-2019-08-14} - -#### Исправление ошибок {#bug-fix-18} - -- Интеграция Кафки была исправлена в этой версии. -- Исправлена обработка выхода онлайн / оффлайн при использовании `arrayReduce` для постоянных споров. [\#6326](https://github.com/ClickHouse/ClickHouse/pull/6326) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено `toFloat()` монотонность. [\#6374](https://github.com/ClickHouse/ClickHouse/pull/6374) ([dimarub2000](https://github.com/dimarub2000)) -- Исправлена обработка выхода онлайн / оффлайн с поддержкой `optimize_skip_unused_shards` и пропал ключ от осколков. [\#6384](https://github.com/ClickHouse/ClickHouse/pull/6384) ([CurtizJ](https://github.com/CurtizJ)) -- Фиксированная логика работы `arrayEnumerateUniqRanked` функция. [\#6423](https://github.com/ClickHouse/ClickHouse/pull/6423) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Удалено дополнительное подробное ведение журнала из обработчика MySQL. [\#6389](https://github.com/ClickHouse/ClickHouse/pull/6389) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить неправильное поведение и возможные вылеты в `topK` и `topKWeighted` агрегированные функции. [\#6404](https://github.com/ClickHouse/ClickHouse/pull/6404) ([CurtizJ](https://github.com/CurtizJ)) -- Не выставляйте виртуальные столбцы в `system.columns` стол. Это необходимо для обратной совместимости. [\#6406](https://github.com/ClickHouse/ClickHouse/pull/6406) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка с выделением памяти для строковых полей в сложном словаре кэша ключей. [\#6447](https://github.com/ClickHouse/ClickHouse/pull/6447) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка с включением адаптивной детализации при создании новой реплики для `Replicated*MergeTree` стол. [\#6452](https://github.com/ClickHouse/ClickHouse/pull/6452) ([алесапин](https://github.com/alesapin)) -- Исправьте бесконечный цикл при чтении сообщений Кафки. [\#6354](https://github.com/ClickHouse/ClickHouse/pull/6354) ([abyss7](https://github.com/abyss7)) -- Исправлена возможность готовых запрос, чтобы вызвать падение сервера из-за переполнения стека в парсер SQL и возможность переполнения стека в `Merge` и `Distributed` таблицы [\#6433](https://github.com/ClickHouse/ClickHouse/pull/6433) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка кодирования горилл на небольших последовательностях. [\#6444](https://github.com/ClickHouse/ClickHouse/pull/6444) ([Enmk](https://github.com/Enmk)) - -#### Улучшение {#improvement-5} - -- Позволяет пользователю переопределить `poll_interval` и `idle_connection_timeout` настройки при подключении. [\#6230](https://github.com/ClickHouse/ClickHouse/pull/6230) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.11.5.28, 2019-08-05 {#clickhouse-release-19-11-5-28-2019-08-05} - -#### Исправление ошибок {#bug-fix-19} - -- Исправлена возможность зависания запросов при перегрузке сервера. [\#6301](https://github.com/ClickHouse/ClickHouse/pull/6301) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте FPE в функции yandexConsistentHash. Это исправление [\#6304](https://github.com/ClickHouse/ClickHouse/issues/6304). [\#6126](https://github.com/ClickHouse/ClickHouse/pull/6126) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка в преобразовании `LowCardinality` напечатать `AggregateFunctionFactory`. Это исправление [\#6257](https://github.com/ClickHouse/ClickHouse/issues/6257). [\#6281](https://github.com/ClickHouse/ClickHouse/pull/6281) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправьте синтаксический анализ `bool` настройки от `true` и `false` строки в файлах конфигурации. [\#6278](https://github.com/ClickHouse/ClickHouse/pull/6278) ([алесапин](https://github.com/alesapin)) -- Исправлена редкая ошибка с несовместимыми заголовками потока в запросах к `Distributed` стол `MergeTree` таблица, когда часть `WHERE` движется к `PREWHERE`. [\#6236](https://github.com/ClickHouse/ClickHouse/pull/6236) ([алесапин](https://github.com/alesapin)) -- Исправлено переполнение при целочисленном делении знакового типа на беззнаковый. Это исправление [\#6214](https://github.com/ClickHouse/ClickHouse/issues/6214). [\#6233](https://github.com/ClickHouse/ClickHouse/pull/6233) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-5} - -- `Kafka` все еще сломанный. - -### ClickHouse релиз 19.11.4.24, 2019-08-01 {#clickhouse-release-19-11-4-24-2019-08-01} - -#### Исправление ошибок {#bug-fix-20} - -- Исправлена ошибка с написанием вторичных индексных меток с адаптивной детализацией. [\#6126](https://github.com/ClickHouse/ClickHouse/pull/6126) ([алесапин](https://github.com/alesapin)) -- Чинить `WITH ROLLUP` и `WITH CUBE` модификаторы `GROUP BY` с двухуровневой агрегацией. [\#6225](https://github.com/ClickHouse/ClickHouse/pull/6225) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлено зависание `JSONExtractRaw` функция. Исправлено [\#6195](https://github.com/ClickHouse/ClickHouse/issues/6195) [\#6198](https://github.com/ClickHouse/ClickHouse/pull/6198) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка segfault в ExternalLoader:: reloadOutdated (). [\#6082](https://github.com/ClickHouse/ClickHouse/pull/6082) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправлен случай, когда сервер может закрыть прослушивающие сокеты, но не выключаться и продолжать обслуживать оставшиеся запросы. В конечном итоге вы можете получить два запущенных процесса clickhouse-server. Иногда сервер может выдать ошибку `bad_function_call` для остальных запросов. [\#6231](https://github.com/ClickHouse/ClickHouse/pull/6231) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено бесполезное и некорректное условие на поле update для начальной загрузки внешних словарей через ODBC, MySQL, ClickHouse и HTTP. Это исправление [\#6069](https://github.com/ClickHouse/ClickHouse/issues/6069) [\#6083](https://github.com/ClickHouse/ClickHouse/pull/6083) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено неуместное исключение в приведении `LowCardinality(Nullable)` to not-Nullable column in case if it doesn't contain Nulls (e.g. in query like `SELECT CAST(CAST('Hello' AS LowCardinality(Nullable(String))) AS String)`. [\#6094](https://github.com/ClickHouse/ClickHouse/issues/6094) [\#6119](https://github.com/ClickHouse/ClickHouse/pull/6119) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Зафиксировать недетерминированный результат «uniq» агрегатная функция в крайне редких случаях. Ошибка присутствовала во всех версиях ClickHouse. [\#6058](https://github.com/ClickHouse/ClickHouse/pull/6058) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Обработка выхода онлайн / оффлайн, когда мы немного завышены запись на функцию `IPv6CIDRToRange`. [\#6068](https://github.com/ClickHouse/ClickHouse/pull/6068) ([Гийом Тассери](https://github.com/YiuRULE)) -- Исправлена небольшая утечка памяти, когда сервер выбрасывает много исключений из многих различных контекстов. [\#6144](https://github.com/ClickHouse/ClickHouse/pull/6144) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте ситуацию, когда потребитель сделал паузу перед подпиской и не возобновил ее после этого. [\#6075](https://github.com/ClickHouse/ClickHouse/pull/6075) ([Иван](https://github.com/abyss7)) Обратите внимание, что Кафка разбит в этой версии. -- Очистка буфера данных Кафки от предыдущей операции чтения, которая была завершена с ошибкой [\#6026](https://github.com/ClickHouse/ClickHouse/pull/6026) ([Николай](https://github.com/bopohaa)) Обратите внимание, что Кафка разбит в этой версии. -- С `StorageMergeTree::background_task_handle` инициализируется в `startup()` то `MergeTreeBlockOutputStream::write()` возможно, вы попытаетесь использовать его перед инициализацией. Просто проверьте, инициализирован ли он. [\#6080](https://github.com/ClickHouse/ClickHouse/pull/6080) ([Иван](https://github.com/abyss7)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-6} - -- Добавлено официальное лицо `rpm` пакеты. [\#5740](https://github.com/ClickHouse/ClickHouse/pull/5740) ([proller](https://github.com/proller)) ([алесапин](https://github.com/alesapin)) -- Добавьте возможность строить `.rpm` и `.tgz` пакеты с `packager` скрипт. [\#5769](https://github.com/ClickHouse/ClickHouse/pull/5769) ([алесапин](https://github.com/alesapin)) -- Исправления для «Arcadia» система сборки. [\#6223](https://github.com/ClickHouse/ClickHouse/pull/6223) ([proller](https://github.com/proller)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-6} - -- `Kafka` сломан в этой версии. - -### ClickHouse релиз 19.11.3.11, 2019-07-18 {#clickhouse-release-19-11-3-11-2019-07-18} - -#### Новая функция {#new-feature-6} - -- Добавлена поддержка подготовленных заявлений. [\#5331](https://github.com/ClickHouse/ClickHouse/pull/5331/) ([Александр](https://github.com/sanych73)) [\#5630](https://github.com/ClickHouse/ClickHouse/pull/5630) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `DoubleDelta` и `Gorilla` кодеки столбцов [\#5600](https://github.com/ClickHouse/ClickHouse/pull/5600) ([Василий Немков](https://github.com/Enmk)) -- Добавлен `os_thread_priority` настройка, позволяющая контролировать «nice» значение потоков обработки запросов, используемых ОС для настройки приоритета динамического планирования. Для этого требуется `CAP_SYS_NICE` возможности для работы. Это орудия труда [\#5858](https://github.com/ClickHouse/ClickHouse/issues/5858) [\#5909](https://github.com/ClickHouse/ClickHouse/pull/5909) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Осуществлять `_topic`, `_offset`, `_key` колонны для двигателя Кафки [\#5382](https://github.com/ClickHouse/ClickHouse/pull/5382) ([Иван](https://github.com/abyss7)) Обратите внимание, что Кафка разбит в этой версии. -- Добавить комбинатор агрегатных функций `-Resample` [\#5590](https://github.com/ClickHouse/ClickHouse/pull/5590) ([hcz](https://github.com/hczhcz)) -- Статистическая функция `groupArrayMovingSum(win_size)(x)` и `groupArrayMovingAvg(win_size)(x)`, которые вычисляют движущуюся сумму / среднее значение с ограничением размера окна или без него. [\#5595](https://github.com/ClickHouse/ClickHouse/pull/5595) ([inv2004](https://github.com/inv2004)) -- Добавить синоним `arrayFlatten` \<-\> `flatten` [\#5764](https://github.com/ClickHouse/ClickHouse/pull/5764) ([hcz](https://github.com/hczhcz)) -- Функция сделала из intergate Н3 `geoToH3` от Uber. [\#4724](https://github.com/ClickHouse/ClickHouse/pull/4724) ([Ремен Иван](https://github.com/BHYCHIK)) [\#5805](https://github.com/ClickHouse/ClickHouse/pull/5805) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Исправление ошибок {#bug-fix-21} - -- Реализуйте кэш DNS с асинхронным обновлением. Отдельный поток разрешает все хосты и обновляет кэш DNS с периодом (настройка `dns_cache_update_period`). Это должно помочь, когда ip хостов часто меняется. [\#5857](https://github.com/ClickHouse/ClickHouse/pull/5857) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена обработка выхода онлайн / оффлайн в `Delta` кодек, который влияет на столбцы со значениями размером менее 32 бит. Ошибка привела к случайному повреждению памяти. [\#5786](https://github.com/ClickHouse/ClickHouse/pull/5786) ([алесапин](https://github.com/alesapin)) -- Исправлена обработка выхода онлайн / оффлайн в TTL слиться с не-физической столбцов в блоке. [\#5819](https://github.com/ClickHouse/ClickHouse/pull/5819) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена редкая ошибка при проверке деталей с помощью `LowCardinality` колонка. Ранее `checkDataPart` всегда терпит неудачу при расставании с `LowCardinality` колонка. [\#5832](https://github.com/ClickHouse/ClickHouse/pull/5832) ([алесапин](https://github.com/alesapin)) -- Избегайте зависания соединений, когда пул потоков сервера заполнен. Это важно для соединений от `remote` табличная функция или соединения с сегментом без реплик при длительном таймауте соединения. Это исправление [\#5878](https://github.com/ClickHouse/ClickHouse/issues/5878) [\#5881](https://github.com/ClickHouse/ClickHouse/pull/5881) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Поддержка постоянных аргументов для того, чтобы `evalMLModel` функция. Это исправление [\#5817](https://github.com/ClickHouse/ClickHouse/issues/5817) [\#5820](https://github.com/ClickHouse/ClickHouse/pull/5820) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, когда ClickHouse определяет часовой пояс по умолчанию как `UCT` вместо `UTC`. Это исправление [\#5804](https://github.com/ClickHouse/ClickHouse/issues/5804). [\#5828](https://github.com/ClickHouse/ClickHouse/pull/5828) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Фиксированный нижний поток буфера в `visitParamExtractRaw`. Это исправление [\#5901](https://github.com/ClickHouse/ClickHouse/issues/5901) [\#5902](https://github.com/ClickHouse/ClickHouse/pull/5902) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Сейчас распространены `DROP/ALTER/TRUNCATE/OPTIMIZE ON CLUSTER` запросы будут выполняться непосредственно на реплике лидера. [\#5757](https://github.com/ClickHouse/ClickHouse/pull/5757) ([алесапин](https://github.com/alesapin)) -- Чинить `coalesce` для `ColumnConst` с `ColumnNullable` + соответствующие изменения. [\#5755](https://github.com/ClickHouse/ClickHouse/pull/5755) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправьте это `ReadBufferFromKafkaConsumer` так что он продолжает читать новые сообщения после этого `commit()` даже если он был остановлен раньше [\#5852](https://github.com/ClickHouse/ClickHouse/pull/5852) ([Иван](https://github.com/abyss7)) -- Чинить `FULL` и `RIGHT` Результаты соединения при присоединении на `Nullable` ключи в правой таблице. [\#5859](https://github.com/ClickHouse/ClickHouse/pull/5859) ([Артем Зуйков](https://github.com/4ertus2)) -- Возможно исправление бесконечного сна низкоприоритетных запросов. [\#5842](https://github.com/ClickHouse/ClickHouse/pull/5842) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено состояние гонки, которое приводит к тому, что некоторые запросы могут не отображаться в query\_log после `SYSTEM FLUSH LOGS` запрос. [\#5456](https://github.com/ClickHouse/ClickHouse/issues/5456) [\#5685](https://github.com/ClickHouse/ClickHouse/pull/5685) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлено `heap-use-after-free` Предупреждение ASan в ClusterCopier вызвано часами, которые пытаются использовать уже удаленный объект copier. [\#5871](https://github.com/ClickHouse/ClickHouse/pull/5871) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлена ошибка `StringRef` указатель, возвращаемый некоторыми реализациями `IColumn::deserializeAndInsertFromArena`. Эта ошибка затронула только модульные тесты. [\#5973](https://github.com/ClickHouse/ClickHouse/pull/5973) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Не допускайте соединения исходного и промежуточного массива со столбцами маскировки одноименных столбцов. [\#5941](https://github.com/ClickHouse/ClickHouse/pull/5941) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка вставки и выбора запроса к движку MySQL с цитированием идентификатора стиля MySQL. [\#5704](https://github.com/ClickHouse/ClickHouse/pull/5704) ([Зимний Чжан](https://github.com/zhang2014)) -- Сейчас `CHECK TABLE` запрос может работать с семейством движков MergeTree. Он возвращает статус проверки и сообщение, если таковые имеются для каждой детали (или файла в случае более простых движков). Кроме того, Исправлена ошибка в извлечении сломанной детали. [\#5865](https://github.com/ClickHouse/ClickHouse/pull/5865) ([алесапин](https://github.com/alesapin)) -- Исправлена среда выполнения SPLIT\_SHARED\_LIBRARIES [\#5793](https://github.com/ClickHouse/ClickHouse/pull/5793) ([Данила Кутенин](https://github.com/danlark1)) -- Инициализация фиксированного часового пояса когда `/etc/localtime` это относительная ссылка, как `../usr/share/zoneinfo/Europe/Moscow` [\#5922](https://github.com/ClickHouse/ClickHouse/pull/5922) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- clickhouse-копир: исправлена использования после освобождения при завершении работы [\#5752](https://github.com/ClickHouse/ClickHouse/pull/5752) ([proller](https://github.com/proller)) -- Обновленный `simdjson`. Исправлена проблема, из-за которой некоторые недопустимые JSONs с нулевыми байтами успешно разбирались. [\#5938](https://github.com/ClickHouse/ClickHouse/pull/5938) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено отключение системных журналов [\#5802](https://github.com/ClickHouse/ClickHouse/pull/5802) ([Антон Попов](https://github.com/CurtizJ)) -- Исправьте зависание, когда условие в invalidate\_query зависит от словаря. [\#6011](https://github.com/ClickHouse/ClickHouse/pull/6011) ([Виталий Баранов](https://github.com/vitlibar)) - -#### Улучшение {#improvement-6} - -- Разрешить неразрешимые адреса в конфигурации кластера. Они будут считаться недоступными и пытаться разрешить их при каждой попытке подключения. Это особенно полезно для Kubernetes. Это исправление [\#5714](https://github.com/ClickHouse/ClickHouse/issues/5714) [\#5924](https://github.com/ClickHouse/ClickHouse/pull/5924) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Закройте неработающие TCP-соединения (по умолчанию с таймаутом в один час). Это особенно важно для больших кластеров с несколькими распределенными таблицами на каждом сервере, поскольку каждый сервер может содержать пул соединений с каждым другим сервером, и после пикового параллелизма запросов соединения будут останавливаться. Это исправление [\#5879](https://github.com/ClickHouse/ClickHouse/issues/5879) [\#5880](https://github.com/ClickHouse/ClickHouse/pull/5880) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Более лучшее качество `topK` функция. Изменено поведение набора SavingSpace для удаления последнего элемента, если новый элемент имеет больший вес. [\#5833](https://github.com/ClickHouse/ClickHouse/issues/5833) [\#5850](https://github.com/ClickHouse/ClickHouse/pull/5850) ([Гийом Тассери](https://github.com/YiuRULE)) -- Функции URL для работы с доменами теперь могут работать для неполных url без схемы [\#5725](https://github.com/ClickHouse/ClickHouse/pull/5725) ([алесапин](https://github.com/alesapin)) -- Контрольные суммы, добавленные к `system.parts_columns` стол. [\#5874](https://github.com/ClickHouse/ClickHouse/pull/5874) ([Никита Михайлов](https://github.com/nikitamikhaylov)) -- Добавлен `Enum` тип данных как синоним для `Enum8` или `Enum16`. [\#5886](https://github.com/ClickHouse/ClickHouse/pull/5886) ([dimarub2000](https://github.com/dimarub2000)) -- Полный вариант транспонирования битов для `T64` кодек. Может привести к лучшему сжатию с помощью `zstd`. [\#5742](https://github.com/ClickHouse/ClickHouse/pull/5742) ([Артем Зуйков](https://github.com/4ertus2)) -- Состояние на `startsWith` функция теперь может использовать первичный ключ. Это исправление [\#5310](https://github.com/ClickHouse/ClickHouse/issues/5310) и [\#5882](https://github.com/ClickHouse/ClickHouse/issues/5882) [\#5919](https://github.com/ClickHouse/ClickHouse/pull/5919) ([dimarub2000](https://github.com/dimarub2000)) -- Разрешить использовать `clickhouse-copier` с перекрестной репликацией кластерной топологии, разрешив пустое имя базы данных. [\#5745](https://github.com/ClickHouse/ClickHouse/pull/5745) ([nvartolomei](https://github.com/nvartolomei)) -- Воспользуйся `UTC` как часовой пояс по умолчанию в системе без `tzdata` (e.g. bare Docker container). Before this patch, error message `Could not determine local time zone` была напечатана, и сервер или клиент отказались запускаться. [\#5827](https://github.com/ClickHouse/ClickHouse/pull/5827) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Возвращенная назад поддержка аргумента с плавающей запятой в функции `quantileTiming` для обратной совместимости. [\#5911](https://github.com/ClickHouse/ClickHouse/pull/5911) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Показать, в какой таблице отсутствует столбец в сообщениях об ошибках. [\#5768](https://github.com/ClickHouse/ClickHouse/pull/5768) ([Иван](https://github.com/abyss7)) -- Запретить выполнение запроса с одинаковым идентификатором query\_id разными пользователями [\#5430](https://github.com/ClickHouse/ClickHouse/pull/5430) ([proller](https://github.com/proller)) -- Более надежный код для отправки метрик в графит. Он будет работать даже во время длительного многократного использования `RENAME TABLE` операция. [\#5875](https://github.com/ClickHouse/ClickHouse/pull/5875) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Более информативные сообщения об ошибках будут отображаться, когда ThreadPool не может запланировать выполнение задачи. Это исправление [\#5305](https://github.com/ClickHouse/ClickHouse/issues/5305) [\#5801](https://github.com/ClickHouse/ClickHouse/pull/5801) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Инвертирование ngramSearch, чтобы быть более интуитивным [\#5807](https://github.com/ClickHouse/ClickHouse/pull/5807) ([Данила Кутенин](https://github.com/danlark1)) -- Добавить пользователя parsing в HDFS engine builder [\#5946](https://github.com/ClickHouse/ClickHouse/pull/5946) ([аконяев90](https://github.com/akonyaev90)) -- Обновить значение по умолчанию `max_ast_elements parameter` [\#5933](https://github.com/ClickHouse/ClickHouse/pull/5933) ([Артем Коновалов](https://github.com/izebit)) -- Добавлено понятие устаревших настроек. Устаревшая настройка `allow_experimental_low_cardinality_type` может использоваться без какого-либо эффекта. [0f15c01c6802f7ce1a1494c12c846be8c98944cd](https://github.com/ClickHouse/ClickHouse/commit/0f15c01c6802f7ce1a1494c12c846be8c98944cd) [Алексей Миловидов](https://github.com/alexey-milovidov) - -#### Улучшение производительности {#performance-improvement-4} - -- Увеличьте количество потоков для выбора из таблицы слияния для более равномерного распределения потоков. Добавлена настройка `max_streams_multiplier_for_merge_tables`. Это исправление [\#5797](https://github.com/ClickHouse/ClickHouse/issues/5797) [\#5915](https://github.com/ClickHouse/ClickHouse/pull/5915) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-7} - -- Добавьте тест обратной совместимости для взаимодействия клиент-сервер с различными версиями clickhouse. [\#5868](https://github.com/ClickHouse/ClickHouse/pull/5868) ([алесапин](https://github.com/alesapin)) -- Проверьте информацию о покрытии в каждом запросе фиксации и вытягивания. [\#5896](https://github.com/ClickHouse/ClickHouse/pull/5896) ([алесапин](https://github.com/alesapin)) -- Сотрудничайте с address sanitizer для поддержки наших пользовательских распределителей (`Arena` и `ArenaWithFreeLists`) для лучшей отладки «use-after-free» ошибки. [\#5728](https://github.com/ClickHouse/ClickHouse/pull/5728) ([акузм](https://github.com/akuzm)) -- Переключитесь на [Реализация LLVM libunwind](https://github.com/llvm-mirror/libunwind) для обработки исключений C++ и для печати трассировок стека [\#4828](https://github.com/ClickHouse/ClickHouse/pull/4828) ([Никита Лапков](https://github.com/laplab)) -- Добавьте еще два предупреждения от -Weverything [\#5923](https://github.com/ClickHouse/ClickHouse/pull/5923) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Разрешите построить ClickHouse с дезинфицирующим средством для памяти. [\#3949](https://github.com/ClickHouse/ClickHouse/pull/3949) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен отчет утилиты о `bitTest` функция в тест. [\#5943](https://github.com/ClickHouse/ClickHouse/pull/5943) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Настройки: добавлена возможность инициализации экземпляра ClickHouse, который требует проверки подлинности. [\#5727](https://github.com/ClickHouse/ClickHouse/pull/5727) ([Корвяков Андрей Николаевич](https://github.com/shurshun)) -- Librdkafka обновление до версии 1.1.0 [\#5872](https://github.com/ClickHouse/ClickHouse/pull/5872) ([Иван](https://github.com/abyss7)) -- Добавьте глобальный тайм-аут для интеграционных тестов и отключите некоторые из них в коде тестов. [\#5741](https://github.com/ClickHouse/ClickHouse/pull/5741) ([алесапин](https://github.com/alesapin)) -- Исправьте некоторые сбои ThreadSanitizer. [\#5854](https://github.com/ClickHouse/ClickHouse/pull/5854) ([акузм](https://github.com/akuzm)) -- То `--no-undefined` опция заставляет компоновщика проверять все внешние имена на наличие во время связывания. Очень полезно отслеживать реальные зависимости между библиотеками в режиме разделенной сборки. [\#5855](https://github.com/ClickHouse/ClickHouse/pull/5855) ([Иван](https://github.com/abyss7)) -- Добавлен тест производительности для [\#5797](https://github.com/ClickHouse/ClickHouse/issues/5797) [\#5914](https://github.com/ClickHouse/ClickHouse/pull/5914) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена совместимость с gcc-7. [\#5840](https://github.com/ClickHouse/ClickHouse/pull/5840) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена поддержка gcc-9. Это исправление [\#5717](https://github.com/ClickHouse/ClickHouse/issues/5717) [\#5774](https://github.com/ClickHouse/ClickHouse/pull/5774) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, когда libunwind может быть связан неправильно. [\#5948](https://github.com/ClickHouse/ClickHouse/pull/5948) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено несколько предупреждений, найденных PVS-Studio. [\#5921](https://github.com/ClickHouse/ClickHouse/pull/5921) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена начальная поддержка для `clang-tidy` статический анализатор. [\#5806](https://github.com/ClickHouse/ClickHouse/pull/5806) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Преобразование макросов BSD / Linux endian( ‘be64toh’ и ‘htobe64’) к эквивалентам Mac OS X [\#5785](https://github.com/ClickHouse/ClickHouse/pull/5785) ([Фу Чен](https://github.com/fredchenbj)) -- Улучшенное руководство по интеграционным тестам. [\#5796](https://github.com/ClickHouse/ClickHouse/pull/5796) ([Владимир Чеботарев](https://github.com/excitoon)) -- Исправление сборки на macosx + gcc9 [\#5822](https://github.com/ClickHouse/ClickHouse/pull/5822) ([Филимонов](https://github.com/filimonov)) -- Исправьте трудноуловимую опечатку: aggreAGte - \> aggregate. [\#5753](https://github.com/ClickHouse/ClickHouse/pull/5753) ([акузм](https://github.com/akuzm)) -- Исправлена сборка freebsd [\#5760](https://github.com/ClickHouse/ClickHouse/pull/5760) ([proller](https://github.com/proller)) -- Добавить ссылку на экспериментальный канал YouTube на сайт [\#5845](https://github.com/ClickHouse/ClickHouse/pull/5845) ([Иван Блинков](https://github.com/blinkov)) -- CMake: добавить опцию для флагов покрытия: WITH\_COVERAGE [\#5776](https://github.com/ClickHouse/ClickHouse/pull/5776) ([proller](https://github.com/proller)) -- Исправьте начальный размер некоторых встроенных подарков. [\#5787](https://github.com/ClickHouse/ClickHouse/pull/5787) ([акузм](https://github.com/akuzm)) -- clickhouse-сервер.postinst: исправлено обнаружение ОС для centos 6 [\#5788](https://github.com/ClickHouse/ClickHouse/pull/5788) ([proller](https://github.com/proller)) -- Добавлена генерация пакетов Arch linux. [\#5719](https://github.com/ClickHouse/ClickHouse/pull/5719) ([Владимир Чеботарев](https://github.com/excitoon)) -- Разделите Common / config.ч по библиотекам (СУБД) [\#5715](https://github.com/ClickHouse/ClickHouse/pull/5715) ([proller](https://github.com/proller)) -- Исправления для «Arcadia» построить платформу [\#5795](https://github.com/ClickHouse/ClickHouse/pull/5795) ([proller](https://github.com/proller)) -- Исправления для нетрадиционной сборки (gcc9, без подмодулей) [\#5792](https://github.com/ClickHouse/ClickHouse/pull/5792) ([proller](https://github.com/proller)) -- Требуется явный тип в unalignedStore, потому что было доказано, что он подвержен ошибкам [\#5791](https://github.com/ClickHouse/ClickHouse/pull/5791) ([акузм](https://github.com/akuzm)) -- Исправлена сборка MacOS [\#5830](https://github.com/ClickHouse/ClickHouse/pull/5830) ([Филимонов](https://github.com/filimonov)) -- Тест производительности относительно новой функции JIT с большим набором данных, как это было запрошено здесь [\#5263](https://github.com/ClickHouse/ClickHouse/issues/5263) [\#5887](https://github.com/ClickHouse/ClickHouse/pull/5887) ([Гийом Тассери](https://github.com/YiuRULE)) -- Запуск статических тестов в стресс-тесте [12693e568722f11e19859742f56428455501fd2a](https://github.com/ClickHouse/ClickHouse/commit/12693e568722f11e19859742f56428455501fd2a) ([алесапин](https://github.com/alesapin)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-7} - -- `Kafka` сломан в этой версии. -- Включить `adaptive_index_granularity` = 10 МБ по умолчанию для новых `MergeTree` таблицы. Если вы создали новые таблицы MergeTree на версии 19.11+, понижение рейтинга до версий до 19.6 будет невозможно. [\#5628](https://github.com/ClickHouse/ClickHouse/pull/5628) ([алесапин](https://github.com/alesapin)) -- Удалены устаревшие недокументированные встроенные словари, которые использовались Яндексом.Метрика. Функция `OSIn`, `SEIn`, `OSToRoot`, `SEToRoot`, `OSHierarchy`, `SEHierarchy` они больше не доступны. Если вы используете эти функции, напишите письмо по адресу clickhouse-feedback@yandex-team.com Примечание: в последний момент мы решили сохранить эти функции на некоторое время. [\#5780](https://github.com/ClickHouse/ClickHouse/pull/5780) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -## ClickHouse релиз 19.10 {#clickhouse-release-19-10} - -### ClickHouse релиз 19.10.1.5, 2019-07-12 {#clickhouse-release-19-10-1-5-2019-07-12} - -#### Новая функция {#new-feature-7} - -- Добавить новый кодек столбца: `T64`. Сделано для(U)столбцов IntX/EnumX/Data (Time)/DecimalX. Это должно быть хорошо для столбцов с постоянными или малыми значениями диапазона. Сам кодек позволяет увеличить или уменьшить тип данных без повторного сжатия. [\#5557](https://github.com/ClickHouse/ClickHouse/pull/5557) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавление СУБД `MySQL` что позволяет просматривать все таблицы на удаленном сервере MySQL [\#5599](https://github.com/ClickHouse/ClickHouse/pull/5599) ([Зимний Чжан](https://github.com/zhang2014)) -- `bitmapContains` реализация. Это в 2 раза быстрее, чем `bitmapHasAny` если второе растровое изображение содержит один элемент. [\#5535](https://github.com/ClickHouse/ClickHouse/pull/5535) ([Zhichang Ю](https://github.com/yuzhichang)) -- Поддержка `crc32` функция (с поведением точно таким же, как в MySQL или PHP). Не используйте его, если вам нужна хэш-функция. [\#5661](https://github.com/ClickHouse/ClickHouse/pull/5661) ([Ремен Иван](https://github.com/BHYCHIK)) -- Реализованный `SYSTEM START/STOP DISTRIBUTED SENDS` запросы для управления асинхронными вставками в `Distributed` таблицы. [\#4935](https://github.com/ClickHouse/ClickHouse/pull/4935) ([Зимний Чжан](https://github.com/zhang2014)) - -#### Исправление ошибок {#bug-fix-22} - -- Игнорируйте ограничения на выполнение запросов и максимальный размер частей для ограничений слияния при выполнении мутаций. [\#5659](https://github.com/ClickHouse/ClickHouse/pull/5659) ([Антон Попов](https://github.com/CurtizJ)) -- Исправлена ошибка, которая может привести к дедупликации обычных блоков (крайне редко) и вставке дубликатов блоков (чаще). [\#5549](https://github.com/ClickHouse/ClickHouse/pull/5549) ([алесапин](https://github.com/alesapin)) -- Исправление функции `arrayEnumerateUniqRanked` для Аргументов с пустыми массивами [\#5559](https://github.com/ClickHouse/ClickHouse/pull/5559) ([proller](https://github.com/proller)) -- Не Подписывайтесь на темы Кафки без намерения опросить какие-либо сообщения. [\#5698](https://github.com/ClickHouse/ClickHouse/pull/5698) ([Иван](https://github.com/abyss7)) -- Сделать настройку `join_use_nulls` не получите никакого эффекта для типов, которые не могут быть внутри Nullable [\#5700](https://github.com/ClickHouse/ClickHouse/pull/5700) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Исправлено `Incorrect size of index granularity` ошибки [\#5720](https://github.com/ClickHouse/ClickHouse/pull/5720) ([коракстер](https://github.com/coraxster)) -- Фиксировать поплавок в десятичные преобразования переполнения [\#5607](https://github.com/ClickHouse/ClickHouse/pull/5607) ([коракстер](https://github.com/coraxster)) -- Смыть буфер, когда `WriteBufferFromHDFS`- деструктор называется. Это исправляет запись в `HDFS`. [\#5684](https://github.com/ClickHouse/ClickHouse/pull/5684) ([Синьдун Пэн](https://github.com/eejoin)) - -#### Улучшение {#improvement-7} - -- Обработать пустые ячейки в `CSV` в качестве значений по умолчанию при настройке `input_format_defaults_for_omitted_fields` это включено. [\#5625](https://github.com/ClickHouse/ClickHouse/pull/5625) ([акузм](https://github.com/akuzm)) -- Неблокирующая загрузка внешних словарей. [\#5567](https://github.com/ClickHouse/ClickHouse/pull/5567) ([Виталий Баранов](https://github.com/vitlibar)) -- Тайм-ауты сети могут быть динамически изменены для уже установленных соединений в соответствии с настройками. [\#4558](https://github.com/ClickHouse/ClickHouse/pull/4558) ([Константин Подшумок](https://github.com/podshumok)) -- С помощью «public\_suffix\_list» для функций `firstSignificantSubdomain`, `cutToFirstSignificantSubdomain`. Он использует идеальную хэш-таблицу, сгенерированную `gperf` с помощью списка, сгенерированного из файла: https://publicsuffix.org/list/public\_suffix\_list.dat (например, теперь мы признаем домен `ac.uk` как несущественные). [\#5030](https://github.com/ClickHouse/ClickHouse/pull/5030) ([Гийом Тассери](https://github.com/YiuRULE)) -- Усыновленный `IPv6` тип данных в системных таблицах; унифицированные столбцы информации о клиенте в `system.processes` и `system.query_log` [\#5640](https://github.com/ClickHouse/ClickHouse/pull/5640) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Использование сеансов для соединений с протоколом совместимости MySQL. \#5476 [\#5646](https://github.com/ClickHouse/ClickHouse/pull/5646) ([Юрий Баранов](https://github.com/yurriy)) -- Поддержка более `ALTER` запросы `ON CLUSTER`. [\#5593](https://github.com/ClickHouse/ClickHouse/pull/5593) [\#5613](https://github.com/ClickHouse/ClickHouse/pull/5613) ([сундили](https://github.com/sundy-li)) -- Поддержка `` раздел в `clickhouse-local` конфигурационный файл. [\#5540](https://github.com/ClickHouse/ClickHouse/pull/5540) ([proller](https://github.com/proller)) -- Разрешить выполнение запроса с помощью `remote` функция таблицы в `clickhouse-local` [\#5627](https://github.com/ClickHouse/ClickHouse/pull/5627) ([proller](https://github.com/proller)) - -#### Улучшение производительности {#performance-improvement-5} - -- Добавьте возможность написать окончательную отметку в конце столбцов MergeTree. Это позволяет избежать бесполезного считывания ключей, находящихся вне диапазона табличных данных. Он включается только в том случае, если используется адаптивная детализация индекса. [\#5624](https://github.com/ClickHouse/ClickHouse/pull/5624) ([алесапин](https://github.com/alesapin)) -- Улучшена производительность таблиц MergeTree на очень медленных файловых системах за счет уменьшения количества `stat` системных вызовов. [\#5648](https://github.com/ClickHouse/ClickHouse/pull/5648) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено снижение производительности при чтении из таблиц MergeTree, которое было введено в версии 19.6. Исправления №5631. [\#5633](https://github.com/ClickHouse/ClickHouse/pull/5633) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-8} - -- Реализованный `TestKeeper` в качестве реализации интерфейса ZooKeeper используется для тестирования [\#5643](https://github.com/ClickHouse/ClickHouse/pull/5643) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) ([Левушкин Алексей](https://github.com/alexey-milovidov)) -- Отныне `.sql` тесты могут выполняться изолированно сервером, параллельно, со случайной базой данных. Это позволяет запускать их быстрее, добавлять новые тесты с пользовательскими конфигурациями серверов и быть уверенным, что различные тесты не влияют друг на друга. [\#5554](https://github.com/ClickHouse/ClickHouse/pull/5554) ([Иван](https://github.com/abyss7)) -- Удалять `` и `` из тестов производительности [\#5672](https://github.com/ClickHouse/ClickHouse/pull/5672) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Исправлено «select\_format» тест производительности для `Pretty` форматы [\#5642](https://github.com/ClickHouse/ClickHouse/pull/5642) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -## ClickHouse релиз 19.9 {#clickhouse-release-19-9} - -### ClickHouse релиз 19.9.3.31, 2019-07-05 {#clickhouse-release-19-9-3-31-2019-07-05} - -#### Исправление ошибок {#bug-fix-23} - -- Исправлена ошибка segfault в Дельта-кодеке, которая влияет на столбцы со значениями размером менее 32 бит. Ошибка привела к случайному повреждению памяти. [\#5786](https://github.com/ClickHouse/ClickHouse/pull/5786) ([алесапин](https://github.com/alesapin)) -- Исправлена редкая ошибка в проверке детали с колонкой LowCardinality. [\#5832](https://github.com/ClickHouse/ClickHouse/pull/5832) ([алесапин](https://github.com/alesapin)) -- Исправлена обработка выхода онлайн / оффлайн в TTL слиться с не-физической столбцов в блоке. [\#5819](https://github.com/ClickHouse/ClickHouse/pull/5819) ([Антон Попов](https://github.com/CurtizJ)) -- Исправьте потенциальный бесконечный спящий режим низкоприоритетных запросов. [\#5842](https://github.com/ClickHouse/ClickHouse/pull/5842) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить, как ClickHouse определяет часовой пояс по умолчанию, как СРТ, а не мирового. [\#5828](https://github.com/ClickHouse/ClickHouse/pull/5828) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, связанная с выполнением распределенного DROP/ALTER/TRUNCATE/OPTIMIZE в кластерных запросах на реплику последователя перед репликой лидера. Теперь они будут выполняться непосредственно на реплике лидера. [\#5757](https://github.com/ClickHouse/ClickHouse/pull/5757) ([алесапин](https://github.com/alesapin)) -- Исправлено состояние гонки, которое приводит к тому, что некоторые запросы могут не отображаться в query\_log сразу же после запроса SYSTEM FLUSH LOGS. [\#5685](https://github.com/ClickHouse/ClickHouse/pull/5685) ([Антон Попов](https://github.com/CurtizJ)) -- Добавлена отсутствующая поддержка постоянных аргументов для `evalMLModel` функция. [\#5820](https://github.com/ClickHouse/ClickHouse/pull/5820) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.9.2.4, 2019-06-24 {#clickhouse-release-19-9-2-4-2019-06-24} - -#### Новая функция {#new-feature-8} - -- Печать информации о замороженных деталях в `system.parts` стол. [\#5471](https://github.com/ClickHouse/ClickHouse/pull/5471) ([proller](https://github.com/proller)) -- Ask client password on clickhouse-запуск клиента на tty, если он не задан в аргументах [\#5092](https://github.com/ClickHouse/ClickHouse/pull/5092) ([proller](https://github.com/proller)) -- Осуществлять `dictGet` и `dictGetOrDefault` функции для десятичных типов. [\#5394](https://github.com/ClickHouse/ClickHouse/pull/5394) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Улучшение {#improvement-8} - -- Инициализации в Debian: добавить службу ожидания [\#5522](https://github.com/ClickHouse/ClickHouse/pull/5522) ([proller](https://github.com/proller)) -- Добавление параметра запрещено по умолчанию, чтобы создать таблицу с подозрительных типов для LowCardinality [\#5448](https://github.com/ClickHouse/ClickHouse/pull/5448) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Регрессионные функции возвращают веса модели, если они не используются в качестве состояния в функции `evalMLMethod`. [\#5411](https://github.com/ClickHouse/ClickHouse/pull/5411) ([Quid37](https://github.com/Quid37)) -- Переименуйте и улучшите методы регрессии. [\#5492](https://github.com/ClickHouse/ClickHouse/pull/5492) ([Quid37](https://github.com/Quid37)) -- Более четкие интерфейсы поиска строк. [\#5586](https://github.com/ClickHouse/ClickHouse/pull/5586) ([Данила Кутенин](https://github.com/danlark1)) - -#### Исправление ошибок {#bug-fix-24} - -- Исправить потенциальную потерю данных в Kafka [\#5445](https://github.com/ClickHouse/ClickHouse/pull/5445) ([Иван](https://github.com/abyss7)) -- Исправьте потенциальную бесконечную петлю в `PrettySpace` форматирование при вызове с нулевыми столбцами [\#5560](https://github.com/ClickHouse/ClickHouse/pull/5560) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Исправлена ошибка переполнения UInt32 в линейных моделях. Разрешить eval ML-модель для аргумента неконстантной модели. [\#5516](https://github.com/ClickHouse/ClickHouse/pull/5516) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- `ALTER TABLE ... DROP INDEX IF EXISTS ...` не следует вызывать исключение, если указанный индекс не существует [\#5524](https://github.com/ClickHouse/ClickHouse/pull/5524) ([Глеб Новиков](https://github.com/NanoBjorn)) -- Исправлена обработка выхода онлайн / оффлайн с `bitmapHasAny` в скалярном подзапросе [\#5528](https://github.com/ClickHouse/ClickHouse/pull/5528) ([Zhichang Ю](https://github.com/yuzhichang)) -- Исправлена ошибка, когда пул соединений репликации не повторяет попытку разрешения узла, даже если кэш DNS был удален. [\#5534](https://github.com/ClickHouse/ClickHouse/pull/5534) ([алесапин](https://github.com/alesapin)) -- Исправлено `ALTER ... MODIFY TTL` на Реплицированном Mergetree. [\#5539](https://github.com/ClickHouse/ClickHouse/pull/5539) ([Антон Попов](https://github.com/CurtizJ)) -- Фиксированная вставка в распределенную таблицу с материализованной колонкой [\#5429](https://github.com/ClickHouse/ClickHouse/pull/5429) ([Азат Хужин](https://github.com/azat)) -- Исправление плохой запас, когда усекают присоединиться хранения [\#5437](https://github.com/ClickHouse/ClickHouse/pull/5437) ([TCeason](https://github.com/TCeason)) -- В последних версиях пакета tzdata некоторые файлы теперь являются символическими ссылками. Текущий механизм обнаружения часового пояса по умолчанию нарушается и дает неверные имена для некоторых часовых поясов. Теперь, по крайней мере, мы заставим имя часового пояса к содержимому TZ, если оно будет предоставлено. [\#5443](https://github.com/ClickHouse/ClickHouse/pull/5443) ([Иван](https://github.com/abyss7)) -- Исправьте некоторые крайне редкие случаи с Многовольницким поисковиком, когда постоянные иглы в сумме имеют длину не менее 16 КБ. Алгоритм пропустил или переписал предыдущие результаты, что может привести к неправильному результату работы алгоритма. `multiSearchAny`. [\#5588](https://github.com/ClickHouse/ClickHouse/pull/5588) ([Данила Кутенин](https://github.com/danlark1)) -- Исправлена проблема, когда настройки для запросов ExternalData не могли использовать параметры ClickHouse. Кроме того, на данный момент настройки `date_time_input_format` и `low_cardinality_allow_in_native_format` не может использоваться из-за неоднозначности имен (во внешних данных это может быть интерпретировано как формат таблицы, а в запросе-как настройка). [\#5455](https://github.com/ClickHouse/ClickHouse/pull/5455) ([Данила Кутенин](https://github.com/danlark1)) -- Исправлена ошибка, когда детали удалялись только из FS, не сбрасывая их из Zookeeper. [\#5520](https://github.com/ClickHouse/ClickHouse/pull/5520) ([алесапин](https://github.com/alesapin)) -- Удалить ведение журнала отладки из протокола MySQL [\#5478](https://github.com/ClickHouse/ClickHouse/pull/5478) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Пропустить ZNONODE во время обработки DDL запроса [\#5489](https://github.com/ClickHouse/ClickHouse/pull/5489) ([Азат Хужин](https://github.com/azat)) -- Фикс микс `UNION ALL` тип столбца результатов. Были случаи с несогласованными данными и типами столбцов результирующих столбцов. [\#5503](https://github.com/ClickHouse/ClickHouse/pull/5503) ([Артем Зуйков](https://github.com/4ertus2)) -- Бросьте исключение на неправильные целые числа в `dictGetT` функции вместо сбоя. [\#5446](https://github.com/ClickHouse/ClickHouse/pull/5446) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка element\_count и load\_factor для хэшированного словаря в `system.dictionaries` стол. [\#5440](https://github.com/ClickHouse/ClickHouse/pull/5440) ([Азат Хужин](https://github.com/azat)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-9} - -- Исправлена сборка без `Brotli` Поддержка сжатия HTTP (`ENABLE_BROTLI=OFF` переменная cmake). [\#5521](https://github.com/ClickHouse/ClickHouse/pull/5521) ([Антон Южанинов](https://github.com/citrin)) -- Включая рев.ч как рев/рев.х [\#5523](https://github.com/ClickHouse/ClickHouse/pull/5523) ([Оривей Деш](https://github.com/orivej)) -- Исправьте предупреждения gcc9 в hyperscan (директива \# line-это зло!) [\#5546](https://github.com/ClickHouse/ClickHouse/pull/5546) ([Данила Кутенин](https://github.com/danlark1)) -- Исправьте все предупреждения при компиляции с gcc-9. Исправлены некоторые проблемы ВНО. Исправьте GCC9 ICE и отправьте его в bugzilla. [\#5498](https://github.com/ClickHouse/ClickHouse/pull/5498) ([Данила Кутенин](https://github.com/danlark1)) -- Фиксированная связь с LLD [\#5477](https://github.com/ClickHouse/ClickHouse/pull/5477) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Удаление неиспользуемых специализаций в словарях [\#5452](https://github.com/ClickHouse/ClickHouse/pull/5452) ([Артем Зуйков](https://github.com/4ertus2)) -- Улучшение тестов производительности для форматирования и синтаксического анализа таблиц для различных типов файлов [\#5497](https://github.com/ClickHouse/ClickHouse/pull/5497) ([Ольга Хвостикова](https://github.com/stavrolia)) -- Исправления для параллельного выполнения тестов [\#5506](https://github.com/ClickHouse/ClickHouse/pull/5506) ([proller](https://github.com/proller)) -- Docker: используйте конфигурации из clickhouse-test [\#5531](https://github.com/ClickHouse/ClickHouse/pull/5531) ([proller](https://github.com/proller)) -- Исправлена компиляция для FreeBSD [\#5447](https://github.com/ClickHouse/ClickHouse/pull/5447) ([proller](https://github.com/proller)) -- Повышение уровня обновления до 1.70 [\#5570](https://github.com/ClickHouse/ClickHouse/pull/5570) ([proller](https://github.com/proller)) -- Исправлена сборка clickhouse как подмодуля [\#5574](https://github.com/ClickHouse/ClickHouse/pull/5574) ([proller](https://github.com/proller)) -- Улучшение тестов производительности JSONExtract [\#5444](https://github.com/ClickHouse/ClickHouse/pull/5444) ([Виталий Баранов](https://github.com/vitlibar)) - -## ClickHouse релиз 19.8 {#clickhouse-release-19-8} - -### ClickHouse релиз 19.8.3.8, 2019-06-11 {#clickhouse-release-19-8-3-8-2019-06-11} - -#### Новые средства {#new-features} - -- Добавлены функции для работы с JSON [\#4686](https://github.com/ClickHouse/ClickHouse/pull/4686) ([hcz](https://github.com/hczhcz)) [\#5124](https://github.com/ClickHouse/ClickHouse/pull/5124). ([Виталий Баранов](https://github.com/vitlibar)) -- Добавьте функцию basename с аналогичным поведением к функции basename, которая существует во многих языках (`os.path.basename` в Python, `basename` in PHP, etc…). Work with both an UNIX-like path or a Windows path. [\#5136](https://github.com/ClickHouse/ClickHouse/pull/5136) ([Гийом Тассери](https://github.com/YiuRULE)) -- Добавлен `LIMIT n, m BY` или `LIMIT m OFFSET n BY` синтаксис для задания смещения N для ограничения на предложение. [\#5138](https://github.com/ClickHouse/ClickHouse/pull/5138) ([Антон Попов](https://github.com/CurtizJ)) -- Добавлен новый тип данных `SimpleAggregateFunction`, что позволяет иметь столбцы с легкой агрегацией в виде `AggregatingMergeTree`. Это может быть использовано только с простыми функциями, такими как `any`, `anyLast`, `sum`, `min`, `max`. [\#4629](https://github.com/ClickHouse/ClickHouse/pull/4629) ([Борис Гранво](https://github.com/bgranvea)) -- Добавлена поддержка непостоянных аргументов в функции `ngramDistance` [\#5198](https://github.com/ClickHouse/ClickHouse/pull/5198) ([Данила Кутенин](https://github.com/danlark1)) -- Добавленные функции `skewPop`, `skewSamp`, `kurtPop` и `kurtSamp` для вычисления асимметрии последовательности, асимметрии образца, эксцесса и эксцесса образца соответственно. [\#5200](https://github.com/ClickHouse/ClickHouse/pull/5200) ([hcz](https://github.com/hczhcz)) -- Поддержка переименования операции для `MaterializeView` место хранения. [\#5209](https://github.com/ClickHouse/ClickHouse/pull/5209) ([Гийом Тассери](https://github.com/YiuRULE)) -- Добавлен сервер, который позволяет подключаться к ClickHouse с помощью клиента MySQL. [\#4715](https://github.com/ClickHouse/ClickHouse/pull/4715) ([Юрий Баранов](https://github.com/yurriy)) -- Добавь `toDecimal*OrZero` и `toDecimal*OrNull` функции. [\#5291](https://github.com/ClickHouse/ClickHouse/pull/5291) ([Артем Зуйков](https://github.com/4ertus2)) -- Поддержка десятичных типов в функциях: `quantile`, `quantiles`, `median`, `quantileExactWeighted`, `quantilesExactWeighted`, medianExactWeighted. [\#5304](https://github.com/ClickHouse/ClickHouse/pull/5304) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавлен `toValidUTF8` function, which replaces all invalid UTF-8 characters by replacement character � (U+FFFD). [\#5322](https://github.com/ClickHouse/ClickHouse/pull/5322) ([Данила Кутенин](https://github.com/danlark1)) -- Добавлен `format` функция. Форматирование константы pattern (упрощенный шаблон формата Python) со строками, перечисленными в аргументах. [\#5330](https://github.com/ClickHouse/ClickHouse/pull/5330) ([Данила Кутенин](https://github.com/danlark1)) -- Добавлен `system.detached_parts` таблица, содержащая информацию об отсоединенных частях `MergeTree` таблицы. [\#5353](https://github.com/ClickHouse/ClickHouse/pull/5353) ([акузм](https://github.com/akuzm)) -- Добавлен `ngramSearch` функция для вычисления несимметричной разности между иглой и стогом сена. [\#5418](https://github.com/ClickHouse/ClickHouse/pull/5418)[\#5422](https://github.com/ClickHouse/ClickHouse/pull/5422) ([Данила Кутенин](https://github.com/danlark1)) -- Реализация основных методов машинного обучения (стохастическая линейная регрессия и логистическая регрессия) с использованием интерфейса агрегатных функций. Имеет различные стратегии обновления весов моделей (простой градиентный спуск, метод импульса, метод Нестерова). Также поддерживаются мини-пакеты нестандартного размера. [\#4943](https://github.com/ClickHouse/ClickHouse/pull/4943) ([Quid37](https://github.com/Quid37)) -- Реализация проекта `geohashEncode` и `geohashDecode` функции. [\#5003](https://github.com/ClickHouse/ClickHouse/pull/5003) ([Василий Немков](https://github.com/Enmk)) -- Добавлена статистическая функция `timeSeriesGroupSum`, который может агрегировать различные временные ряды, которые выборка временных меток не выравнивается. Он будет использовать линейную интерполяцию между двумя временными метками выборки, а затем суммировать временные ряды вместе. Добавлена статистическая функция `timeSeriesGroupRateSum`, который вычисляет скорость временных рядов, а затем суммирует ставки вместе. [\#4542](https://github.com/ClickHouse/ClickHouse/pull/4542) ([Янкуань Лю](https://github.com/LiuYangkuan)) -- Добавленные функции `IPv4CIDRtoIPv4Range` и `IPv6CIDRtoIPv6Range` рассчитать нижний и верхний пределы для IP в подсети с использованием бесклассовой междоменной маршрутизации. [\#5095](https://github.com/ClickHouse/ClickHouse/pull/5095) ([Гийом Тассери](https://github.com/YiuRULE)) -- Добавьте заголовок X-ClickHouse-Summary, когда мы отправляем запрос с помощью HTTP с включенной настройкой `send_progress_in_http_headers`. Возвращает обычную информацию X-ClickHouse-Progress с дополнительной информацией, например, сколько строк и байтов было вставлено в запрос. [\#5116](https://github.com/ClickHouse/ClickHouse/pull/5116) ([Гийом Тассери](https://github.com/YiuRULE)) - -#### Улучшения {#improvements} - -- Добавлен `max_parts_in_total` настройка для семейства таблиц MergeTree (по умолчанию: 100 000), которая предотвращает небезопасную спецификацию ключа раздела \#5166. [\#5171](https://github.com/ClickHouse/ClickHouse/pull/5171) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `clickhouse-obfuscator`: выведите начальное значение для отдельных столбцов, объединив начальное значение с именем столбца, а не с позицией столбца. Это предназначено для преобразования наборов данных с несколькими связанными таблицами, чтобы таблицы оставались соединяемыми после преобразования. [\#5178](https://github.com/ClickHouse/ClickHouse/pull/5178) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавленные функции `JSONExtractRaw`, `JSONExtractKeyAndValues`. Переименованные функции `jsonExtract` к `JSONExtract`. Когда что-то идет не так, эти функции возвращают соответствующие значения, а не наоборот. `NULL`. Модифицированная функция `JSONExtract`, теперь он получает возвращаемый тип из своего последнего параметра и не вводит nullables. Реализован резервный вариант для RapidJSON в случае, если инструкции AVX2 недоступны. Библиотека Simdjson обновлена до новой версии. [\#5235](https://github.com/ClickHouse/ClickHouse/pull/5235) ([Виталий Баранов](https://github.com/vitlibar)) -- Сейчас `if` и `multiIf` функции не зависят от условий `Nullable`, но полагайтесь на ветви для обеспечения совместимости sql. [\#5238](https://github.com/ClickHouse/ClickHouse/pull/5238) ([Цзянь Ву](https://github.com/janplus)) -- `In` теперь предикат генерирует `Null` результат от `Null` входные данные, такие как `Equal` функция. [\#5152](https://github.com/ClickHouse/ClickHouse/pull/5152) ([Цзянь Ву](https://github.com/janplus)) -- Проверьте ограничение по времени для каждого (flush\_interval / poll\_timeout) числа строк из Kafka. Это позволяет чаще отрывать чтение от потребителя Кафки и проверять временные ограничения для потоков верхнего уровня [\#5249](https://github.com/ClickHouse/ClickHouse/pull/5249) ([Иван](https://github.com/abyss7)) -- Соедините рдкафку с комплектным САСЛОМ. Это должно позволить использовать аутентификацию SASL SCRAM [\#5253](https://github.com/ClickHouse/ClickHouse/pull/5253) ([Иван](https://github.com/abyss7)) -- Пакетная версия RowRefList для всех соединений. [\#5267](https://github.com/ClickHouse/ClickHouse/pull/5267) ([Артем Зуйков](https://github.com/4ertus2)) -- clickhouse-server: более информативное прослушивание сообщений об ошибках. [\#5268](https://github.com/ClickHouse/ClickHouse/pull/5268) ([proller](https://github.com/proller)) -- Поддержка словарей в clickhouse-copier для функций в `` [\#5270](https://github.com/ClickHouse/ClickHouse/pull/5270) ([proller](https://github.com/proller)) -- Добавить новую настройку `kafka_commit_every_batch` чтобы регулировать политику Кафки. - Он позволяет установить режим фиксации: после обработки каждой партии сообщений или после записи всего блока в хранилище. Это компромисс между потерей некоторых сообщений или чтением их дважды в некоторых экстремальных ситуациях. [\#5308](https://github.com/ClickHouse/ClickHouse/pull/5308) ([Иван](https://github.com/abyss7)) -- Сделай `windowFunnel` поддержка других целочисленных типов без знака. [\#5320](https://github.com/ClickHouse/ClickHouse/pull/5320) ([сундили](https://github.com/sundy-li)) -- Разрешить теневой виртуальный столбец `_table` в двигателе слияния. [\#5325](https://github.com/ClickHouse/ClickHouse/pull/5325) ([Иван](https://github.com/abyss7)) -- Сделай `sequenceMatch` агрегатные функции поддерживают другие целочисленные типы без знака [\#5339](https://github.com/ClickHouse/ClickHouse/pull/5339) ([сундили](https://github.com/sundy-li)) -- Лучше сообщения об ошибках, если несоответствие контрольной суммы, скорее всего, вызвано аппаратными сбоями. [\#5355](https://github.com/ClickHouse/ClickHouse/pull/5355) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Проверьте, что базовые таблицы поддерживают выборку для `StorageMerge` [\#5366](https://github.com/ClickHouse/ClickHouse/pull/5366) ([Иван](https://github.com/abyss7)) -- Сlose MySQL connections after their usage in external dictionaries. It is related to issue \#893. [\#5395](https://github.com/ClickHouse/ClickHouse/pull/5395) ([Clément Rodriguez](https://github.com/clemrodriguez)) -- Улучшения протокола MySQL Wire. Изменено имя формата на MySQLWire. Использование RAII для вызова RSA\_free. Отключение SSL, если контекст не может быть создан. [\#5419](https://github.com/ClickHouse/ClickHouse/pull/5419) ([Юрий Баранов](https://github.com/yurriy)) -- clickhouse-client: allow to run with unaccessable history file (read-only, no disk space, file is directory, …). [\#5431](https://github.com/ClickHouse/ClickHouse/pull/5431) ([proller](https://github.com/proller)) -- Соблюдайте настройки запросов при асинхронных вставках в распределенные таблицы. [\#4936](https://github.com/ClickHouse/ClickHouse/pull/4936) ([TCeason](https://github.com/TCeason)) -- Переименованные функции `leastSqr` к `simpleLinearRegression`, `LinearRegression` к `linearRegression`, `LogisticRegression` к `logisticRegression`. [\#5391](https://github.com/ClickHouse/ClickHouse/pull/5391) ([Николай Кочетов](https://github.com/KochetovNicolai)) - -#### Улучшения в производительности {#performance-improvements} - -- Распараллеливание обработки деталей невоспроизводимого MergeTree столы В изменить изменить запрос. [\#4639](https://github.com/ClickHouse/ClickHouse/pull/4639) ([Иван Куш](https://github.com/IvanKush)) -- Оптимизация при извлечении регулярных выражений. [\#5193](https://github.com/ClickHouse/ClickHouse/pull/5193) [\#5191](https://github.com/ClickHouse/ClickHouse/pull/5191) ([Данила Кутенин](https://github.com/danlark1)) -- Не добавляйте правый ключевой столбец join к результату соединения, если он используется только в разделе join on. [\#5260](https://github.com/ClickHouse/ClickHouse/pull/5260) ([Артем Зуйков](https://github.com/4ertus2)) -- Заморозьте буфер Кафки после первого пустого ответа. Это позволяет избежать многократных обращений к `ReadBuffer::next()` для пустого результата в некоторых потоках разбора строк. [\#5283](https://github.com/ClickHouse/ClickHouse/pull/5283) ([Иван](https://github.com/abyss7)) -- `concat` оптимизация функций для нескольких аргументов. [\#5357](https://github.com/ClickHouse/ClickHouse/pull/5357) ([Данила Кутенин](https://github.com/danlark1)) -- Query optimisation. Allow push down IN statement while rewriting commа/cross join into inner one. [\#5396](https://github.com/ClickHouse/ClickHouse/pull/5396) ([Артем Зуйков](https://github.com/4ertus2)) -- Обновите нашу реализацию LZ4 со ссылкой на нее, чтобы иметь более быструю декомпрессию. [\#5070](https://github.com/ClickHouse/ClickHouse/pull/5070) ([Данила Кутенин](https://github.com/danlark1)) -- Реализована сортировка MSD radix (на основе kxsort) и частичная сортировка. [\#5129](https://github.com/ClickHouse/ClickHouse/pull/5129) ([Евгений Правда](https://github.com/kvinty)) - -#### Устранение ошибок {#bug-fixes} - -- Исправить пуш требуют колонн с соединением [\#5192](https://github.com/ClickHouse/ClickHouse/pull/5192) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлена ошибка, когда ClickHouse запускался systemd, команда `sudo service clickhouse-server forcerestart` он работал не так, как ожидалось. [\#5204](https://github.com/ClickHouse/ClickHouse/pull/5204) ([proller](https://github.com/proller)) -- Исправьте коды ошибок http в DataPartsExchange (interserver http server на порту 9009 всегда возвращал код 200, даже при ошибках). [\#5216](https://github.com/ClickHouse/ClickHouse/pull/5216) ([proller](https://github.com/proller)) -- Исправить SimpleAggregateFunction на более длительный строк, чем MAX\_SMALL\_STRING\_SIZE [\#5311](https://github.com/ClickHouse/ClickHouse/pull/5311) ([Азат Хужин](https://github.com/azat)) -- Исправьте ошибку для `Decimal` к `Nullable(Decimal)` конверсия в ин. Поддержка других десятичных и десятичных преобразований (включая различные масштабы). [\#5350](https://github.com/ClickHouse/ClickHouse/pull/5350) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлено блокирование FPU в библиотеке simdjson, приводящее к неправильному вычислению `uniqHLL` и `uniqCombined` агрегатная функция и математические функции, такие как `log`. [\#5354](https://github.com/ClickHouse/ClickHouse/pull/5354) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена обработка смешанных случаев const/nonconst в функциях JSON. [\#5435](https://github.com/ClickHouse/ClickHouse/pull/5435) ([Виталий Баранов](https://github.com/vitlibar)) -- Чинить `retention` функция. Теперь все условия, которые удовлетворяют в строке данных, добавляются в состояние данных. [\#5119](https://github.com/ClickHouse/ClickHouse/pull/5119) ([小路](https://github.com/nicelulu)) -- Исправьте тип результата для `quantileExact` с десятичными дробями. [\#5304](https://github.com/ClickHouse/ClickHouse/pull/5304) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Документация {#documentation} - -- Перевести документацию для `CollapsingMergeTree` к китайцам. [\#5168](https://github.com/ClickHouse/ClickHouse/pull/5168) ([张风啸](https://github.com/AlexZFX)) -- Переведите некоторые документы о табличных движках на китайский язык. - [\#5134](https://github.com/ClickHouse/ClickHouse/pull/5134) - [\#5328](https://github.com/ClickHouse/ClickHouse/pull/5328) - ([никогда ли](https://github.com/neverlee)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements} - -- Исправьте некоторые отчеты о дезинфицирующих средствах, которые показывают вероятное использование после освобождения.[\#5139](https://github.com/ClickHouse/ClickHouse/pull/5139) [\#5143](https://github.com/ClickHouse/ClickHouse/pull/5143) [\#5393](https://github.com/ClickHouse/ClickHouse/pull/5393) ([Иван](https://github.com/abyss7)) -- Для удобства переместите тесты производительности из отдельных каталогов. [\#5158](https://github.com/ClickHouse/ClickHouse/pull/5158) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте неправильные тесты производительности. [\#5255](https://github.com/ClickHouse/ClickHouse/pull/5255) ([алесапин](https://github.com/alesapin)) -- Добавлен инструмент для вычисления контрольных сумм, вызванных битовыми переворотами, для отладки аппаратных проблем. [\#5334](https://github.com/ClickHouse/ClickHouse/pull/5334) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Сделайте сценарий runner более удобным для использования. [\#5340](https://github.com/ClickHouse/ClickHouse/pull/5340)[\#5360](https://github.com/ClickHouse/ClickHouse/pull/5360) ([Филимонов](https://github.com/filimonov)) -- Добавьте небольшую инструкцию, как писать тесты производительности. [\#5408](https://github.com/ClickHouse/ClickHouse/pull/5408) ([алесапин](https://github.com/alesapin)) -- Добавить возможность делать замены В создать, заполнить и запросов падение производительности тесты [\#5367](https://github.com/ClickHouse/ClickHouse/pull/5367) ([Ольга Хвостикова](https://github.com/stavrolia)) - -## ClickHouse релиз 19.7 {#clickhouse-release-19-7} - -### ClickHouse релиз 19.7.5.29, 2019-07-05 {#clickhouse-release-19-7-5-29-2019-07-05} - -#### Исправление ошибок {#bug-fix-25} - -- Исправьте регрессию производительности в некоторых запросах с помощью JOIN. [\#5192](https://github.com/ClickHouse/ClickHouse/pull/5192) ([Зимний Чжан](https://github.com/zhang2014)) - -### ClickHouse релиз 19.7.5.27, 2019-06-09 {#clickhouse-release-19-7-5-27-2019-06-09} - -#### Новые средства {#new-features-1} - -- Добавлены функции связанные с растровым изображением `bitmapHasAny` и `bitmapHasAll` по аналогии с `hasAny` и `hasAll` функции для массивов. [\#5279](https://github.com/ClickHouse/ClickHouse/pull/5279) ([Сергей Владыкин](https://github.com/svladykin)) - -#### Устранение ошибок {#bug-fixes-1} - -- Исправлена обработка выхода онлайн / оффлайн на `minmax` Индекс с нулевым значением. [\#5246](https://github.com/ClickHouse/ClickHouse/pull/5246) ([Никита Васильев](https://github.com/nikvas0)) -- Отметить все входные столбцы в пределе по мере необходимости выход. Это исправляет ‘Not found column’ ошибка в некоторых распределенных запросах. [\#5407](https://github.com/ClickHouse/ClickHouse/pull/5407) ([Константин Сергеевич Пан](https://github.com/kvap)) -- Чинить «Column ‘0’ already exists» ошибка в работе `SELECT .. PREWHERE` на колонке с дефолтом [\#5397](https://github.com/ClickHouse/ClickHouse/pull/5397) ([proller](https://github.com/proller)) -- Чинить `ALTER MODIFY TTL` запрос на `ReplicatedMergeTree`. [\#5539](https://github.com/ClickHouse/ClickHouse/pull/5539/commits) ([Антон Попов](https://github.com/CurtizJ)) -- Не разрушайте сервер, когда потребители Kafka не смогли запустить его. [\#5285](https://github.com/ClickHouse/ClickHouse/pull/5285) ([Иван](https://github.com/abyss7)) -- Исправленные функции растрового изображения дают неверный результат. [\#5359](https://github.com/ClickHouse/ClickHouse/pull/5359) ([Энди Янг](https://github.com/andyyzh)) -- Исправить element\_count для хэшированного словаря (не включать дубликаты) [\#5440](https://github.com/ClickHouse/ClickHouse/pull/5440) ([Азат Хужин](https://github.com/azat)) -- Используйте содержимое переменной окружения TZ в качестве имени для часового пояса. В некоторых случаях это помогает правильно определить часовой пояс по умолчанию.[\#5443](https://github.com/ClickHouse/ClickHouse/pull/5443) ([Иван](https://github.com/abyss7)) -- Не пытайтесь конвертировать целые числа в `dictGetT` функции, потому что он не работает правильно. Вместо этого создайте исключение. [\#5446](https://github.com/ClickHouse/ClickHouse/pull/5446) ([Артем Зуйков](https://github.com/4ertus2)) -- Фиксировать параметры в запрос внешних данных по протоколу HTTP. [\#5455](https://github.com/ClickHouse/ClickHouse/pull/5455) ([Данила - Кутенин](https://github.com/danlark1)) -- Исправлена ошибка, когда детали удалялись только из FS, не сбрасывая их из Zookeeper. [\#5520](https://github.com/ClickHouse/ClickHouse/pull/5520) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка сегментации в `bitmapHasAny` функция. [\#5528](https://github.com/ClickHouse/ClickHouse/pull/5528) ([Zhichang Ю](https://github.com/yuzhichang)) -- Исправлена ошибка, когда пул соединений репликации не повторяет попытку разрешения узла, даже если кэш DNS был удален. [\#5534](https://github.com/ClickHouse/ClickHouse/pull/5534) ([алесапин](https://github.com/alesapin)) -- Исправлено `DROP INDEX IF EXISTS` запрос. Сейчас `ALTER TABLE ... DROP INDEX IF EXISTS ...` запрос не вызывает исключения, если указанный индекс не существует. [\#5524](https://github.com/ClickHouse/ClickHouse/pull/5524) ([Глеб Новиков](https://github.com/NanoBjorn)) -- Союз исправить все колонки супертипа. Были случаи с несогласованными данными и типами столбцов результирующих столбцов. [\#5503](https://github.com/ClickHouse/ClickHouse/pull/5503) ([Артем Зуйков](https://github.com/4ertus2)) -- Пропустите ZNONODE во время обработки DDL-запроса. До того, как другой узел удалит znode в очереди задач, тот, который - не обработал его, но уже получил список детей,завершит поток DDLWorker. [\#5489](https://github.com/ClickHouse/ClickHouse/pull/5489) ([Азат Хужин](https://github.com/azat)) -- Исправлена вставка в таблицу Distributed () с материализованным столбцом. [\#5429](https://github.com/ClickHouse/ClickHouse/pull/5429) ([Азат Хужин](https://github.com/azat)) - -### ClickHouse релиз 19.7.3.9, 2019-05-30 {#clickhouse-release-19-7-3-9-2019-05-30} - -#### Новые средства {#new-features-2} - -- Разрешить ограничить диапазон настроек, которые могут быть заданы пользователем. - Эти ограничения можно настроить в профиле настроек пользователя. - [\#4931](https://github.com/ClickHouse/ClickHouse/pull/4931) ([Виталий - Баранов](https://github.com/vitlibar)) -- Добавьте вторую версию функции `groupUniqArray` с дополнительным - `max_size` параметр, ограничивающий размер результирующего массива. Этот - поведение похоже на то, что `groupArray(max_size)(x)` функция. - [\#5026](https://github.com/ClickHouse/ClickHouse/pull/5026) ([Гийом - Тассери](https://github.com/YiuRULE)) -- Для форматов входных файлов TSVWithNames/CSVWithNames порядок столбцов теперь может быть - определяется из заголовка файла. Это контролируется с помощью - `input_format_with_names_use_header` параметр. - [\#5081](https://github.com/ClickHouse/ClickHouse/pull/5081) - ([Александр](https://github.com/Akazz)) - -#### Устранение ошибок {#bug-fixes-2} - -- Сбой с uncompressed\_cache + JOIN во время слияния (\#5197) - [\#5133](https://github.com/ClickHouse/ClickHouse/pull/5133) ([Данила - Кутенин](https://github.com/danlark1)) -- Ошибка сегментации при запросе clickhouse-клиента к системным таблицам. \#5066 - [\#5127](https://github.com/ClickHouse/ClickHouse/pull/5127) - ([Иван](https://github.com/abyss7)) -- Потеря данных при большой нагрузке через KafkaEngine (\#4736) - [\#5080](https://github.com/ClickHouse/ClickHouse/pull/5080) - ([Иван](https://github.com/abyss7)) -- Исправлено очень редкое состояние гонки данных, которое могло произойти при выполнении запроса с объединением всех, включающих по крайней мере два выбора из системы.колонны, система.таблицы, система.детали, система.parts\_tables или таблицы объединить семью и исполнительского изменять столбцы из связанных таблиц одновременно. [\#5189](https://github.com/ClickHouse/ClickHouse/pull/5189) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшения в производительности {#performance-improvements-1} - -- Используйте radix sort для сортировки по одному числовому столбцу в `ORDER BY` без - `LIMIT`. [\#5106](https://github.com/ClickHouse/ClickHouse/pull/5106), - [\#4439](https://github.com/ClickHouse/ClickHouse/pull/4439) - ([Евгений Правда](https://github.com/kvinty), - [Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Документация {#documentation-1} - -- Перевод документации для некоторых движков таблиц на китайский язык. - [\#5107](https://github.com/ClickHouse/ClickHouse/pull/5107), - [\#5094](https://github.com/ClickHouse/ClickHouse/pull/5094), - [\#5087](https://github.com/ClickHouse/ClickHouse/pull/5087) - ([张风啸](https://github.com/AlexZFX)), - [\#5068](https://github.com/ClickHouse/ClickHouse/pull/5068) ([никогда - Ли](https://github.com/neverlee)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements-1} - -- Правильная печать символов UTF-8 в `clickhouse-test`. - [\#5084](https://github.com/ClickHouse/ClickHouse/pull/5084) - ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте параметр командной строки для clickhouse-client, чтобы всегда загружать предложение - данные. [\#5102](https://github.com/ClickHouse/ClickHouse/pull/5102) - ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Устраните некоторые предупреждения PVS-Studio. - [\#5082](https://github.com/ClickHouse/ClickHouse/pull/5082) - ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Обновление LZ4 [\#5040](https://github.com/ClickHouse/ClickHouse/pull/5040) ([Данила - Кутенин](https://github.com/danlark1)) -- Добавьте gperf для построения требований к предстоящему запросу на вытягивание \#5030. - [\#5110](https://github.com/ClickHouse/ClickHouse/pull/5110) - ([proller](https://github.com/proller)) - -## ClickHouse релиз 19.6 {#clickhouse-release-19-6} - -### ClickHouse релиз 19.6.3.18, 2019-06-13 {#clickhouse-release-19-6-3-18-2019-06-13} - -#### Устранение ошибок {#bug-fixes-3} - -- Исправлено в состоянии pushdown для запросов из табличных функций `mysql` и `odbc` и соответствующие табличные двигатели. Это исправляет \#3540 и \#2384. [\#5313](https://github.com/ClickHouse/ClickHouse/pull/5313) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена тупиковая ситуация в Zookeeper. [\#5297](https://github.com/ClickHouse/ClickHouse/pull/5297) ([github1youlc](https://github.com/github1youlc)) -- Разрешить кавычки десятичных знаков в CSV. [\#5284](https://github.com/ClickHouse/ClickHouse/pull/5284) ([Артем Зуйков](https://github.com/4ertus2) -- Запретить преобразование из float Inf/NaN в десятичные дроби (исключение throw). [\#5282](https://github.com/ClickHouse/ClickHouse/pull/5282) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена гонка данных в запросе переименования. [\#5247](https://github.com/ClickHouse/ClickHouse/pull/5247) ([Зимний Чжан](https://github.com/zhang2014)) -- Временно отключите LFAlloc. Использование LFAlloc может привести к большому количеству MAP\_FAILED при выделении несжатого кэша и в результате к сбоям запросов на высоконагруженных серверах. [cfdba93](https://github.com/ClickHouse/ClickHouse/commit/cfdba938ce22f16efeec504f7f90206a515b1280)([Данила Кутенин](https://github.com/danlark1)) - -### ClickHouse релиз 19.6.2.11, 2019-05-13 {#clickhouse-release-19-6-2-11-2019-05-13} - -#### Новые средства {#new-features-3} - -- Выражения TTL для столбцов и таблиц. [\#4212](https://github.com/ClickHouse/ClickHouse/pull/4212) ([Антон Попов](https://github.com/CurtizJ)) -- Добавлена поддержка для `brotli` сжатие для HTTP-ответов (Accept-Encoding: br) [\#4388](https://github.com/ClickHouse/ClickHouse/pull/4388) ([Михаил](https://github.com/fandyushin)) -- Добавлена новая функция `isValidUTF8` для проверки правильности кодировки набора байтов в кодировке utf-8. [\#4934](https://github.com/ClickHouse/ClickHouse/pull/4934) ([Данила Кутенин](https://github.com/danlark1)) -- Добавление новой политики балансировки нагрузки `first_or_random` который отправляет запросы на первый указанный хост, а если он недоступен, то отправляет запросы на случайные хосты shard. Полезно для настройки топологии перекрестной репликации. [\#5012](https://github.com/ClickHouse/ClickHouse/pull/5012) ([nvartolomei](https://github.com/nvartolomei)) - -#### Экспериментальная возможность {#experimental-features-1} - -- Добавить настройку `index_granularity_bytes` (адаптивная степень детализации индекса) для семейства таблиц MergeTree\*. [\#4826](https://github.com/ClickHouse/ClickHouse/pull/4826) ([алесапин](https://github.com/alesapin)) - -#### Улучшения {#improvements-1} - -- Добавлена поддержка непостоянных и отрицательных аргументов размера и длины для функции `substringUTF8`. [\#4989](https://github.com/ClickHouse/ClickHouse/pull/4989) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Отключить push-вниз в правой таблице в левой присоединиться, левой таблицы в правую присоединиться, и обе таблицы полностью присоединиться. Это исправляет неправильные результаты соединения в некоторых случаях. [\#4846](https://github.com/ClickHouse/ClickHouse/pull/4846) ([Иван](https://github.com/abyss7)) -- `clickhouse-copier`: автоматическая загрузка конфигурации задачи из `--task-file` вариант [\#4876](https://github.com/ClickHouse/ClickHouse/pull/4876) ([proller](https://github.com/proller)) -- Добавлен обработчик опечаток для фабрики хранения и фабрики табличных функций. [\#4891](https://github.com/ClickHouse/ClickHouse/pull/4891) ([Данила Кутенин](https://github.com/danlark1)) -- Поддержка звездочек и квалифицированных звездочек для нескольких соединений без вложенных запросов [\#4898](https://github.com/ClickHouse/ClickHouse/pull/4898) ([Артем Зуйков](https://github.com/4ertus2)) -- Сделайте сообщение об ошибке отсутствующего столбца более удобным для пользователя. [\#4915](https://github.com/ClickHouse/ClickHouse/pull/4915) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Улучшения в производительности {#performance-improvements-2} - -- Значительное ускорение от присоединения [\#4924](https://github.com/ClickHouse/ClickHouse/pull/4924) ([Мартийн Баккер](https://github.com/Gladdy)) - -#### Назад Несовместимые Изменения {#backward-incompatible-changes} - -- Заголовок http `Query-Id` был переименован в `X-ClickHouse-Query-Id` для последовательности. [\#4972](https://github.com/ClickHouse/ClickHouse/pull/4972) ([Михаил](https://github.com/fandyushin)) - -#### Устранение ошибок {#bug-fixes-4} - -- Исправлено потенциальное разыменование нулевого указателя в `clickhouse-copier`. [\#4900](https://github.com/ClickHouse/ClickHouse/pull/4900) ([proller](https://github.com/proller)) -- Исправлена ошибка запроса с соединением + массив присоединиться [\#4938](https://github.com/ClickHouse/ClickHouse/pull/4938) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлено зависание при запуске сервера, когда словарь зависит от другого словаря через базу данных с engine=Dictionary. [\#4962](https://github.com/ClickHouse/ClickHouse/pull/4962) ([Виталий Баранов](https://github.com/vitlibar)) -- Partially fix distributed\_product\_mode = local. It's possible to allow columns of local tables in where/having/order by/… via table aliases. Throw exception if table does not have alias. There's not possible to access to the columns without table aliases yet. [\#4986](https://github.com/ClickHouse/ClickHouse/pull/4986) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправьте потенциально неправильный результат для `SELECT DISTINCT` с `JOIN` [\#5001](https://github.com/ClickHouse/ClickHouse/pull/5001) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлено очень редкое состояние гонки данных, которое могло произойти при выполнении запроса с объединением всех, включающих по крайней мере два выбора из системы.колонны, система.таблицы, система.детали, система.parts\_tables или таблицы объединить семью и исполнительского изменять столбцы из связанных таблиц одновременно. [\#5189](https://github.com/ClickHouse/ClickHouse/pull/5189) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements-2} - -- Исправлены ошибки тестирования при запуске clickhouse-сервера на другом хосте [\#4713](https://github.com/ClickHouse/ClickHouse/pull/4713) ([Василий Немков](https://github.com/Enmk)) -- clickhouse-test: отключение последовательностей управления цветом в среде без tty. [\#4937](https://github.com/ClickHouse/ClickHouse/pull/4937) ([алесапин](https://github.com/alesapin)) -- clickhouse-test: разрешить использование любой тестовой базы данных (удалить `test.` квалификация там, где это возможно) [\#5008](https://github.com/ClickHouse/ClickHouse/pull/5008) ([proller](https://github.com/proller)) -- Исправление ошибок утилиты [\#5037](https://github.com/ClickHouse/ClickHouse/pull/5037) ([Виталий Баранов](https://github.com/vitlibar)) -- Yandex LFAlloc был добавлен в ClickHouse для выделения данных MarkCache и UncompressedCache различными способами для более надежного улавливания сегментов [\#4995](https://github.com/ClickHouse/ClickHouse/pull/4995) ([Данила Кутенин](https://github.com/danlark1)) -- Python util, чтобы помочь с backports и changelogs. [\#4949](https://github.com/ClickHouse/ClickHouse/pull/4949) ([Иван](https://github.com/abyss7)) - -## ClickHouse релиз 19.5 {#clickhouse-release-19-5} - -### ClickHouse релиз 19.5.4.22, 2019-05-13 {#clickhouse-release-19-5-4-22-2019-05-13} - -#### Устранение ошибок {#bug-fixes-5} - -- Исправлена возможная ошибка в функциях bitmap\* [\#5220](https://github.com/ClickHouse/ClickHouse/pull/5220) [\#5228](https://github.com/ClickHouse/ClickHouse/pull/5228) ([Энди Янг](https://github.com/andyyzh)) -- Исправлено очень редкое состояние гонки данных, которое могло произойти при выполнении запроса с объединением всех, включающих по крайней мере два выбора из системы.колонны, система.таблицы, система.детали, система.parts\_tables или таблицы объединить семью и исполнительского изменять столбцы из связанных таблиц одновременно. [\#5189](https://github.com/ClickHouse/ClickHouse/pull/5189) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправления ошибок `Set for IN is not created yet in case of using single LowCardinality column in the left part of IN`. Эта ошибка произошла, если столбец LowCardinality был частью первичного ключа. \#5031 [\#5154](https://github.com/ClickHouse/ClickHouse/pull/5154) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Модификация функции удержания: если строка удовлетворяет как первому, так и N-му условию, то в состояние данных добавляется только первое удовлетворенное условие. Теперь все условия, которые удовлетворяют в строке данных, добавляются в состояние данных. [\#5119](https://github.com/ClickHouse/ClickHouse/pull/5119) ([小路](https://github.com/nicelulu)) - -### ClickHouse релиз 19.5.3.8, 2019-04-18 {#clickhouse-release-19-5-3-8-2019-04-18} - -#### Устранение ошибок {#bug-fixes-6} - -- Фиксированный тип установки `max_partitions_per_insert_block` из булев тип uint64. [\#5028](https://github.com/ClickHouse/ClickHouse/pull/5028) ([Мохаммад Хосейн Сехават](https://github.com/mhsekhavat)) - -### ClickHouse релиз 19.5.2.6, 2019-04-15 {#clickhouse-release-19-5-2-6-2019-04-15} - -#### Новые средства {#new-features-4} - -- [Гиперскан](https://github.com/intel/hyperscan) было добавлено несколько совпадений регулярных выражений (функции `multiMatchAny`, `multiMatchAnyIndex`, `multiFuzzyMatchAny`, `multiFuzzyMatchAnyIndex`). [\#4780](https://github.com/ClickHouse/ClickHouse/pull/4780), [\#4841](https://github.com/ClickHouse/ClickHouse/pull/4841) ([Данила Кутенин](https://github.com/danlark1)) -- `multiSearchFirstPosition` была добавлена функция. [\#4780](https://github.com/ClickHouse/ClickHouse/pull/4780) ([Данила Кутенин](https://github.com/danlark1)) -- Реализуйте предварительно заданный фильтр выражений для каждой строки таблиц. [\#4792](https://github.com/ClickHouse/ClickHouse/pull/4792) ([Иван](https://github.com/abyss7)) -- Новый тип индексов пропуска данных на основе фильтров Блума (может использоваться для `equal`, `in` и `like` должностные обязанности). [\#4499](https://github.com/ClickHouse/ClickHouse/pull/4499) ([Никита Васильев](https://github.com/nikvas0)) -- Добавлен `ASOF JOIN` что позволяет запускать запросы, которые присоединяются к самому последнему известному значению. [\#4774](https://github.com/ClickHouse/ClickHouse/pull/4774) [\#4867](https://github.com/ClickHouse/ClickHouse/pull/4867) [\#4863](https://github.com/ClickHouse/ClickHouse/pull/4863) [\#4875](https://github.com/ClickHouse/ClickHouse/pull/4875) ([Мартийн Баккер](https://github.com/Gladdy), [Артем Зуйков](https://github.com/4ertus2)) -- Переписать несколько раз `COMMA JOIN` к `CROSS JOIN`. Затем перепишите их на `INNER JOIN` если можно. [\#4661](https://github.com/ClickHouse/ClickHouse/pull/4661) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Улучшение {#improvement-9} - -- `topK` и `topKWeighted` теперь поддерживает пользовательские `loadFactor` (Исправлена проблема [\#4252](https://github.com/ClickHouse/ClickHouse/issues/4252)). [\#4634](https://github.com/ClickHouse/ClickHouse/pull/4634) ([Кирилл Даньшин](https://github.com/kirillDanshin)) -- Разрешить использовать `parallel_replicas_count > 1` даже для таблиц без выборки (настройка для них просто игнорируется). В предыдущих версиях это приводило к исключениям. [\#4637](https://github.com/ClickHouse/ClickHouse/pull/4637) ([Алексей Елыманов](https://github.com/digitalist)) -- Поддержка `CREATE OR REPLACE VIEW`. Позволяет создать представление или задать новое определение в одном операторе. [\#4654](https://github.com/ClickHouse/ClickHouse/pull/4654) ([Борис Гранво](https://github.com/bgranvea)) -- `Buffer` движок таблицы теперь поддерживает `PREWHERE`. [\#4671](https://github.com/ClickHouse/ClickHouse/pull/4671) ([Янкуань Лю](https://github.com/LiuYangkuan)) -- Добавить возможность запуска реплицированной таблицы без метаданных в zookeeper in `readonly` режим. [\#4691](https://github.com/ClickHouse/ClickHouse/pull/4691) ([алесапин](https://github.com/alesapin)) -- Исправлено мерцание индикатора выполнения в clickhouse-клиенте. Эта проблема была наиболее заметна при использовании `FORMAT Null` с потоковыми запросами. [\#4811](https://github.com/ClickHouse/ClickHouse/pull/4811) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Разрешить отключать функции с помощью `hyperscan` библиотека на основе каждого пользователя, чтобы ограничить потенциально чрезмерное и неконтролируемое использование ресурсов. [\#4816](https://github.com/ClickHouse/ClickHouse/pull/4816) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте номер версии, регистрирующий все ошибки. [\#4824](https://github.com/ClickHouse/ClickHouse/pull/4824) ([proller](https://github.com/proller)) -- Добавлено ограничение на использование `multiMatch` функции, которые требуют размера строки, чтобы вписаться в `unsigned int`. Также добавлено ограничение по количеству аргументов для `multiSearch` функции. [\#4834](https://github.com/ClickHouse/ClickHouse/pull/4834) ([Данила Кутенин](https://github.com/danlark1)) -- Улучшено использование пространства царапин и обработка ошибок в Hyperscan. [\#4866](https://github.com/ClickHouse/ClickHouse/pull/4866) ([Данила Кутенин](https://github.com/danlark1)) -- Заполнить `system.graphite_detentions` из таблицы config of `*GraphiteMergeTree` столы для двигателей. [\#4584](https://github.com/ClickHouse/ClickHouse/pull/4584) ([Mikhail f. Shiryaev](https://github.com/Felixoid)) -- Переименовать `trigramDistance` функция к `ngramDistance` и добавьте больше функций с помощью `CaseInsensitive` и `UTF`. [\#4602](https://github.com/ClickHouse/ClickHouse/pull/4602) ([Данила Кутенин](https://github.com/danlark1)) -- Улучшен расчет индексов пропуска данных. [\#4640](https://github.com/ClickHouse/ClickHouse/pull/4640) ([Никита Васильев](https://github.com/nikvas0)) -- Держать обычные, `DEFAULT`, `MATERIALIZED` и `ALIAS` столбцы в одном списке (Исправлена проблема [\#2867](https://github.com/ClickHouse/ClickHouse/issues/2867)). [\#4707](https://github.com/ClickHouse/ClickHouse/pull/4707) ([Алексей Зателепин](https://github.com/ztlpn)) - -#### Исправление ошибок {#bug-fix-26} - -- Избегать `std::terminate` в случае сбоя выделения памяти. Сейчас `std::bad_alloc` исключение создается, как и ожидалось. [\#4665](https://github.com/ClickHouse/ClickHouse/pull/4665) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено чтение capnproto из буфера. Иногда файлы не были успешно загружены по протоколу HTTP. [\#4674](https://github.com/ClickHouse/ClickHouse/pull/4674) ([Владислав](https://github.com/smirnov-vs)) -- Исправления ошибок `Unknown log entry type: 0` после `OPTIMIZE TABLE FINAL` запрос. [\#4683](https://github.com/ClickHouse/ClickHouse/pull/4683) ([Амос Птица](https://github.com/amosbird)) -- Неверные аргументы, чтобы `hasAny` или `hasAll` функции может привести к обработка выхода онлайн / оффлайн. [\#4698](https://github.com/ClickHouse/ClickHouse/pull/4698) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Взаимоблокировка может произойти во время выполнения `DROP DATABASE dictionary` запрос. [\#4701](https://github.com/ClickHouse/ClickHouse/pull/4701) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить неопределенное поведение в `median` и `quantile` функции. [\#4702](https://github.com/ClickHouse/ClickHouse/pull/4702) ([hcz](https://github.com/hczhcz)) -- Исправьте обнаружение уровня сжатия, когда `network_compression_method` в нижнем регистре. Разбитые в в19.1. [\#4706](https://github.com/ClickHouse/ClickHouse/pull/4706) ([proller](https://github.com/proller)) -- Фиксированное незнание `UTC` настройка (Исправлена проблема [\#4658](https://github.com/ClickHouse/ClickHouse/issues/4658)). [\#4718](https://github.com/ClickHouse/ClickHouse/pull/4718) ([proller](https://github.com/proller)) -- Чинить `histogram` поведение функции с помощью `Distributed` таблицы. [\#4741](https://github.com/ClickHouse/ClickHouse/pull/4741) ([olegkv](https://github.com/olegkv)) -- Исправлен отчет Цан `destroy of a locked mutex`. [\#4742](https://github.com/ClickHouse/ClickHouse/pull/4742) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен отчет TSan о завершении работы из-за состояния гонки в использовании системных журналов. Исправлено потенциальное использование-после освобождения при выключении, когда включен part\_log. [\#4758](https://github.com/ClickHouse/ClickHouse/pull/4758) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить перепроверять детали в `ReplicatedMergeTreeAlterThread` в случае ошибки. [\#4772](https://github.com/ClickHouse/ClickHouse/pull/4772) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Арифметические операции над промежуточными состояниями агрегатной функции не работали для постоянных аргументов (таких как результаты подзапросов). [\#4776](https://github.com/ClickHouse/ClickHouse/pull/4776) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Всегда делайте обратные кавычки имен столбцов в метаданных. В противном случае невозможно создать таблицу с именем столбца `index` (сервер не будет перезапущен из-за неправильной формы `ATTACH` запрос в метаданных). [\#4782](https://github.com/ClickHouse/ClickHouse/pull/4782) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить сбой в работе `ALTER ... MODIFY ORDER BY` на `Distributed` стол. [\#4790](https://github.com/ClickHouse/ClickHouse/pull/4790) ([TCeason](https://github.com/TCeason)) -- Исправлена обработка выхода онлайн / оффлайн в `JOIN ON` с включенной функцией `enable_optimize_predicate_expression`. [\#4794](https://github.com/ClickHouse/ClickHouse/pull/4794) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлена ошибка с добавлением посторонней строки после использования сообщения protobuf от Кафки. [\#4808](https://github.com/ClickHouse/ClickHouse/pull/4808) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправить аварию `JOIN` на не значение столбца против значение null. Чинить `NULLs` в правой клавиш в `ANY JOIN` + `join_use_nulls`. [\#4815](https://github.com/ClickHouse/ClickHouse/pull/4815) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка сегментации в `clickhouse-copier`. [\#4835](https://github.com/ClickHouse/ClickHouse/pull/4835) ([proller](https://github.com/proller)) -- Исправлено состояние гонки в `SELECT` от `system.tables` если таблица переименована или изменена одновременно. [\#4836](https://github.com/ClickHouse/ClickHouse/pull/4836) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена гонка данных при извлечении части данных, которая уже устарела. [\#4839](https://github.com/ClickHouse/ClickHouse/pull/4839) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена редкая гонка данных, которая может произойти во время `RENAME` таблица семейства MergeTree. [\#4844](https://github.com/ClickHouse/ClickHouse/pull/4844) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка сегментации в функции `arrayIntersect`. Ошибка сегментации может произойти, если функция вызывается со смешанными постоянными и обычными аргументами. [\#4847](https://github.com/ClickHouse/ClickHouse/pull/4847) ([Лисян Цянь](https://github.com/fancyqlx)) -- Исправлено чтение из `Array(LowCardinality)` столбец в редком случае, когда столбец содержит длинную последовательность пустых массивов. [\#4850](https://github.com/ClickHouse/ClickHouse/pull/4850) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправить сбой в работе `FULL/RIGHT JOIN` когда мы присоединились на обнуляемой против не допускает значения null. [\#4855](https://github.com/ClickHouse/ClickHouse/pull/4855) ([Артем Зуйков](https://github.com/4ertus2)) -- Чинить `No message received` исключение при извлечении деталей между репликами. [\#4856](https://github.com/ClickHouse/ClickHouse/pull/4856) ([алесапин](https://github.com/alesapin)) -- Исправлено `arrayIntersect` неправильный результат функции в случае нескольких повторяющихся значений в одном массиве. [\#4871](https://github.com/ClickHouse/ClickHouse/pull/4871) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправьте состояние гонки во время параллельной работы `ALTER COLUMN` запросы, которые могут привести к сбою сервера (Исправлена проблема [\#3421](https://github.com/ClickHouse/ClickHouse/issues/3421)). [\#4592](https://github.com/ClickHouse/ClickHouse/pull/4592) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправьте неправильный результат в `FULL/RIGHT JOIN` с колонкой const. [\#4723](https://github.com/ClickHouse/ClickHouse/pull/4723) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправьте дубликаты внутри `GLOBAL JOIN` с Asterisk. [\#4705](https://github.com/ClickHouse/ClickHouse/pull/4705) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправить вычет параметров в `ALTER MODIFY` из колонки `CODEC` если тип столбца не указан. [\#4883](https://github.com/ClickHouse/ClickHouse/pull/4883) ([алесапин](https://github.com/alesapin)) -- Функции `cutQueryStringAndFragment()` и `queryStringAndFragment()` теперь работает правильно, когда `URL` содержит фрагмент и не содержит запроса. [\#4894](https://github.com/ClickHouse/ClickHouse/pull/4894) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправлена редкая ошибка при настройке `min_bytes_to_use_direct_io` больше нуля, что происходит, когда поток должен искать назад в файле столбца. [\#4897](https://github.com/ClickHouse/ClickHouse/pull/4897) ([алесапин](https://github.com/alesapin)) -- Исправьте неправильные типы аргументов для агрегатных функций с помощью `LowCardinality` аргументы (Исправлена проблема [\#4919](https://github.com/ClickHouse/ClickHouse/issues/4919)). [\#4922](https://github.com/ClickHouse/ClickHouse/pull/4922) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправить неправильное имя квалификация в `GLOBAL JOIN`. [\#4969](https://github.com/ClickHouse/ClickHouse/pull/4969) ([Артем Зуйков](https://github.com/4ertus2)) -- Фиксированная функция `toISOWeek` результат за 1970 год. [\#4988](https://github.com/ClickHouse/ClickHouse/pull/4988) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Чинить `DROP`, `TRUNCATE` и `OPTIMIZE` дублирование запросов при выполнении на `ON CLUSTER` для `ReplicatedMergeTree*` столы семейные. [\#4991](https://github.com/ClickHouse/ClickHouse/pull/4991) ([алесапин](https://github.com/alesapin)) - -#### Назад Несовместимые Изменения {#backward-incompatible-change-8} - -- Переименовать настройки `insert_sample_with_metadata` ставить `input_format_defaults_for_omitted_fields`. [\#4771](https://github.com/ClickHouse/ClickHouse/pull/4771) ([Артем Зуйков](https://github.com/4ertus2)) -- Добавлена настройка `max_partitions_per_insert_block` (со значением 100 по умолчанию). Если вставленный блок содержит большее количество разделов, то возникает исключение. Установите его равным 0, если вы хотите удалить ограничение (не рекомендуется). [\#4845](https://github.com/ClickHouse/ClickHouse/pull/4845) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Функции мульти-поиска были переименованы (`multiPosition` к `multiSearchAllPositions`, `multiSearch` к `multiSearchAny`, `firstMatch` к `multiSearchFirstIndex`). [\#4780](https://github.com/ClickHouse/ClickHouse/pull/4780) ([Данила Кутенин](https://github.com/danlark1)) - -#### Улучшение производительности {#performance-improvement-6} - -- Оптимизировать Volnitsky поисковик путем встраивания, дающая около 5-10% улучшение поиска по запросам со многими иглами или много схожих биграмм. [\#4862](https://github.com/ClickHouse/ClickHouse/pull/4862) ([Данила Кутенин](https://github.com/danlark1)) -- Исправлена проблема производительности при настройке `use_uncompressed_cache` больше нуля, который появился при считывании всех данных, содержащихся в кэше. [\#4913](https://github.com/ClickHouse/ClickHouse/pull/4913) ([алесапин](https://github.com/alesapin)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-10} - -- Упрочнение отладочной сборки: более детализированные сопоставления памяти и ASLR; добавление защиты памяти для кэша меток и индекса. Это позволяет найти больше ошибок топтания памяти в случае, когда ASan и MSan не могут этого сделать. [\#4632](https://github.com/ClickHouse/ClickHouse/pull/4632) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте поддержку переменных cmake `ENABLE_PROTOBUF`, `ENABLE_PARQUET` и `ENABLE_BROTLI` который позволяет включить/выключить выше особенностей (так же, как мы можем сделать для librdkafka, MySQL и т. д). [\#4669](https://github.com/ClickHouse/ClickHouse/pull/4669) ([Сильвиу Развивается](https://github.com/silviucpp)) -- Добавьте возможность печати списка процессов и stacktraces всех потоков, если некоторые запросы зависли после тестового запуска. [\#4675](https://github.com/ClickHouse/ClickHouse/pull/4675) ([алесапин](https://github.com/alesapin)) -- Добавить повторные попытки ВКЛ `Connection loss` ошибка в работе `clickhouse-test`. [\#4682](https://github.com/ClickHouse/ClickHouse/pull/4682) ([алесапин](https://github.com/alesapin)) -- Добавьте build FreeBSD с Vagrant и построить с резьбой дезинфицирующее средство на упаковщик скриптов. [\#4712](https://github.com/ClickHouse/ClickHouse/pull/4712) [\#4748](https://github.com/ClickHouse/ClickHouse/pull/4748) ([алесапин](https://github.com/alesapin)) -- Теперь пользователь запросил пароль для пользователя `'default'` во время установки. [\#4725](https://github.com/ClickHouse/ClickHouse/pull/4725) ([proller](https://github.com/proller)) -- Подавить предупреждение в `rdkafka` библиотека. [\#4740](https://github.com/ClickHouse/ClickHouse/pull/4740) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Разрешить возможность сборки без ssl. [\#4750](https://github.com/ClickHouse/ClickHouse/pull/4750) ([proller](https://github.com/proller)) -- Добавьте способ запуска образа clickhouse-server от пользовательского пользователя. [\#4753](https://github.com/ClickHouse/ClickHouse/pull/4753) ([Mikhail f. Shiryaev](https://github.com/Felixoid)) -- Обновите contrib boost до 1.69. [\#4793](https://github.com/ClickHouse/ClickHouse/pull/4793) ([proller](https://github.com/proller)) -- Отключить использование `mremap` при компиляции с помощью дезинфицирующего средства для нитей. Как ни странно, Цан не перехватил его `mremap` (хотя это действительно перехват `mmap`, `munmap`) это приводит к ложным срабатываниям. Исправлен отчет TSan в тестах с сохранением состояния. [\#4859](https://github.com/ClickHouse/ClickHouse/pull/4859) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте тестовую проверку с использованием схемы формата через HTTP-интерфейс. [\#4864](https://github.com/ClickHouse/ClickHouse/pull/4864) ([Виталий Баранов](https://github.com/vitlibar)) - -## ClickHouse релиз 19.4 {#clickhouse-release-19-4} - -### ClickHouse релиз 19.4.4.33, 2019-04-17 {#clickhouse-release-19-4-4-33-2019-04-17} - -#### Устранение ошибок {#bug-fixes-7} - -- Избегать `std::terminate` в случае сбоя выделения памяти. Сейчас `std::bad_alloc` исключение создается, как и ожидалось. [\#4665](https://github.com/ClickHouse/ClickHouse/pull/4665) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено чтение capnproto из буфера. Иногда файлы не были успешно загружены по протоколу HTTP. [\#4674](https://github.com/ClickHouse/ClickHouse/pull/4674) ([Владислав](https://github.com/smirnov-vs)) -- Исправления ошибок `Unknown log entry type: 0` после `OPTIMIZE TABLE FINAL` запрос. [\#4683](https://github.com/ClickHouse/ClickHouse/pull/4683) ([Амос Птица](https://github.com/amosbird)) -- Неверные аргументы, чтобы `hasAny` или `hasAll` функции может привести к обработка выхода онлайн / оффлайн. [\#4698](https://github.com/ClickHouse/ClickHouse/pull/4698) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Взаимоблокировка может произойти во время выполнения `DROP DATABASE dictionary` запрос. [\#4701](https://github.com/ClickHouse/ClickHouse/pull/4701) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить неопределенное поведение в `median` и `quantile` функции. [\#4702](https://github.com/ClickHouse/ClickHouse/pull/4702) ([hcz](https://github.com/hczhcz)) -- Исправьте обнаружение уровня сжатия, когда `network_compression_method` в нижнем регистре. Разбитые в в19.1. [\#4706](https://github.com/ClickHouse/ClickHouse/pull/4706) ([proller](https://github.com/proller)) -- Фиксированное незнание `UTC` настройка (Исправлена проблема [\#4658](https://github.com/ClickHouse/ClickHouse/issues/4658)). [\#4718](https://github.com/ClickHouse/ClickHouse/pull/4718) ([proller](https://github.com/proller)) -- Чинить `histogram` поведение функции с помощью `Distributed` таблицы. [\#4741](https://github.com/ClickHouse/ClickHouse/pull/4741) ([olegkv](https://github.com/olegkv)) -- Исправлен отчет Цан `destroy of a locked mutex`. [\#4742](https://github.com/ClickHouse/ClickHouse/pull/4742) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен отчет TSan о завершении работы из-за состояния гонки в использовании системных журналов. Исправлено потенциальное использование-после освобождения при выключении, когда включен part\_log. [\#4758](https://github.com/ClickHouse/ClickHouse/pull/4758) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить перепроверять детали в `ReplicatedMergeTreeAlterThread` в случае ошибки. [\#4772](https://github.com/ClickHouse/ClickHouse/pull/4772) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Арифметические операции над промежуточными состояниями агрегатной функции не работали для постоянных аргументов (таких как результаты подзапросов). [\#4776](https://github.com/ClickHouse/ClickHouse/pull/4776) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Всегда делайте обратные кавычки имен столбцов в метаданных. В противном случае невозможно создать таблицу с именем столбца `index` (сервер не будет перезапущен из-за неправильной формы `ATTACH` запрос в метаданных). [\#4782](https://github.com/ClickHouse/ClickHouse/pull/4782) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправить сбой в работе `ALTER ... MODIFY ORDER BY` на `Distributed` стол. [\#4790](https://github.com/ClickHouse/ClickHouse/pull/4790) ([TCeason](https://github.com/TCeason)) -- Исправлена обработка выхода онлайн / оффлайн в `JOIN ON` с включенной функцией `enable_optimize_predicate_expression`. [\#4794](https://github.com/ClickHouse/ClickHouse/pull/4794) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлена ошибка с добавлением посторонней строки после использования сообщения protobuf от Кафки. [\#4808](https://github.com/ClickHouse/ClickHouse/pull/4808) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправлена ошибка сегментации в `clickhouse-copier`. [\#4835](https://github.com/ClickHouse/ClickHouse/pull/4835) ([proller](https://github.com/proller)) -- Исправлено состояние гонки в `SELECT` от `system.tables` если таблица переименована или изменена одновременно. [\#4836](https://github.com/ClickHouse/ClickHouse/pull/4836) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена гонка данных при извлечении части данных, которая уже устарела. [\#4839](https://github.com/ClickHouse/ClickHouse/pull/4839) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена редкая гонка данных, которая может произойти во время `RENAME` таблица семейства MergeTree. [\#4844](https://github.com/ClickHouse/ClickHouse/pull/4844) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка сегментации в функции `arrayIntersect`. Ошибка сегментации может произойти, если функция вызывается со смешанными постоянными и обычными аргументами. [\#4847](https://github.com/ClickHouse/ClickHouse/pull/4847) ([Лисян Цянь](https://github.com/fancyqlx)) -- Исправлено чтение из `Array(LowCardinality)` столбец в редком случае, когда столбец содержит длинную последовательность пустых массивов. [\#4850](https://github.com/ClickHouse/ClickHouse/pull/4850) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Чинить `No message received` исключение при извлечении деталей между репликами. [\#4856](https://github.com/ClickHouse/ClickHouse/pull/4856) ([алесапин](https://github.com/alesapin)) -- Исправлено `arrayIntersect` неправильный результат функции в случае нескольких повторяющихся значений в одном массиве. [\#4871](https://github.com/ClickHouse/ClickHouse/pull/4871) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправьте состояние гонки во время параллельной работы `ALTER COLUMN` запросы, которые могут привести к сбою сервера (Исправлена проблема [\#3421](https://github.com/ClickHouse/ClickHouse/issues/3421)). [\#4592](https://github.com/ClickHouse/ClickHouse/pull/4592) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправьте вычет параметров в `ALTER MODIFY` из колонки `CODEC` если тип столбца не указан. [\#4883](https://github.com/ClickHouse/ClickHouse/pull/4883) ([алесапин](https://github.com/alesapin)) -- Функции `cutQueryStringAndFragment()` и `queryStringAndFragment()` теперь работает правильно, когда `URL` содержит фрагмент и не содержит запроса. [\#4894](https://github.com/ClickHouse/ClickHouse/pull/4894) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправлена редкая ошибка при настройке `min_bytes_to_use_direct_io` больше нуля, что происходит, когда поток должен искать назад в файле столбца. [\#4897](https://github.com/ClickHouse/ClickHouse/pull/4897) ([алесапин](https://github.com/alesapin)) -- Исправьте неправильные типы аргументов для агрегатных функций с помощью `LowCardinality` аргументы (Исправлена проблема [\#4919](https://github.com/ClickHouse/ClickHouse/issues/4919)). [\#4922](https://github.com/ClickHouse/ClickHouse/pull/4922) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Фиксированная функция `toISOWeek` результат за 1970 год. [\#4988](https://github.com/ClickHouse/ClickHouse/pull/4988) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Чинить `DROP`, `TRUNCATE` и `OPTIMIZE` дублирование запросов при выполнении на `ON CLUSTER` для `ReplicatedMergeTree*` столы семейные. [\#4991](https://github.com/ClickHouse/ClickHouse/pull/4991) ([алесапин](https://github.com/alesapin)) - -#### Улучшения {#improvements-2} - -- Держать обычные, `DEFAULT`, `MATERIALIZED` и `ALIAS` столбцы в одном списке (Исправлена проблема [\#2867](https://github.com/ClickHouse/ClickHouse/issues/2867)). [\#4707](https://github.com/ClickHouse/ClickHouse/pull/4707) ([Алексей Зателепин](https://github.com/ztlpn)) - -### ClickHouse релиз 19.4.3.11, 2019-04-02 {#clickhouse-release-19-4-3-11-2019-04-02} - -#### Устранение ошибок {#bug-fixes-8} - -- Исправить сбой в работе `FULL/RIGHT JOIN` когда мы присоединились на обнуляемой против не допускает значения null. [\#4855](https://github.com/ClickHouse/ClickHouse/pull/4855) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка сегментации в `clickhouse-copier`. [\#4835](https://github.com/ClickHouse/ClickHouse/pull/4835) ([proller](https://github.com/proller)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-11} - -- Добавьте способ запуска образа clickhouse-server от пользовательского пользователя. [\#4753](https://github.com/ClickHouse/ClickHouse/pull/4753) ([Mikhail f. Shiryaev](https://github.com/Felixoid)) - -### ClickHouse релиз 19.4.2.7, 2019-03-30 {#clickhouse-release-19-4-2-7-2019-03-30} - -#### Устранение ошибок {#bug-fixes-9} - -- Исправлено чтение из `Array(LowCardinality)` столбец в редком случае, когда столбец содержит длинную последовательность пустых массивов. [\#4850](https://github.com/ClickHouse/ClickHouse/pull/4850) ([Николай Кочетов](https://github.com/KochetovNicolai)) - -### ClickHouse релиз 19.4.1.3, 2019-03-19 {#clickhouse-release-19-4-1-3-2019-03-19} - -#### Устранение ошибок {#bug-fixes-10} - -- Исправлены удаленные запросы, содержащие и то, и другое `LIMIT BY` и `LIMIT`. Ранее, если `LIMIT BY` и `LIMIT` были использованы для удаленного запроса, `LIMIT` может случиться и раньше `LIMIT BY`, что привело к слишком отфильтрованному результату. [\#4708](https://github.com/ClickHouse/ClickHouse/pull/4708) ([Константин Сергеевич Пан](https://github.com/kvap)) - -### ClickHouse релиз 19.4.0.49, 2019-03-09 {#clickhouse-release-19-4-0-49-2019-03-09} - -#### Новые средства {#new-features-5} - -- Добавлена полная поддержка для `Protobuf` формат (ввод и вывод, вложенные структуры данных). [\#4174](https://github.com/ClickHouse/ClickHouse/pull/4174) [\#4493](https://github.com/ClickHouse/ClickHouse/pull/4493) ([Виталий Баранов](https://github.com/vitlibar)) -- Добавлены растровые функции с ревущими растровыми изображениями. [\#4207](https://github.com/ClickHouse/ClickHouse/pull/4207) ([Энди Янг](https://github.com/andyyzh)) [\#4568](https://github.com/ClickHouse/ClickHouse/pull/4568) ([Виталий Баранов](https://github.com/vitlibar)) -- Поддержка формата паркета. [\#4448](https://github.com/ClickHouse/ClickHouse/pull/4448) ([proller](https://github.com/proller)) -- Для сравнения нечетких строк было добавлено расстояние N-грамм. Это похоже на Q-граммовые метрики в языке R. [\#4466](https://github.com/ClickHouse/ClickHouse/pull/4466) ([Данила Кутенин](https://github.com/danlark1)) -- Комбинируйте правила для свертки графита из выделенных шаблонов агрегации и хранения. [\#4426](https://github.com/ClickHouse/ClickHouse/pull/4426) ([Mikhail f. Shiryaev](https://github.com/Felixoid)) -- Добавлен `max_execution_speed` и `max_execution_speed_bytes` чтобы ограничить использование ресурсов. Добавлен `min_execution_speed_bytes` установка в дополнение к `min_execution_speed`. [\#4430](https://github.com/ClickHouse/ClickHouse/pull/4430) ([Зимний Чжан](https://github.com/zhang2014)) -- Реализованная функция `flatten`. [\#4555](https://github.com/ClickHouse/ClickHouse/pull/4555) [\#4409](https://github.com/ClickHouse/ClickHouse/pull/4409) ([Алексей-Миловидов](https://github.com/alexey-milovidov), [произв](https://github.com/kzon)) -- Добавленные функции `arrayEnumerateDenseRanked` и `arrayEnumerateUniqRanked` (это как будто `arrayEnumerateUniq` но позволяет точно настроить глубину массива, чтобы заглянуть внутрь многомерных массивов). [\#4475](https://github.com/ClickHouse/ClickHouse/pull/4475) ([proller](https://github.com/proller)) [\#4601](https://github.com/ClickHouse/ClickHouse/pull/4601) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Multiple JOINS with some restrictions: no asterisks, no complex aliases in ON/WHERE/GROUP BY/… [\#4462](https://github.com/ClickHouse/ClickHouse/pull/4462) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Устранение ошибок {#bug-fixes-11} - -- Этот релиз также содержит все исправления ошибок из 19.3 и 19.1. -- Исправлена ошибка в индексах пропуска данных: неправильный порядок гранул после вставки. [\#4407](https://github.com/ClickHouse/ClickHouse/pull/4407) ([Никита Васильев](https://github.com/nikvas0)) -- Исправлено `set` индекс для `Nullable` и `LowCardinality` столбцы. Перед ним, `set` индекс с `Nullable` или `LowCardinality` колонка привела к ошибке `Data type must be deserialized with multiple streams` во время выбора. [\#4594](https://github.com/ClickHouse/ClickHouse/pull/4594) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Правильно установите update\_time на полный `executable` обновление словаря. [\#4551](https://github.com/ClickHouse/ClickHouse/pull/4551) ([Тема Новиков](https://github.com/temoon)) -- Исправлена поломка индикатора выполнения в 19.3. [\#4627](https://github.com/ClickHouse/ClickHouse/pull/4627) ([Филимонов](https://github.com/filimonov)) -- Исправлены несогласованные значения MemoryTracker при сжатии области памяти, в некоторых случаях. [\#4619](https://github.com/ClickHouse/ClickHouse/pull/4619) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено неопределенное поведение в ThreadPool. [\#4612](https://github.com/ClickHouse/ClickHouse/pull/4612) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена очень редкая ошибка с сообщением `mutex lock failed: Invalid argument` это может произойти, когда таблица MergeTree была удалена одновременно с SELECT. [\#4608](https://github.com/ClickHouse/ClickHouse/pull/4608) ([Алексей Зателепин](https://github.com/ztlpn)) -- Совместимость драйвера ODBC с `LowCardinality` тип данных. [\#4381](https://github.com/ClickHouse/ClickHouse/pull/4381) ([proller](https://github.com/proller)) -- FreeBSD: исправление для `AIOcontextPool: Found io_event with unknown id 0` ошибка. [\#4438](https://github.com/ClickHouse/ClickHouse/pull/4438) ([urgordeadbeef](https://github.com/urgordeadbeef)) -- `system.part_log` таблица была создана независимо от конфигурации. [\#4483](https://github.com/ClickHouse/ClickHouse/pull/4483) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте неопределенное поведение в `dictIsIn` функция для словарей кэша. [\#4515](https://github.com/ClickHouse/ClickHouse/pull/4515) ([алесапин](https://github.com/alesapin)) -- Fixed a deadlock when a SELECT query locks the same table multiple times (e.g. from different threads or when executing multiple subqueries) and there is a concurrent DDL query. [\#4535](https://github.com/ClickHouse/ClickHouse/pull/4535) ([Алексей Зателепин](https://github.com/ztlpn)) -- Отключите compile\_expressions по умолчанию, пока мы не получим собственные `llvm` contrib и может проверить его с помощью `clang` и `asan`. [\#4579](https://github.com/ClickHouse/ClickHouse/pull/4579) ([алесапин](https://github.com/alesapin)) -- Предотвращать `std::terminate` когда `invalidate_query` для `clickhouse` внешний источник словаря вернул неверный результирующий набор (пустой или более одной строки или более одного столбца). Исправлена проблема, когда `invalidate_query` выполнялось каждые пять секунд независимо от `lifetime`. [\#4583](https://github.com/ClickHouse/ClickHouse/pull/4583) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Избегайте тупиковой ситуации, когда `invalidate_query` для словаря с `clickhouse` источник был задействован `system.dictionaries` таблица или `Dictionaries` база данных (редкий случай). [\#4599](https://github.com/ClickHouse/ClickHouse/pull/4599) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено перекрестное соединение с пустым местом. [\#4598](https://github.com/ClickHouse/ClickHouse/pull/4598) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена обработка выхода онлайн / оффлайн в функции «replicate» когда передается постоянный аргумент. [\#4603](https://github.com/ClickHouse/ClickHouse/pull/4603) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте лямбда-функцию с помощью оптимизатора предикатов. [\#4408](https://github.com/ClickHouse/ClickHouse/pull/4408) ([Зимний Чжан](https://github.com/zhang2014)) -- Несколько соединений несколько исправлений. [\#4595](https://github.com/ClickHouse/ClickHouse/pull/4595) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Улучшения {#improvements-3} - -- Поддержка псевдонимов в разделе JOIN ON для правых столбцов таблицы. [\#4412](https://github.com/ClickHouse/ClickHouse/pull/4412) ([Артем Зуйков](https://github.com/4ertus2)) -- Результат нескольких соединений требует правильных имен результатов, которые будут использоваться в подсекциях. В результате замените плоские псевдонимы именами источников. [\#4474](https://github.com/ClickHouse/ClickHouse/pull/4474) ([Артем Зуйков](https://github.com/4ertus2)) -- Улучшить нажимаем-вниз-логика вступила заявления. [\#4387](https://github.com/ClickHouse/ClickHouse/pull/4387) ([Иван](https://github.com/abyss7)) - -#### Улучшения в производительности {#performance-improvements-3} - -- Улучшенная эвристика «move to PREWHERE» оптимизация. [\#4405](https://github.com/ClickHouse/ClickHouse/pull/4405) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Используйте правильные таблицы поиска, которые используют API HashTable для 8-битных и 16-битных ключей. [\#4536](https://github.com/ClickHouse/ClickHouse/pull/4536) ([Амос Птица](https://github.com/amosbird)) -- Улучшена производительность сравнения строк. [\#4564](https://github.com/ClickHouse/ClickHouse/pull/4564) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Очистите распределенную очередь DDL в отдельном потоке, чтобы она не замедляла основной цикл, обрабатывающий распределенные задачи DDL. [\#4502](https://github.com/ClickHouse/ClickHouse/pull/4502) ([Алексей Зателепин](https://github.com/ztlpn)) -- Когда `min_bytes_to_use_direct_io` имеет значение 1, не каждый файл был открыт в режиме O\_DIRECT, потому что размер данных для чтения иногда недооценивался размером одного сжатого блока. [\#4526](https://github.com/ClickHouse/ClickHouse/pull/4526) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-12} - -- Добавлена поддержка clang-9 [\#4604](https://github.com/ClickHouse/ClickHouse/pull/4604) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправь ошибку `__asm__` инструкции (опять же) [\#4621](https://github.com/ClickHouse/ClickHouse/pull/4621) ([Константин Подшумок](https://github.com/podshumok)) -- Добавить возможность задавать настройки для `clickhouse-performance-test` из командной строки. [\#4437](https://github.com/ClickHouse/ClickHouse/pull/4437) ([алесапин](https://github.com/alesapin)) -- Добавьте тесты словарей в интеграционные тесты. [\#4477](https://github.com/ClickHouse/ClickHouse/pull/4477) ([алесапин](https://github.com/alesapin)) -- Добавлены запросы от бенчмарка на веб-сайте к автоматизированным тестам производительности. [\#4496](https://github.com/ClickHouse/ClickHouse/pull/4496) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `xxhash.h` не существует во внешнем lz4, потому что это деталь реализации, и ее символы находятся в пространстве имен с `XXH_NAMESPACE` макрос. Когда lz4 является внешним, xxHash также должен быть внешним, и зависимые должны быть связаны с ним. [\#4495](https://github.com/ClickHouse/ClickHouse/pull/4495) ([Оривей Деш](https://github.com/orivej)) -- Исправлен случай, когда `quantileTiming` агрегатная функция может быть вызвана с отрицательным или плавающим аргументом (это исправляет тест fuzz с неопределенным поведением дезинфицирующего средства). [\#4506](https://github.com/ClickHouse/ClickHouse/pull/4506) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправление орфографических ошибок. [\#4531](https://github.com/ClickHouse/ClickHouse/pull/4531) ([сдк2](https://github.com/sdk2)) -- Исправлена компиляция на Mac. [\#4371](https://github.com/ClickHouse/ClickHouse/pull/4371) ([Виталий Баранов](https://github.com/vitlibar)) -- Исправления сборки для FreeBSD и различных необычных конфигураций сборки. [\#4444](https://github.com/ClickHouse/ClickHouse/pull/4444) ([proller](https://github.com/proller)) - -## ClickHouse релиз 19.3 {#clickhouse-release-19-3} - -### ClickHouse релиз 19.3.9.1, 2019-04-02 {#clickhouse-release-19-3-9-1-2019-04-02} - -#### Устранение ошибок {#bug-fixes-12} - -- Исправить сбой в работе `FULL/RIGHT JOIN` когда мы присоединились на обнуляемой против не допускает значения null. [\#4855](https://github.com/ClickHouse/ClickHouse/pull/4855) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка сегментации в `clickhouse-copier`. [\#4835](https://github.com/ClickHouse/ClickHouse/pull/4835) ([proller](https://github.com/proller)) -- Исправлено чтение из `Array(LowCardinality)` столбец в редком случае, когда столбец содержит длинную последовательность пустых массивов. [\#4850](https://github.com/ClickHouse/ClickHouse/pull/4850) ([Николай Кочетов](https://github.com/KochetovNicolai)) - -#### Сборка/Тестирование / Улучшение Упаковки {#buildtestingpackaging-improvement-13} - -- Добавьте способ запуска образа clickhouse-server от пользовательского пользователя [\#4753](https://github.com/ClickHouse/ClickHouse/pull/4753) ([Mikhail f. Shiryaev](https://github.com/Felixoid)) - -### ClickHouse релиз 19.3.7, 2019-03-12 {#clickhouse-release-19-3-7-2019-03-12} - -#### Устранение ошибок {#bug-fixes-13} - -- Исправлена ошибка в \#3920. Эта ошибка проявляется как случайное повреждение кэша (сообщения `Unknown codec family code`, `Cannot seek through file`) и segfaults. Эта ошибка впервые появилась в версии 19.1 и присутствует в версиях до 19.1.10 и 19.3.6. [\#4623](https://github.com/ClickHouse/ClickHouse/pull/4623) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.3.6, 2019-03-02 {#clickhouse-release-19-3-6-2019-03-02} - -#### Устранение ошибок {#bug-fixes-14} - -- При наличии более 1000 потоков в пуле, `std::terminate` может произойти на выходе из потока. [Азат Хужин](https://github.com/azat) [\#4485](https://github.com/ClickHouse/ClickHouse/pull/4485) [\#4505](https://github.com/ClickHouse/ClickHouse/pull/4505) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Теперь это можно создать `ReplicatedMergeTree*` таблицы с комментариями к столбцам без значений по умолчанию и таблицы со столбцами кодеки без комментариев и значений по умолчанию. Также исправлено сравнение кодеков. [\#4523](https://github.com/ClickHouse/ClickHouse/pull/4523) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка при соединении с массивом или кортежем. [\#4552](https://github.com/ClickHouse/ClickHouse/pull/4552) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка в работе clickhouse-копировальной машины с сообщением `ThreadStatus not created`. [\#4540](https://github.com/ClickHouse/ClickHouse/pull/4540) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлено зависание при выключении сервера, если использовались распределенные DDLs. [\#4472](https://github.com/ClickHouse/ClickHouse/pull/4472) ([Алексей Зателепин](https://github.com/ztlpn)) -- Неверные номера столбцов были напечатаны в сообщении об ошибке о синтаксическом анализе текстового формата для столбцов с числом больше 10. [\#4484](https://github.com/ClickHouse/ClickHouse/pull/4484) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements-3} - -- Исправлена сборка с включенным AVX. [\#4527](https://github.com/ClickHouse/ClickHouse/pull/4527) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Включите расширенный учет и учет ввода-вывода на основе хорошо известной версии вместо ядра, под которым он компилируется. [\#4541](https://github.com/ClickHouse/ClickHouse/pull/4541) ([nvartolomei](https://github.com/nvartolomei)) -- Разрешить пропустить настройку core\_dump.size\_limit, предупреждение, а не бросать, если лимита не получится. [\#4473](https://github.com/ClickHouse/ClickHouse/pull/4473) ([proller](https://github.com/proller)) -- Удалил то `inline` метки из `void readBinary(...)` в `Field.cpp`. Также объединены избыточные `namespace DB` блоки. [\#4530](https://github.com/ClickHouse/ClickHouse/pull/4530) ([hcz](https://github.com/hczhcz)) - -### ClickHouse релиз 19.3.5, 2019-02-21 {#clickhouse-release-19-3-5-2019-02-21} - -#### Устранение ошибок {#bug-fixes-15} - -- Исправлена ошибка с обработкой больших запросов вставки http. [\#4454](https://github.com/ClickHouse/ClickHouse/pull/4454) ([алесапин](https://github.com/alesapin)) -- Исправлена обратная несовместимость со старыми версиями из-за неправильной реализации `send_logs_level` установка. [\#4445](https://github.com/ClickHouse/ClickHouse/pull/4445) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена обратная несовместимость функции таблицы `remote` введено с комментариями к колонке. [\#4446](https://github.com/ClickHouse/ClickHouse/pull/4446) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.3.4, 2019-02-16 {#clickhouse-release-19-3-4-2019-02-16} - -#### Улучшения {#improvements-4} - -- Размер индекса таблицы не учитывается для ограничений памяти при выполнении `ATTACH TABLE` запрос. Избегайте возможности того, что стол не может быть прикреплен после отсоединения. [\#4396](https://github.com/ClickHouse/ClickHouse/pull/4396) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Немного повышен лимит на максимальный размер строки и массива, полученный от ZooKeeper. Это позволяет продолжать работу с увеличенным размером `CLIENT_JVMFLAGS=-Djute.maxbuffer=...` на смотрителя зоопарка. [\#4398](https://github.com/ClickHouse/ClickHouse/pull/4398) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Разрешить восстанавливать брошенную реплику, даже если она уже имеет огромное количество узлов в своей очереди. [\#4399](https://github.com/ClickHouse/ClickHouse/pull/4399) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавьте один обязательный аргумент к `SET` индекс (максимальное количество хранимых строк). [\#4386](https://github.com/ClickHouse/ClickHouse/pull/4386) ([Никита Васильев](https://github.com/nikvas0)) - -#### Устранение ошибок {#bug-fixes-16} - -- Исправлено `WITH ROLLUP` результат для группы по одиночке `LowCardinality` ключ. [\#4384](https://github.com/ClickHouse/ClickHouse/pull/4384) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Исправлена ошибка в заданном индексе (удаление гранулы, если она содержит более `max_rows` грядки). [\#4386](https://github.com/ClickHouse/ClickHouse/pull/4386) ([Никита Васильев](https://github.com/nikvas0)) -- Множество исправлений для сборки FreeBSD. [\#4397](https://github.com/ClickHouse/ClickHouse/pull/4397) ([proller](https://github.com/proller)) -- Исправлена подстановка псевдонимов в запросах с подзапросом, содержащим один и тот же псевдоним (проблема [\#4110](https://github.com/ClickHouse/ClickHouse/issues/4110)). [\#4351](https://github.com/ClickHouse/ClickHouse/pull/4351) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements-4} - -- Добавить возможность запуска `clickhouse-server` для тестов без состояния в образе docker. [\#4347](https://github.com/ClickHouse/ClickHouse/pull/4347) ([Василий Немков](https://github.com/Enmk)) - -### ClickHouse релиз 19.3.3, 2019-02-13 {#clickhouse-release-19-3-3-2019-02-13} - -#### Новые средства {#new-features-6} - -- Добавил тот `KILL MUTATION` оператор, который позволяет удалять мутации, которые по каким-то причинам застряли. Добавлен `latest_failed_part`, `latest_fail_time`, `latest_fail_reason` поля к тому же `system.mutations` таблица для более легкого устранения неполадок. [\#4287](https://github.com/ClickHouse/ClickHouse/pull/4287) ([Алексей Зателепин](https://github.com/ztlpn)) -- Добавлена статистическая функция `entropy` который вычисляет энтропию Шеннона. [\#4238](https://github.com/ClickHouse/ClickHouse/pull/4238) ([Quid37](https://github.com/Quid37)) -- Добавлена возможность отправлять запросы `INSERT INTO tbl VALUES (....` к серверу без разделения на `query` и `data` части. [\#4301](https://github.com/ClickHouse/ClickHouse/pull/4301) ([алесапин](https://github.com/alesapin)) -- Общая реализация проекта `arrayWithConstant` была добавлена функция. [\#4322](https://github.com/ClickHouse/ClickHouse/pull/4322) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Реализованный `NOT BETWEEN` оператор сравнения. [\#4228](https://github.com/ClickHouse/ClickHouse/pull/4228) ([Дмитрий Наумов](https://github.com/nezed)) -- Осуществлять `sumMapFiltered` для того чтобы иметь возможность ограничить количество ключей для которых значения будут суммироваться по формуле `sumMap`. [\#4129](https://github.com/ClickHouse/ClickHouse/pull/4129) ([Léo Ercolanelli](https://github.com/ercolanelli-leo)) -- Добавлена поддержка `Nullable` напечатать `mysql` табличная функция. [\#4198](https://github.com/ClickHouse/ClickHouse/pull/4198) ([Emmanuel Donin de Rosière](https://github.com/edonin)) -- Поддержка произвольных константных выражений в `LIMIT` пункт. [\#4246](https://github.com/ClickHouse/ClickHouse/pull/4246) ([k3box](https://github.com/k3box)) -- Добавлен `topKWeighted` агрегатная функция, принимающая дополнительный аргумент с весом (целое число без знака). [\#4245](https://github.com/ClickHouse/ClickHouse/pull/4245) ([Андрей Гольман](https://github.com/andrewgolman)) -- `StorageJoin` теперь поддерживать `join_any_take_last_row` настройка, позволяющая перезаписать существующие значения одного и того же ключа. [\#3973](https://github.com/ClickHouse/ClickHouse/pull/3973) ([Амос Птица](https://github.com/amosbird) -- Добавлена функция `toStartOfInterval`. [\#4304](https://github.com/ClickHouse/ClickHouse/pull/4304) ([Виталий Баранов](https://github.com/vitlibar)) -- Добавлен `RowBinaryWithNamesAndTypes` формат. [\#4200](https://github.com/ClickHouse/ClickHouse/pull/4200) ([Козлюк Олег Викторович](https://github.com/DarkWanderer)) -- Добавлен `IPv4` и `IPv6` тип данных. Более эффективное внедрение `IPv*` функции. [\#3669](https://github.com/ClickHouse/ClickHouse/pull/3669) ([Василий Немков](https://github.com/Enmk)) -- Добавлена функция `toStartOfTenMinutes()`. [\#4298](https://github.com/ClickHouse/ClickHouse/pull/4298) ([Виталий Баранов](https://github.com/vitlibar)) -- Добавлен `Protobuf` выходной формат. [\#4005](https://github.com/ClickHouse/ClickHouse/pull/4005) [\#4158](https://github.com/ClickHouse/ClickHouse/pull/4158) ([Виталий Баранов](https://github.com/vitlibar)) -- Добавлена поддержка brotli для HTTP-интерфейса для импорта данных (вставки). [\#4235](https://github.com/ClickHouse/ClickHouse/pull/4235) ([Михаил](https://github.com/fandyushin)) -- Добавлены подсказки, когда пользователь делает опечатку в имени функции или вводит клиент командной строки. [\#4239](https://github.com/ClickHouse/ClickHouse/pull/4239) ([Данила Кутенин](https://github.com/danlark1)) -- Добавлен `Query-Id` к заголовку HTTP-ответа сервера. [\#4231](https://github.com/ClickHouse/ClickHouse/pull/4231) ([Михаил](https://github.com/fandyushin)) - -#### Экспериментальная возможность {#experimental-features-2} - -- Добавлен `minmax` и `set` индексы пропуска данных для семейства движков таблиц MergeTree. [\#4143](https://github.com/ClickHouse/ClickHouse/pull/4143) ([Никита Васильев](https://github.com/nikvas0)) -- Добавлено преобразование из `CROSS JOIN` к `INNER JOIN` если можно. [\#4221](https://github.com/ClickHouse/ClickHouse/pull/4221) [\#4266](https://github.com/ClickHouse/ClickHouse/pull/4266) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Устранение ошибок {#bug-fixes-17} - -- Исправлено `Not found column` для повторяющихся столбцов в `JOIN ON` раздел. [\#4279](https://github.com/ClickHouse/ClickHouse/pull/4279) ([Артем Зуйков](https://github.com/4ertus2)) -- Сделай `START REPLICATED SENDS` команда начала репликации отправляет. [\#4229](https://github.com/ClickHouse/ClickHouse/pull/4229) ([nvartolomei](https://github.com/nvartolomei)) -- Фиксированное выполнение агрегатных функций с помощью `Array(LowCardinality)` аргументы. [\#4055](https://github.com/ClickHouse/ClickHouse/pull/4055) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Исправлено неправильное поведение при выполнении `INSERT ... SELECT ... FROM file(...)` запрос и файл имеет `CSVWithNames` или `TSVWIthNames` формат и первая строка данных отсутствуют. [\#4297](https://github.com/ClickHouse/ClickHouse/pull/4297) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка при перезагрузке словаря, если словарь недоступен. Эта ошибка появилась в 19.1.6. [\#4188](https://github.com/ClickHouse/ClickHouse/pull/4188) ([proller](https://github.com/proller)) -- Исправлено `ALL JOIN` с дубликатами в правой таблице. [\#4184](https://github.com/ClickHouse/ClickHouse/pull/4184) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка сегментации с помощью `use_uncompressed_cache=1` и исключение с неправильным несжатым размером. Эта ошибка появилась в 19.1.6. [\#4186](https://github.com/ClickHouse/ClickHouse/pull/4186) ([алесапин](https://github.com/alesapin)) -- Исправлено `compile_expressions` ошибка с сопоставлением больших (более int16) дат. [\#4341](https://github.com/ClickHouse/ClickHouse/pull/4341) ([алесапин](https://github.com/alesapin)) -- Исправлена бесконечная петля при выборе функции из таблицы `numbers(0)`. [\#4280](https://github.com/ClickHouse/ClickHouse/pull/4280) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Временно отключите оптимизацию предикатов для `ORDER BY`. [\#3890](https://github.com/ClickHouse/ClickHouse/pull/3890) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлено `Illegal instruction` ошибка при использовании функций base64 на старых процессорах. Эта ошибка была воспроизведена только тогда, когда ClickHouse был скомпилирован с помощью gcc-8. [\#4275](https://github.com/ClickHouse/ClickHouse/pull/4275) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено `No message received` ошибка при взаимодействии с драйвером PostgreSQL ODBC через TLS-соединение. Также исправлена ошибка segfault при использовании драйвера MySQL ODBC. [\#4170](https://github.com/ClickHouse/ClickHouse/pull/4170) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен неверный результат, когда `Date` и `DateTime` аргументы используются в ветвях условного оператора (функции `if`). Добавлен общий случай для функции `if`. [\#4243](https://github.com/ClickHouse/ClickHouse/pull/4243) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Словари ClickHouse теперь загружаются внутри `clickhouse` процесс. [\#4166](https://github.com/ClickHouse/ClickHouse/pull/4166) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена тупиковая ситуация, когда `SELECT` из-за стола с `File` двигатель был восстановлен после того, как `No such file or directory` ошибка. [\#4161](https://github.com/ClickHouse/ClickHouse/pull/4161) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Фиксированное состояние гонки при выборе из `system.tables` может дать `table doesn't exist` ошибка. [\#4313](https://github.com/ClickHouse/ClickHouse/pull/4313) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `clickhouse-client` может segfault на выходе при загрузке данных для предложений командной строки, если он был запущен в интерактивном режиме. [\#4317](https://github.com/ClickHouse/ClickHouse/pull/4317) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка при выполнении мутаций, содержащих `IN` операторы давали неверные результаты. [\#4099](https://github.com/ClickHouse/ClickHouse/pull/4099) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправлена ошибка: если есть база данных с `Dictionary` движок, все словари принудительно загружаются при запуске сервера, и если есть словарь с источником ClickHouse от localhost, то словарь не может загрузиться. [\#4255](https://github.com/ClickHouse/ClickHouse/pull/4255) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка при повторной попытке создания системных журналов при выключении сервера. [\#4254](https://github.com/ClickHouse/ClickHouse/pull/4254) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Правильно верните правильный тип и правильно обработайте замки `joinGet` функция. [\#4153](https://github.com/ClickHouse/ClickHouse/pull/4153) ([Амос Птица](https://github.com/amosbird)) -- Добавлен `sumMapWithOverflow` функция. [\#4151](https://github.com/ClickHouse/ClickHouse/pull/4151) ([Léo Ercolanelli](https://github.com/ercolanelli-leo)) -- Исправлена обработка выхода онлайн / оффлайн с `allow_experimental_multiple_joins_emulation`. [52de2c](https://github.com/ClickHouse/ClickHouse/commit/52de2cd927f7b5257dd67e175f0a5560a48840d0) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлена ошибка с неправильным `Date` и `DateTime` сравнение. [\#4237](https://github.com/ClickHouse/ClickHouse/pull/4237) ([valexey](https://github.com/valexey)) -- Исправлен тест fuzz при неопределенном поведении дезинфицирующего средства: добавлена проверка типа параметра для `quantile*Weighted` семейство функций. [\#4145](https://github.com/ClickHouse/ClickHouse/pull/4145) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено редкое состояние гонки при удалении старых частей данных может произойти сбой с помощью `File not found` ошибка. [\#4378](https://github.com/ClickHouse/ClickHouse/pull/4378) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка установки пакета с отсутствующим /etc / clickhouse-server / config.XML. [\#4343](https://github.com/ClickHouse/ClickHouse/pull/4343) ([proller](https://github.com/proller)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements-5} - -- Пакет Debian: исправьте/etc/clickhouse-server / preprocessed link в соответствии с конфигурацией. [\#4205](https://github.com/ClickHouse/ClickHouse/pull/4205) ([proller](https://github.com/proller)) -- Различные исправления сборки для FreeBSD. [\#4225](https://github.com/ClickHouse/ClickHouse/pull/4225) ([proller](https://github.com/proller)) -- Добавлена возможность создавать, заполнять и удалять таблицы в perftest. [\#4220](https://github.com/ClickHouse/ClickHouse/pull/4220) ([алесапин](https://github.com/alesapin)) -- Добавлен скрипт для проверки наличия дубликатов включений. [\#4326](https://github.com/ClickHouse/ClickHouse/pull/4326) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена возможность выполнения запросов по индексу в тесте производительности. [\#4264](https://github.com/ClickHouse/ClickHouse/pull/4264) ([алесапин](https://github.com/alesapin)) -- Предлагается установить пакет с отладочными символами. [\#4274](https://github.com/ClickHouse/ClickHouse/pull/4274) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Рефакторинг производительности-тест. Улучшенная регистрация и обработка сигналов. [\#4171](https://github.com/ClickHouse/ClickHouse/pull/4171) ([алесапин](https://github.com/alesapin)) -- Добавлены документы в анонимизированный Яндекс.Метрика набирает данные. [\#4164](https://github.com/ClickHouse/ClickHouse/pull/4164) ([алесапин](https://github.com/alesapin)) -- Аdded tool for converting an old month-partitioned part to the custom-partitioned format. [\#4195](https://github.com/ClickHouse/ClickHouse/pull/4195) ([Алексей Зателепин](https://github.com/ztlpn)) -- Добавлены документы о двух наборах данных в s3. [\#4144](https://github.com/ClickHouse/ClickHouse/pull/4144) ([алесапин](https://github.com/alesapin)) -- Добавлен скрипт, который создает список изменений из описания запросов на вытягивание. [\#4169](https://github.com/ClickHouse/ClickHouse/pull/4169) [\#4173](https://github.com/ClickHouse/ClickHouse/pull/4173) ([Кочетовниколай](https://github.com/KochetovNicolai)) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Добавлен кукольный модуль для Clickhouse. [\#4182](https://github.com/ClickHouse/ClickHouse/pull/4182) ([Максим Федотов](https://github.com/MaxFedotov)) -- Добавлены документы для группы недокументированных функций. [\#4168](https://github.com/ClickHouse/ClickHouse/pull/4168) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправление сборки рук. [\#4210](https://github.com/ClickHouse/ClickHouse/pull/4210)[\#4306](https://github.com/ClickHouse/ClickHouse/pull/4306) [\#4291](https://github.com/ClickHouse/ClickHouse/pull/4291) ([proller](https://github.com/proller)) ([proller](https://github.com/proller)) -- Словарные тесты теперь можно запускать из `ctest`. [\#4189](https://github.com/ClickHouse/ClickHouse/pull/4189) ([proller](https://github.com/proller)) -- Сейчас `/etc/ssl` используется в качестве каталога по умолчанию с SSL-сертификатами. [\#4167](https://github.com/ClickHouse/ClickHouse/pull/4167) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена проверка инструкций SSE и AVX при запуске. [\#4234](https://github.com/ClickHouse/ClickHouse/pull/4234) ([Игр](https://github.com/igron99)) -- Init скрипт будет ждать сервер до запуска. [\#4281](https://github.com/ClickHouse/ClickHouse/pull/4281) ([proller](https://github.com/proller)) - -#### Назад Несовместимые Изменения {#backward-incompatible-changes-1} - -- Удаленный `allow_experimental_low_cardinality_type` установка. `LowCardinality` типы данных уже готовы к производству. [\#4323](https://github.com/ClickHouse/ClickHouse/pull/4323) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Уменьшите размер маркированного кэша и размер несжатого кэша соответственно доступному объему памяти. [\#4240](https://github.com/ClickHouse/ClickHouse/pull/4240) ([Лопатин Константин](https://github.com/k-lopatin) -- Добавить ключевые слова `INDEX` в `CREATE TABLE` запрос. Столбец с именем `index` должен быть заключен в кавычки с обратными или двойными кавычками: `` `index` ``. [\#4143](https://github.com/ClickHouse/ClickHouse/pull/4143) ([Никита Васильев](https://github.com/nikvas0)) -- `sumMap` теперь продвигайте тип результата вместо переполнения. Старое `sumMap` поведение может быть получено с помощью `sumMapWithOverflow` функция. [\#4151](https://github.com/ClickHouse/ClickHouse/pull/4151) ([Léo Ercolanelli](https://github.com/ercolanelli-leo)) - -#### Улучшения в производительности {#performance-improvements-4} - -- `std::sort` заменено на `pdqsort` для запросов без `LIMIT`. [\#4236](https://github.com/ClickHouse/ClickHouse/pull/4236) ([Евгений Правда](https://github.com/kvinty)) -- Теперь сервер повторно использует потоки из глобального пула потоков. Это влияет на производительность в некоторых угловых случаях. [\#4150](https://github.com/ClickHouse/ClickHouse/pull/4150) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшения {#improvements-5} - -- Реализована поддержка AIO для FreeBSD. [\#4305](https://github.com/ClickHouse/ClickHouse/pull/4305) ([urgordeadbeef](https://github.com/urgordeadbeef)) -- `SELECT * FROM a JOIN b USING a, b` теперь вернуться `a` и `b` столбцы только из левой таблицы. [\#4141](https://github.com/ClickHouse/ClickHouse/pull/4141) ([Артем Зуйков](https://github.com/4ertus2)) -- Позволять `-C` возможность работы клиента в качестве `-c` вариант. [\#4232](https://github.com/ClickHouse/ClickHouse/pull/4232) ([семинсергей](https://github.com/syominsergey)) -- Теперь вариант `--password` использовать без стоимости требует пароль из stdin. [\#4230](https://github.com/ClickHouse/ClickHouse/pull/4230) ([BSD\_Conqueror](https://github.com/bsd-conqueror)) -- Добавлена подсветка неэскапированных метасимволов в строковых литералах, содержащих `LIKE` выражения или регулярные выражения. [\#4327](https://github.com/ClickHouse/ClickHouse/pull/4327) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена отмена HTTP-запросов только для чтения, если клиентский сокет уходит. [\#4213](https://github.com/ClickHouse/ClickHouse/pull/4213) ([nvartolomei](https://github.com/nvartolomei)) -- Теперь сервер сообщает о прогрессе, чтобы сохранить клиентские соединения живыми. [\#4215](https://github.com/ClickHouse/ClickHouse/pull/4215) ([Иван](https://github.com/abyss7)) -- Немного лучше сообщение с причиной для оптимизации запроса с помощью `optimize_throw_if_noop` настройка включена. [\#4294](https://github.com/ClickHouse/ClickHouse/pull/4294) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена поддержка `--version` опция для сервера clickhouse. [\#4251](https://github.com/ClickHouse/ClickHouse/pull/4251) ([Лопатин Константин](https://github.com/k-lopatin)) -- Добавлен `--help/-h` опцион на `clickhouse-server`. [\#4233](https://github.com/ClickHouse/ClickHouse/pull/4233) ([Юрий Баранов](https://github.com/yurriy)) -- Добавлена поддержка скалярных подзапросов с результатом состояния агрегатной функции. [\#4348](https://github.com/ClickHouse/ClickHouse/pull/4348) ([Николай Кочетов](https://github.com/KochetovNicolai)) -- Улучшено время завершения работы сервера и изменено время ожидания. [\#4372](https://github.com/ClickHouse/ClickHouse/pull/4372) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлена информация о настройке replicated\_can\_become\_leader для system.реплики и добавить ведение журнала, если реплика не будет пытаться стать лидером. [\#4379](https://github.com/ClickHouse/ClickHouse/pull/4379) ([Алексей Зателепин](https://github.com/ztlpn)) - -## ClickHouse релиз 19.1 {#clickhouse-release-19-1} - -### ClickHouse релиз 19.1.14, 2019-03-14 {#clickhouse-release-19-1-14-2019-03-14} - -- Исправления ошибок `Column ... queried more than once` это может произойти, если установка `asterisk_left_columns_only` имеет значение 1 в случае использования `GLOBAL JOIN` с `SELECT *` (редкий случай). Эта проблема не существует в версии 19.3 и более поздних версиях. [6bac7d8d](https://github.com/ClickHouse/ClickHouse/pull/4692/commits/6bac7d8d11a9b0d6de0b32b53c47eb2f6f8e7062) ([Артем Зуйков](https://github.com/4ertus2)) - -### ClickHouse релиз 19.1.13, 2019-03-12 {#clickhouse-release-19-1-13-2019-03-12} - -Этот релиз содержит точно такой же набор исправлений, как и 19.3.7. - -### ClickHouse релиз 19.1.10, 2019-03-03 {#clickhouse-release-19-1-10-2019-03-03} - -Этот релиз содержит точно такой же набор исправлений, как и 19.3.6. - -## ClickHouse релиз 19.1 {#clickhouse-release-19-1-1} - -### ClickHouse релиз 19.1.9, 2019-02-21 {#clickhouse-release-19-1-9-2019-02-21} - -#### Устранение ошибок {#bug-fixes-18} - -- Исправлена обратная несовместимость со старыми версиями из-за неправильной реализации `send_logs_level` установка. [\#4445](https://github.com/ClickHouse/ClickHouse/pull/4445) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена обратная несовместимость функции таблицы `remote` введено с комментариями к колонке. [\#4446](https://github.com/ClickHouse/ClickHouse/pull/4446) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.1.8, 2019-02-16 {#clickhouse-release-19-1-8-2019-02-16} - -#### Устранение ошибок {#bug-fixes-19} - -- Исправлена ошибка установки пакета с отсутствующим /etc / clickhouse-server / config.XML. [\#4343](https://github.com/ClickHouse/ClickHouse/pull/4343) ([proller](https://github.com/proller)) - -## ClickHouse релиз 19.1 {#clickhouse-release-19-1-2} - -### ClickHouse релиз 19.1.7, 2019-02-15 {#clickhouse-release-19-1-7-2019-02-15} - -#### Устранение ошибок {#bug-fixes-20} - -- Правильно возвращайте правильный тип и правильно обрабатывайте замки `joinGet` функция. [\#4153](https://github.com/ClickHouse/ClickHouse/pull/4153) ([Амос Птица](https://github.com/amosbird)) -- Исправлена ошибка при повторной попытке создания системных журналов при выключении сервера. [\#4254](https://github.com/ClickHouse/ClickHouse/pull/4254) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка: если есть база данных с `Dictionary` движок, все словари принудительно загружаются при запуске сервера, и если есть словарь с источником ClickHouse от localhost, то словарь не может загрузиться. [\#4255](https://github.com/ClickHouse/ClickHouse/pull/4255) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка при выполнении мутаций, содержащих `IN` операторы давали неверные результаты. [\#4099](https://github.com/ClickHouse/ClickHouse/pull/4099) ([Алексей Зателепин](https://github.com/ztlpn)) -- `clickhouse-client` может segfault на выходе при загрузке данных для предложений командной строки, если он был запущен в интерактивном режиме. [\#4317](https://github.com/ClickHouse/ClickHouse/pull/4317) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Фиксированное состояние гонки при выборе из `system.tables` может дать `table doesn't exist` ошибка. [\#4313](https://github.com/ClickHouse/ClickHouse/pull/4313) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена тупиковая ситуация, когда `SELECT` из-за стола с надписью: `File` двигатель был восстановлен после того, как `No such file or directory` ошибка. [\#4161](https://github.com/ClickHouse/ClickHouse/pull/4161) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка: локальные словари ClickHouse загружаются через TCP, но должны загружаться внутри процесса. [\#4166](https://github.com/ClickHouse/ClickHouse/pull/4166) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено `No message received` ошибка при взаимодействии с драйвером PostgreSQL ODBC через TLS-соединение. Также исправлена ошибка segfault при использовании драйвера MySQL ODBC. [\#4170](https://github.com/ClickHouse/ClickHouse/pull/4170) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Временно отключите оптимизацию предикатов для `ORDER BY`. [\#3890](https://github.com/ClickHouse/ClickHouse/pull/3890) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлена бесконечная петля при выборе функции из таблицы `numbers(0)`. [\#4280](https://github.com/ClickHouse/ClickHouse/pull/4280) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлено `compile_expressions` ошибка с сопоставлением больших (более int16) дат. [\#4341](https://github.com/ClickHouse/ClickHouse/pull/4341) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка сегментации с помощью `uncompressed_cache=1` и исключение с неправильным несжатым размером. [\#4186](https://github.com/ClickHouse/ClickHouse/pull/4186) ([алесапин](https://github.com/alesapin)) -- Исправлено `ALL JOIN` с дубликатами в правой таблице. [\#4184](https://github.com/ClickHouse/ClickHouse/pull/4184) ([Артем Зуйков](https://github.com/4ertus2)) -- Исправлено неправильное поведение при выполнении `INSERT ... SELECT ... FROM file(...)` запрос и файл имеет `CSVWithNames` или `TSVWIthNames` формат и первая строка данных отсутствуют. [\#4297](https://github.com/ClickHouse/ClickHouse/pull/4297) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Фиксированное выполнение агрегатных функций с помощью `Array(LowCardinality)` аргументы. [\#4055](https://github.com/ClickHouse/ClickHouse/pull/4055) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Пакет Debian: исправьте/etc/clickhouse-server / preprocessed link в соответствии с конфигурацией. [\#4205](https://github.com/ClickHouse/ClickHouse/pull/4205) ([proller](https://github.com/proller)) -- Исправлен тест fuzz при неопределенном поведении дезинфицирующего средства: добавлена проверка типа параметра для `quantile*Weighted` семейство функций. [\#4145](https://github.com/ClickHouse/ClickHouse/pull/4145) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Сделай `START REPLICATED SENDS` команда начала репликации отправляет. [\#4229](https://github.com/ClickHouse/ClickHouse/pull/4229) ([nvartolomei](https://github.com/nvartolomei)) -- Исправлено `Not found column` для повторяющихся столбцов в разделе JOIN ON. [\#4279](https://github.com/ClickHouse/ClickHouse/pull/4279) ([Артем Зуйков](https://github.com/4ertus2)) -- Сейчас `/etc/ssl` используется в качестве каталога по умолчанию с SSL-сертификатами. [\#4167](https://github.com/ClickHouse/ClickHouse/pull/4167) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка при перезагрузке словаря, если словарь недоступен. [\#4188](https://github.com/ClickHouse/ClickHouse/pull/4188) ([proller](https://github.com/proller)) -- Исправлена ошибка с неправильным `Date` и `DateTime` сравнение. [\#4237](https://github.com/ClickHouse/ClickHouse/pull/4237) ([valexey](https://github.com/valexey)) -- Исправлен неверный результат, когда `Date` и `DateTime` аргументы используются в ветвях условного оператора (функции `if`). Добавлен общий случай для функции `if`. [\#4243](https://github.com/ClickHouse/ClickHouse/pull/4243) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -### ClickHouse релиз 19.1.6, 2019-01-24 {#clickhouse-release-19-1-6-2019-01-24} - -#### Новые средства {#new-features-7} - -- Пользовательские кодеки сжатия для каждого столбца для таблиц. [\#3899](https://github.com/ClickHouse/ClickHouse/pull/3899) [\#4111](https://github.com/ClickHouse/ClickHouse/pull/4111) ([алесапин](https://github.com/alesapin), [Зимний Чжан](https://github.com/zhang2014), [Анатолий](https://github.com/Sindbag)) -- Добавлен кодек сжатия `Delta`. [\#4052](https://github.com/ClickHouse/ClickHouse/pull/4052) ([алесапин](https://github.com/alesapin)) -- Разрешить `ALTER` кодеки сжатия. [\#4054](https://github.com/ClickHouse/ClickHouse/pull/4054) ([алесапин](https://github.com/alesapin)) -- Добавленные функции `left`, `right`, `trim`, `ltrim`, `rtrim`, `timestampadd`, `timestampsub` для совместимости со стандартом SQL. [\#3826](https://github.com/ClickHouse/ClickHouse/pull/3826) ([Иван Блинков](https://github.com/blinkov)) -- Поддержка записи в систему `HDFS` таблица или `hdfs` табличная функция. [\#4084](https://github.com/ClickHouse/ClickHouse/pull/4084) ([алесапин](https://github.com/alesapin)) -- Добавлены функции поиска нескольких постоянных строк из большого стога сена: `multiPosition`, `multiSearch` ,`firstMatch` также с помощью `-UTF8`, `-CaseInsensitive`, и `-CaseInsensitiveUTF8` варианты. [\#4053](https://github.com/ClickHouse/ClickHouse/pull/4053) ([Данила Кутенин](https://github.com/danlark1)) -- Обрезка неиспользуемых осколков, если `SELECT` фильтры запросов по ключу сегментирования (настройка `optimize_skip_unused_shards`). [\#3851](https://github.com/ClickHouse/ClickHouse/pull/3851) ([Глеб Кантеров](https://github.com/kanterov), [Иван](https://github.com/abyss7)) -- Позволять `Kafka` движок для игнорирования некоторого количества ошибок синтаксического анализа в каждом блоке. [\#4094](https://github.com/ClickHouse/ClickHouse/pull/4094) ([Иван](https://github.com/abyss7)) -- Добавлена поддержка для `CatBoost` мультиклассовые модели оценки. Функция `modelEvaluate` возвращает кортеж с необработанными прогнозами для каждого класса для многоклассовых моделей. `libcatboostmodel.so` должно быть построено с помощью [\#607](https://github.com/catboost/catboost/pull/607). [\#3959](https://github.com/ClickHouse/ClickHouse/pull/3959) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Добавленные функции `filesystemAvailable`, `filesystemFree`, `filesystemCapacity`. [\#4097](https://github.com/ClickHouse/ClickHouse/pull/4097) ([Борис Гранво](https://github.com/bgranvea)) -- Добавлены функции хэширования `xxHash64` и `xxHash32`. [\#3905](https://github.com/ClickHouse/ClickHouse/pull/3905) ([Филимонов](https://github.com/filimonov)) -- Добавлен `gccMurmurHash` функция хэширования (GCC flavoured Murmur hash), которая использует то же самое хэш-семя, что и [ССЗ](https://github.com/gcc-mirror/gcc/blob/41d6b10e96a1de98e90a7c0378437c3255814b16/libstdc%2B%2B-v3/include/bits/functional_hash.h#L191) [\#4000](https://github.com/ClickHouse/ClickHouse/pull/4000) ([сундили](https://github.com/sundy-li)) -- Добавлены функции хэширования `javaHash`, `hiveHash`. [\#3811](https://github.com/ClickHouse/ClickHouse/pull/3811) ([shangshujie365](https://github.com/shangshujie365)) -- Добавлена функция таблицы `remoteSecure`. Функция работает как `remote`, но использует безопасное соединение. [\#4088](https://github.com/ClickHouse/ClickHouse/pull/4088) ([proller](https://github.com/proller)) - -#### Экспериментальная возможность {#experimental-features-3} - -- Добавлена эмуляция нескольких соединений (`allow_experimental_multiple_joins_emulation` установочный). [\#3946](https://github.com/ClickHouse/ClickHouse/pull/3946) ([Артем Зуйков](https://github.com/4ertus2)) - -#### Устранение ошибок {#bug-fixes-21} - -- Сделай `compiled_expression_cache_size` установка ограничена по умолчанию для снижения потребления памяти. [\#4041](https://github.com/ClickHouse/ClickHouse/pull/4041) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка, которая привела к зависанию в потоках, выполняющих изменения реплицированных таблиц, и в потоке, обновляющем конфигурацию из ZooKeeper. [\#2947](https://github.com/ClickHouse/ClickHouse/issues/2947) [\#3891](https://github.com/ClickHouse/ClickHouse/issues/3891) [\#3934](https://github.com/ClickHouse/ClickHouse/pull/3934) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправлено состояние гонки при выполнении распределенной задачи ALTER. Состояние гонки привело к тому, что более чем одна реплика пыталась выполнить задачу, и все реплики, кроме одной, потерпели неудачу с ошибкой ZooKeeper. [\#3904](https://github.com/ClickHouse/ClickHouse/pull/3904) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправьте ошибку, когда `from_zk` элементы конфигурации не были обновлены после истечения времени ожидания запроса к ZooKeeper. [\#2947](https://github.com/ClickHouse/ClickHouse/issues/2947) [\#3947](https://github.com/ClickHouse/ClickHouse/pull/3947) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправлена ошибка с неправильным префиксом для масок подсети IPv4. [\#3945](https://github.com/ClickHouse/ClickHouse/pull/3945) ([алесапин](https://github.com/alesapin)) -- Исправлена ошибка (`std::terminate`) в редких случаях, когда новый поток не может быть создан из-за исчерпания ресурсов. [\#3956](https://github.com/ClickHouse/ClickHouse/pull/3956) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, когда в `remote` таблица выполнения функции, когда ошибались ограничений, используемых в `getStructureOfRemoteTable`. [\#4009](https://github.com/ClickHouse/ClickHouse/pull/4009) ([алесапин](https://github.com/alesapin)) -- Исправьте утечку сокетов netlink. Они были помещены в пул, где они никогда не удалялись, а новые сокеты создавались в начале нового потока, когда использовались все текущие сокеты. [\#4017](https://github.com/ClickHouse/ClickHouse/pull/4017) ([Алексей Зателепин](https://github.com/ztlpn)) -- Исправлена ошибка с закрытием `/proc/self/fd` каталог раньше, чем все fds были прочитаны из него `/proc` после раздвоения `odbc-bridge` подпроцесс. [\#4120](https://github.com/ClickHouse/ClickHouse/pull/4120) ([алесапин](https://github.com/alesapin)) -- Исправлено монотонное преобразование строки в UInt в случае использования строки в первичном ключе. [\#3870](https://github.com/ClickHouse/ClickHouse/pull/3870) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлена ошибка при вычислении монотонности функции преобразования целых чисел. [\#3921](https://github.com/ClickHouse/ClickHouse/pull/3921) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена обработка выхода онлайн / оффлайн в `arrayEnumerateUniq`, `arrayEnumerateDense` функции в случае некоторых недопустимых аргументов. [\#3909](https://github.com/ClickHouse/ClickHouse/pull/3909) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправьте UB в StorageMerge. [\#3910](https://github.com/ClickHouse/ClickHouse/pull/3910) ([Амос Птица](https://github.com/amosbird)) -- Исправлена обработка выхода онлайн / оффлайн в функции `addDays`, `subtractDays`. [\#3913](https://github.com/ClickHouse/ClickHouse/pull/3913) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка: функции `round`, `floor`, `trunc`, `ceil` может возвращать фиктивный результат при выполнении с целочисленным аргументом и большим отрицательным масштабом. [\#3914](https://github.com/ClickHouse/ClickHouse/pull/3914) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, вызванная ‘kill query sync’ что ведет к свалке ядра. [\#3916](https://github.com/ClickHouse/ClickHouse/pull/3916) ([мувулдипекер](https://github.com/fancyqlx)) -- Исправлена ошибка с длительной задержкой после пустой очереди репликации. [\#3928](https://github.com/ClickHouse/ClickHouse/pull/3928) [\#3932](https://github.com/ClickHouse/ClickHouse/pull/3932) ([алесапин](https://github.com/alesapin)) -- Исправлено чрезмерное использование памяти при вставке в таблицу с `LowCardinality` первичный ключ. [\#3955](https://github.com/ClickHouse/ClickHouse/pull/3955) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Исправлено `LowCardinality` сериализация для `Native` форматирование в случае пустых массивов. [\#3907](https://github.com/ClickHouse/ClickHouse/issues/3907) [\#4011](https://github.com/ClickHouse/ClickHouse/pull/4011) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Исправлен неверный результат при использовании числового столбца distinct by single LowCardinality. [\#3895](https://github.com/ClickHouse/ClickHouse/issues/3895) [\#4012](https://github.com/ClickHouse/ClickHouse/pull/4012) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Исправлена специализированная агрегация с ключом LowCardinality (в случае, когда `compile` настройка включена). [\#3886](https://github.com/ClickHouse/ClickHouse/pull/3886) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Исправлена переадресация пользователей и паролей для запросов реплицированных таблиц. [\#3957](https://github.com/ClickHouse/ClickHouse/pull/3957) ([алесапин](https://github.com/alesapin)) ([小路](https://github.com/nicelulu)) -- Исправлено очень редкое состояние гонки, которое может произойти при перечислении таблиц в базе данных словаря во время перезагрузки словарей. [\#3970](https://github.com/ClickHouse/ClickHouse/pull/3970) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлен неверный результат при использовании метода Rollup или CUBE. [\#3756](https://github.com/ClickHouse/ClickHouse/issues/3756) [\#3837](https://github.com/ClickHouse/ClickHouse/pull/3837) ([Сэм Чоу](https://github.com/reflection)) -- Исправлены псевдонимы столбцов для запроса с помощью `JOIN ON` синтаксис и распределенные таблицы. [\#3980](https://github.com/ClickHouse/ClickHouse/pull/3980) ([Зимний Чжан](https://github.com/zhang2014)) -- Исправлена ошибка во внутренней реализации `quantileTDigest` (найдено Артемом Вахрушевым). Эта ошибка никогда не происходит в ClickHouse и была актуальна только для тех, кто использует кодовую базу ClickHouse непосредственно в качестве библиотеки. [\#3935](https://github.com/ClickHouse/ClickHouse/pull/3935) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Улучшения {#improvements-6} - -- Поддержка `IF NOT EXISTS` в `ALTER TABLE ADD COLUMN` заявления вместе с `IF EXISTS` в `DROP/MODIFY/CLEAR/COMMENT COLUMN`. [\#3900](https://github.com/ClickHouse/ClickHouse/pull/3900) ([Борис Гранво](https://github.com/bgranvea)) -- Функция `parseDateTimeBestEffort`: поддержка форматов `DD.MM.YYYY`, `DD.MM.YY`, `DD-MM-YYYY`, `DD-Mon-YYYY`, `DD/Month/YYYY` и тому подобное. [\#3922](https://github.com/ClickHouse/ClickHouse/pull/3922) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- `CapnProtoInputStream` теперь поддерживайте зубчатые конструкции. [\#4063](https://github.com/ClickHouse/ClickHouse/pull/4063) ([Hultgren Один Ван Дер Хорст](https://github.com/Miniwoffer)) -- Улучшение удобства использования: добавлена проверка того, что серверный процесс запускается от владельца каталога данных. Не позволяют запускать сервер от root, если данные принадлежат к непривилегированным пользователем. [\#3785](https://github.com/ClickHouse/ClickHouse/pull/3785) ([Сергей-в-Гальцев](https://github.com/sergey-v-galtsev)) -- Улучшена логика проверки необходимых столбцов при анализе запросов с соединениями. [\#3930](https://github.com/ClickHouse/ClickHouse/pull/3930) ([Артем Зуйков](https://github.com/4ertus2)) -- Уменьшено количество подключений в случае большого количества распределенных таблиц на одном сервере. [\#3726](https://github.com/ClickHouse/ClickHouse/pull/3726) ([Зимний Чжан](https://github.com/zhang2014)) -- Поддерживаемые итоговые значения строка для `WITH TOTALS` запрос для драйвера ODBC. [\#3836](https://github.com/ClickHouse/ClickHouse/pull/3836) ([Максим Корицкий](https://github.com/nightweb)) -- Разрешено к использованию `Enum`s как целые числа внутри функции if. [\#3875](https://github.com/ClickHouse/ClickHouse/pull/3875) ([Иван](https://github.com/abyss7)) -- Добавлен `low_cardinality_allow_in_native_format` установка. Если он отключен, не используйте его `LowCadrinality` напечатать `Native` формат. [\#3879](https://github.com/ClickHouse/ClickHouse/pull/3879) ([Кочетовниколай](https://github.com/KochetovNicolai)) -- Удалил некоторые избыточные объекты из кэша скомпилированных выражений, чтобы снизить использование памяти. [\#4042](https://github.com/ClickHouse/ClickHouse/pull/4042) ([алесапин](https://github.com/alesapin)) -- Добавить проверить это `SET send_logs_level = 'value'` запрос принимает соответствующее значение. [\#3873](https://github.com/ClickHouse/ClickHouse/pull/3873) ([Сабянин Максим](https://github.com/s-mx)) -- Исправлена проверка типа данных в функциях преобразования типов. [\#3896](https://github.com/ClickHouse/ClickHouse/pull/3896) ([Зимний Чжан](https://github.com/zhang2014)) - -#### Улучшения в производительности {#performance-improvements-5} - -- Добавьте параметр MergeTree `use_minimalistic_part_header_in_zookeeper`. Если этот параметр включен, реплицированные таблицы будут хранить метаданные компактной детали в одном znode детали. Это может значительно уменьшить размер моментального снимка ZooKeeper (особенно если таблицы содержат много столбцов). Обратите внимание, что после включения этого параметра вы не сможете понизить рейтинг до версии, которая его не поддерживает. [\#3960](https://github.com/ClickHouse/ClickHouse/pull/3960) ([Алексей Зателепин](https://github.com/ztlpn)) -- Добавление реализации функций на основе DFA `sequenceMatch` и `sequenceCount` в случае, если шаблон не содержит времени. [\#4004](https://github.com/ClickHouse/ClickHouse/pull/4004) ([Léo Ercolanelli](https://github.com/ercolanelli-leo)) -- Повышение производительности при сериализации целых чисел. [\#3968](https://github.com/ClickHouse/ClickHouse/pull/3968) ([Амос Птица](https://github.com/amosbird)) -- Нулевое левое заполнение PODArray так, чтобы элемент -1 всегда был действителен и обнулялся. Он используется для безветвевого расчета смещений. [\#3920](https://github.com/ClickHouse/ClickHouse/pull/3920) ([Амос Птица](https://github.com/amosbird)) -- Возвратившегося `jemalloc` версии, которые приводят к снижению производительности. [\#4018](https://github.com/ClickHouse/ClickHouse/pull/4018) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) - -#### Назад Несовместимые Изменения {#backward-incompatible-changes-2} - -- Удалена недокументированная функция `ALTER MODIFY PRIMARY KEY` потому что он был вытеснен на второй план `ALTER MODIFY ORDER BY` команда. [\#3887](https://github.com/ClickHouse/ClickHouse/pull/3887) ([Алексей Зателепин](https://github.com/ztlpn)) -- Удаленная функция `shardByHash`. [\#3833](https://github.com/ClickHouse/ClickHouse/pull/3833) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Запретить использование скалярных подзапросов с результатом типа `AggregateFunction`. [\#3865](https://github.com/ClickHouse/ClickHouse/pull/3865) ([Иван](https://github.com/abyss7)) - -#### Улучшения Сборки / Тестирования / Упаковки {#buildtestingpackaging-improvements-6} - -- Добавлена поддержка PowerPC (`ppc64le`) строить. [\#4132](https://github.com/ClickHouse/ClickHouse/pull/4132) ([Данила Кутенин](https://github.com/danlark1)) -- Функциональные тесты с отслеживанием состояния выполняются на общедоступном наборе данных. [\#3969](https://github.com/ClickHouse/ClickHouse/pull/3969) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлена ошибка, когда сервер не может начать работу с `bash: /usr/bin/clickhouse-extract-from-config: Operation not permitted` сообщение внутри Docker или systemd-nspawn. [\#4136](https://github.com/ClickHouse/ClickHouse/pull/4136) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Обновленный `rdkafka` библиотека для v1.0.0-проект RC5. Используется cppkafka вместо raw c интерфейса. [\#4025](https://github.com/ClickHouse/ClickHouse/pull/4025) ([Иван](https://github.com/abyss7)) -- Обновленный `mariadb-client` библиотека. Исправлена одна из проблем, обнаруженных UBSan. [\#3924](https://github.com/ClickHouse/ClickHouse/pull/3924) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Некоторые исправления для утилиты для сборки. [\#3926](https://github.com/ClickHouse/ClickHouse/pull/3926) [\#3021](https://github.com/ClickHouse/ClickHouse/pull/3021) [\#3948](https://github.com/ClickHouse/ClickHouse/pull/3948) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлено в фиксации запусков тестов с утилиты для сборки. -- Добавлено в фиксации работает в PVS-Studio-статический анализатор. -- Исправлены ошибки, обнаруженные компанией PVS-Studio. [\#4013](https://github.com/ClickHouse/ClickHouse/pull/4013) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлены проблемы совместимости glibc. [\#4100](https://github.com/ClickHouse/ClickHouse/pull/4100) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Переместите изображения Docker в 18.10 и добавьте файл совместимости для glibc \>= 2.28 [\#3965](https://github.com/ClickHouse/ClickHouse/pull/3965) ([алесапин](https://github.com/alesapin)) -- Добавьте переменную env, если пользователь не хочет использовать каталоги chown в образе Server Docker. [\#3967](https://github.com/ClickHouse/ClickHouse/pull/3967) ([алесапин](https://github.com/alesapin)) -- Включено большинство предупреждений от `-Weverything` в лязг. Включенный `-Wpedantic`. [\#3986](https://github.com/ClickHouse/ClickHouse/pull/3986) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Добавлено еще несколько предупреждений, которые доступны только в clang 8. [\#3993](https://github.com/ClickHouse/ClickHouse/pull/3993) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Ссылка на `libLLVM` а не к отдельным библиотекам LLVM при использовании общего связывания. [\#3989](https://github.com/ClickHouse/ClickHouse/pull/3989) ([Оривей Деш](https://github.com/orivej)) -- Добавлены переменные дезинфицирующего средства для тестовых изображений. [\#4072](https://github.com/ClickHouse/ClickHouse/pull/4072) ([алесапин](https://github.com/alesapin)) -- `clickhouse-server` пакет debian будет рекомендовать `libcap2-bin` пакет для использования `setcap` инструмент для настройки возможностей. Это необязательно. [\#4093](https://github.com/ClickHouse/ClickHouse/pull/4093) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Улучшено время компиляции, исправлены ошибки. [\#3898](https://github.com/ClickHouse/ClickHouse/pull/3898) ([proller](https://github.com/proller)) -- Добавлены тесты производительности для хэш-функций. [\#3918](https://github.com/ClickHouse/ClickHouse/pull/3918) ([Филимонов](https://github.com/filimonov)) -- Фиксированные циклические библиотечные зависимости. [\#3958](https://github.com/ClickHouse/ClickHouse/pull/3958) ([proller](https://github.com/proller)) -- Улучшена компиляция с низким уровнем доступной памяти. [\#4030](https://github.com/ClickHouse/ClickHouse/pull/4030) ([proller](https://github.com/proller)) -- Добавлен тестовый сценарий для воспроизведения снижения производительности в `jemalloc`. [\#4036](https://github.com/ClickHouse/ClickHouse/pull/4036) ([Алексей-Миловидов](https://github.com/alexey-milovidov)) -- Исправлены опечатки в комментариях и строковых литералах под заголовком `dbms`. [\#4122](https://github.com/ClickHouse/ClickHouse/pull/4122) ([майха](https://github.com/maiha)) -- Исправлены опечатки в комментариях. [\#4089](https://github.com/ClickHouse/ClickHouse/pull/4089) ([Евгений Правда](https://github.com/kvinty)) - -## [Changelog для 2018](https://github.com/ClickHouse/ClickHouse/blob/master/docs/en/changelog/2018.md) {#changelog-for-2018} diff --git a/docs/ru/whats_new/changelog/2019.md b/docs/ru/whats_new/changelog/2019.md new file mode 120000 index 00000000000..905836eef7a --- /dev/null +++ b/docs/ru/whats_new/changelog/2019.md @@ -0,0 +1 @@ +en/whats_new/changelog/2019.md \ No newline at end of file diff --git a/docs/ru/whats_new/roadmap.md b/docs/ru/whats_new/roadmap.md deleted file mode 100644 index 3994ed4ac29..00000000000 --- a/docs/ru/whats_new/roadmap.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -machine_translated: true -machine_translated_rev: 1cd5f0028d917696daf71ac1c9ee849c99c1d5c8 ---- - -# Дорожная карта {#roadmap} - -## Q1 2020 {#q1-2020} - -- Управление доступом на основе ролей - -## Q2 2020 {#q2-2020} - -- Интеграция с внешними службами аутентификации -- Пулы ресурсов для более точного распределения емкости кластера между пользователями - -{## [Оригинальная статья](https://clickhouse.tech/docs/en/roadmap/) ##} diff --git a/docs/ru/whats_new/roadmap.md b/docs/ru/whats_new/roadmap.md new file mode 120000 index 00000000000..81184f9c26c --- /dev/null +++ b/docs/ru/whats_new/roadmap.md @@ -0,0 +1 @@ +en/whats_new/roadmap.md \ No newline at end of file From b00d9c78550840735a13aba1a47c50cd061c9f91 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 17:56:54 +0300 Subject: [PATCH 095/208] Fix bad translation, step 1: remove files #10191 --- docs/ru/development/architecture.md | 1 - docs/ru/development/build.md | 1 - docs/ru/development/build_cross_arm.md | 1 - docs/ru/development/build_cross_osx.md | 1 - docs/ru/development/build_osx.md | 1 - docs/ru/development/index.md | 1 - docs/ru/development/tests.md | 1 - docs/ru/engines/table_engines/special/generate.md | 1 - docs/ru/getting_started/tutorial.md | 1 - docs/ru/introduction/adopters.md | 1 - .../operations/optimizing_performance/sampling_query_profiler.md | 1 - docs/ru/operations/performance_test.md | 1 - docs/ru/operations/utilities/clickhouse-benchmark.md | 1 - docs/ru/whats_new/changelog/2017.md | 1 - docs/ru/whats_new/changelog/2018.md | 1 - docs/ru/whats_new/changelog/2019.md | 1 - docs/ru/whats_new/roadmap.md | 1 - 17 files changed, 17 deletions(-) delete mode 120000 docs/ru/development/architecture.md delete mode 120000 docs/ru/development/build.md delete mode 120000 docs/ru/development/build_cross_arm.md delete mode 120000 docs/ru/development/build_cross_osx.md delete mode 120000 docs/ru/development/build_osx.md delete mode 120000 docs/ru/development/index.md delete mode 120000 docs/ru/development/tests.md delete mode 120000 docs/ru/engines/table_engines/special/generate.md delete mode 120000 docs/ru/getting_started/tutorial.md delete mode 120000 docs/ru/introduction/adopters.md delete mode 120000 docs/ru/operations/optimizing_performance/sampling_query_profiler.md delete mode 120000 docs/ru/operations/performance_test.md delete mode 120000 docs/ru/operations/utilities/clickhouse-benchmark.md delete mode 120000 docs/ru/whats_new/changelog/2017.md delete mode 120000 docs/ru/whats_new/changelog/2018.md delete mode 120000 docs/ru/whats_new/changelog/2019.md delete mode 120000 docs/ru/whats_new/roadmap.md diff --git a/docs/ru/development/architecture.md b/docs/ru/development/architecture.md deleted file mode 120000 index 61968e46da2..00000000000 --- a/docs/ru/development/architecture.md +++ /dev/null @@ -1 +0,0 @@ -en/development/architecture.md \ No newline at end of file diff --git a/docs/ru/development/build.md b/docs/ru/development/build.md deleted file mode 120000 index 156d8382515..00000000000 --- a/docs/ru/development/build.md +++ /dev/null @@ -1 +0,0 @@ -en/development/build.md \ No newline at end of file diff --git a/docs/ru/development/build_cross_arm.md b/docs/ru/development/build_cross_arm.md deleted file mode 120000 index ea33bb61837..00000000000 --- a/docs/ru/development/build_cross_arm.md +++ /dev/null @@ -1 +0,0 @@ -en/development/build_cross_arm.md \ No newline at end of file diff --git a/docs/ru/development/build_cross_osx.md b/docs/ru/development/build_cross_osx.md deleted file mode 120000 index d4dc16f2fbc..00000000000 --- a/docs/ru/development/build_cross_osx.md +++ /dev/null @@ -1 +0,0 @@ -en/development/build_cross_osx.md \ No newline at end of file diff --git a/docs/ru/development/build_osx.md b/docs/ru/development/build_osx.md deleted file mode 120000 index 5c38a2b001a..00000000000 --- a/docs/ru/development/build_osx.md +++ /dev/null @@ -1 +0,0 @@ -en/development/build_osx.md \ No newline at end of file diff --git a/docs/ru/development/index.md b/docs/ru/development/index.md deleted file mode 120000 index 754385a9f4b..00000000000 --- a/docs/ru/development/index.md +++ /dev/null @@ -1 +0,0 @@ -en/development/index.md \ No newline at end of file diff --git a/docs/ru/development/tests.md b/docs/ru/development/tests.md deleted file mode 120000 index ce23c881f32..00000000000 --- a/docs/ru/development/tests.md +++ /dev/null @@ -1 +0,0 @@ -en/development/tests.md \ No newline at end of file diff --git a/docs/ru/engines/table_engines/special/generate.md b/docs/ru/engines/table_engines/special/generate.md deleted file mode 120000 index 631f9bbba66..00000000000 --- a/docs/ru/engines/table_engines/special/generate.md +++ /dev/null @@ -1 +0,0 @@ -en/engines/table_engines/special/generate.md \ No newline at end of file diff --git a/docs/ru/getting_started/tutorial.md b/docs/ru/getting_started/tutorial.md deleted file mode 120000 index 18b86bb2e9c..00000000000 --- a/docs/ru/getting_started/tutorial.md +++ /dev/null @@ -1 +0,0 @@ -en/getting_started/tutorial.md \ No newline at end of file diff --git a/docs/ru/introduction/adopters.md b/docs/ru/introduction/adopters.md deleted file mode 120000 index b9b77a27eb9..00000000000 --- a/docs/ru/introduction/adopters.md +++ /dev/null @@ -1 +0,0 @@ -en/introduction/adopters.md \ No newline at end of file diff --git a/docs/ru/operations/optimizing_performance/sampling_query_profiler.md b/docs/ru/operations/optimizing_performance/sampling_query_profiler.md deleted file mode 120000 index 565f39130fb..00000000000 --- a/docs/ru/operations/optimizing_performance/sampling_query_profiler.md +++ /dev/null @@ -1 +0,0 @@ -en/operations/optimizing_performance/sampling_query_profiler.md \ No newline at end of file diff --git a/docs/ru/operations/performance_test.md b/docs/ru/operations/performance_test.md deleted file mode 120000 index 3787adb92bd..00000000000 --- a/docs/ru/operations/performance_test.md +++ /dev/null @@ -1 +0,0 @@ -en/operations/performance_test.md \ No newline at end of file diff --git a/docs/ru/operations/utilities/clickhouse-benchmark.md b/docs/ru/operations/utilities/clickhouse-benchmark.md deleted file mode 120000 index fda8b1a50c7..00000000000 --- a/docs/ru/operations/utilities/clickhouse-benchmark.md +++ /dev/null @@ -1 +0,0 @@ -en/operations/utilities/clickhouse-benchmark.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2017.md b/docs/ru/whats_new/changelog/2017.md deleted file mode 120000 index f278c42f170..00000000000 --- a/docs/ru/whats_new/changelog/2017.md +++ /dev/null @@ -1 +0,0 @@ -en/whats_new/changelog/2017.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2018.md b/docs/ru/whats_new/changelog/2018.md deleted file mode 120000 index 675c07e8bbb..00000000000 --- a/docs/ru/whats_new/changelog/2018.md +++ /dev/null @@ -1 +0,0 @@ -en/whats_new/changelog/2018.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2019.md b/docs/ru/whats_new/changelog/2019.md deleted file mode 120000 index 905836eef7a..00000000000 --- a/docs/ru/whats_new/changelog/2019.md +++ /dev/null @@ -1 +0,0 @@ -en/whats_new/changelog/2019.md \ No newline at end of file diff --git a/docs/ru/whats_new/roadmap.md b/docs/ru/whats_new/roadmap.md deleted file mode 120000 index 81184f9c26c..00000000000 --- a/docs/ru/whats_new/roadmap.md +++ /dev/null @@ -1 +0,0 @@ -en/whats_new/roadmap.md \ No newline at end of file From ab8900ecff65150e803c50984cde78e634e095c7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 18:03:35 +0300 Subject: [PATCH 096/208] Fix bad translation, step 2: replace with symlinks #10191 --- docs/ru/development/architecture.md | 1 + docs/ru/development/build.md | 1 + docs/ru/development/build_cross_arm.md | 1 + docs/ru/development/build_cross_osx.md | 1 + docs/ru/development/build_osx.md | 1 + docs/ru/development/index.md | 1 + docs/ru/development/tests.md | 1 + docs/ru/engines/table_engines/special/generate.md | 1 + docs/ru/getting_started/tutorial.md | 1 + docs/ru/introduction/adopters.md | 1 + .../operations/optimizing_performance/sampling_query_profiler.md | 1 + docs/ru/operations/performance_test.md | 1 + docs/ru/operations/utilities/clickhouse-benchmark.md | 1 + docs/ru/whats_new/changelog/2017.md | 1 + docs/ru/whats_new/changelog/2018.md | 1 + docs/ru/whats_new/changelog/2019.md | 1 + docs/ru/whats_new/roadmap.md | 1 + 17 files changed, 17 insertions(+) create mode 120000 docs/ru/development/architecture.md create mode 120000 docs/ru/development/build.md create mode 120000 docs/ru/development/build_cross_arm.md create mode 120000 docs/ru/development/build_cross_osx.md create mode 120000 docs/ru/development/build_osx.md create mode 120000 docs/ru/development/index.md create mode 120000 docs/ru/development/tests.md create mode 120000 docs/ru/engines/table_engines/special/generate.md create mode 120000 docs/ru/getting_started/tutorial.md create mode 120000 docs/ru/introduction/adopters.md create mode 120000 docs/ru/operations/optimizing_performance/sampling_query_profiler.md create mode 120000 docs/ru/operations/performance_test.md create mode 120000 docs/ru/operations/utilities/clickhouse-benchmark.md create mode 120000 docs/ru/whats_new/changelog/2017.md create mode 120000 docs/ru/whats_new/changelog/2018.md create mode 120000 docs/ru/whats_new/changelog/2019.md create mode 120000 docs/ru/whats_new/roadmap.md diff --git a/docs/ru/development/architecture.md b/docs/ru/development/architecture.md new file mode 120000 index 00000000000..abda4dd48a8 --- /dev/null +++ b/docs/ru/development/architecture.md @@ -0,0 +1 @@ +../../en/development/architecture.md \ No newline at end of file diff --git a/docs/ru/development/build.md b/docs/ru/development/build.md new file mode 120000 index 00000000000..480dbc2e9f5 --- /dev/null +++ b/docs/ru/development/build.md @@ -0,0 +1 @@ +../../en/development/build.md \ No newline at end of file diff --git a/docs/ru/development/build_cross_arm.md b/docs/ru/development/build_cross_arm.md new file mode 120000 index 00000000000..983a9872dc1 --- /dev/null +++ b/docs/ru/development/build_cross_arm.md @@ -0,0 +1 @@ +../../en/development/build_cross_arm.md \ No newline at end of file diff --git a/docs/ru/development/build_cross_osx.md b/docs/ru/development/build_cross_osx.md new file mode 120000 index 00000000000..72e64e8631f --- /dev/null +++ b/docs/ru/development/build_cross_osx.md @@ -0,0 +1 @@ +../../en/development/build_cross_osx.md \ No newline at end of file diff --git a/docs/ru/development/build_osx.md b/docs/ru/development/build_osx.md new file mode 120000 index 00000000000..f9adaf24584 --- /dev/null +++ b/docs/ru/development/build_osx.md @@ -0,0 +1 @@ +../../en/development/build_osx.md \ No newline at end of file diff --git a/docs/ru/development/index.md b/docs/ru/development/index.md new file mode 120000 index 00000000000..1e2ad97dcc5 --- /dev/null +++ b/docs/ru/development/index.md @@ -0,0 +1 @@ +../../en/development/index.md \ No newline at end of file diff --git a/docs/ru/development/tests.md b/docs/ru/development/tests.md new file mode 120000 index 00000000000..c03d36c3916 --- /dev/null +++ b/docs/ru/development/tests.md @@ -0,0 +1 @@ +../../en/development/tests.md \ No newline at end of file diff --git a/docs/ru/engines/table_engines/special/generate.md b/docs/ru/engines/table_engines/special/generate.md new file mode 120000 index 00000000000..566dc4e5382 --- /dev/null +++ b/docs/ru/engines/table_engines/special/generate.md @@ -0,0 +1 @@ +../../../../en/engines/table_engines/special/generate.md \ No newline at end of file diff --git a/docs/ru/getting_started/tutorial.md b/docs/ru/getting_started/tutorial.md new file mode 120000 index 00000000000..8bc40816ab2 --- /dev/null +++ b/docs/ru/getting_started/tutorial.md @@ -0,0 +1 @@ +../../en/getting_started/tutorial.md \ No newline at end of file diff --git a/docs/ru/introduction/adopters.md b/docs/ru/introduction/adopters.md new file mode 120000 index 00000000000..659153d5f6c --- /dev/null +++ b/docs/ru/introduction/adopters.md @@ -0,0 +1 @@ +../../en/introduction/adopters.md \ No newline at end of file diff --git a/docs/ru/operations/optimizing_performance/sampling_query_profiler.md b/docs/ru/operations/optimizing_performance/sampling_query_profiler.md new file mode 120000 index 00000000000..9f3b57cd086 --- /dev/null +++ b/docs/ru/operations/optimizing_performance/sampling_query_profiler.md @@ -0,0 +1 @@ +../../../en/operations/optimizing_performance/sampling_query_profiler.md \ No newline at end of file diff --git a/docs/ru/operations/performance_test.md b/docs/ru/operations/performance_test.md new file mode 120000 index 00000000000..a74c126c63f --- /dev/null +++ b/docs/ru/operations/performance_test.md @@ -0,0 +1 @@ +../../en/operations/performance_test.md \ No newline at end of file diff --git a/docs/ru/operations/utilities/clickhouse-benchmark.md b/docs/ru/operations/utilities/clickhouse-benchmark.md new file mode 120000 index 00000000000..3695c9fbdd3 --- /dev/null +++ b/docs/ru/operations/utilities/clickhouse-benchmark.md @@ -0,0 +1 @@ +../../../en/operations/utilities/clickhouse-benchmark.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2017.md b/docs/ru/whats_new/changelog/2017.md new file mode 120000 index 00000000000..a098eddf1d8 --- /dev/null +++ b/docs/ru/whats_new/changelog/2017.md @@ -0,0 +1 @@ +../../../en/whats_new/changelog/2017.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2018.md b/docs/ru/whats_new/changelog/2018.md new file mode 120000 index 00000000000..124fb19e175 --- /dev/null +++ b/docs/ru/whats_new/changelog/2018.md @@ -0,0 +1 @@ +../../../en/whats_new/changelog/2018.md \ No newline at end of file diff --git a/docs/ru/whats_new/changelog/2019.md b/docs/ru/whats_new/changelog/2019.md new file mode 120000 index 00000000000..740d1edd238 --- /dev/null +++ b/docs/ru/whats_new/changelog/2019.md @@ -0,0 +1 @@ +../../../en/whats_new/changelog/2019.md \ No newline at end of file diff --git a/docs/ru/whats_new/roadmap.md b/docs/ru/whats_new/roadmap.md new file mode 120000 index 00000000000..5ef0ebdb1bb --- /dev/null +++ b/docs/ru/whats_new/roadmap.md @@ -0,0 +1 @@ +../../en/whats_new/roadmap.md \ No newline at end of file From 218b9b3c6ca0c67526449f12741f0db89117e2ec Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 18:40:11 +0300 Subject: [PATCH 097/208] Remove garbage --- docs/en/operations/performance_test.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/en/operations/performance_test.md b/docs/en/operations/performance_test.md index d955b50fa02..8c93f4e5f19 100644 --- a/docs/en/operations/performance_test.md +++ b/docs/en/operations/performance_test.md @@ -24,7 +24,7 @@ With this instruction you can run basic ClickHouse performance test on any serve # Then do: chmod a+x clickhouse -1. Download configs: +5. Download configs: @@ -34,7 +34,7 @@ With this instruction you can run basic ClickHouse performance test on any serve wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/programs/server/config.d/path.xml -O config.d/path.xml wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/programs/server/config.d/log_to_console.xml -O config.d/log_to_console.xml -1. Download benchmark files: +6. Download benchmark files: @@ -42,7 +42,7 @@ With this instruction you can run basic ClickHouse performance test on any serve chmod a+x benchmark-new.sh wget https://raw.githubusercontent.com/ClickHouse/ClickHouse/master/benchmark/clickhouse/queries.sql -1. Download test data according to the [Yandex.Metrica dataset](../getting_started/example_datasets/metrica.md) instruction (“hits” table containing 100 million rows). +7. Download test data according to the [Yandex.Metrica dataset](../getting_started/example_datasets/metrica.md) instruction (“hits” table containing 100 million rows). @@ -50,31 +50,31 @@ With this instruction you can run basic ClickHouse performance test on any serve tar xvf hits_100m_obfuscated_v1.tar.xz -C . mv hits_100m_obfuscated_v1/* . -1. Run the server: +8. Run the server: ./clickhouse server -1. Check the data: ssh to the server in another terminal +9. Check the data: ssh to the server in another terminal ./clickhouse client --query "SELECT count() FROM hits_100m_obfuscated" 100000000 -1. Edit the benchmark-new.sh, change “clickhouse-client” to “./clickhouse client” and add “–max\_memory\_usage 100000000000” parameter. +10. Edit the benchmark-new.sh, change “clickhouse-client” to “./clickhouse client” and add “–max\_memory\_usage 100000000000” parameter. mcedit benchmark-new.sh -1. Run the benchmark: +11. Run the benchmark: ./benchmark-new.sh hits_100m_obfuscated -1. Send the numbers and the info about your hardware configuration to clickhouse-feedback@yandex-team.com +12. Send the numbers and the info about your hardware configuration to clickhouse-feedback@yandex-team.com -All the results are published here: https://clickhouse.tech/benchmark\_hardware.html +All the results are published here: https://clickhouse.tech/benchmark_hardware.html From 59b5f88099dae933372b7eb439ecb66cd480bc9a Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 11 Apr 2020 18:43:13 +0300 Subject: [PATCH 098/208] Eliminate the rott. --- docs/en/operations/performance_test.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/operations/performance_test.md b/docs/en/operations/performance_test.md index 8c93f4e5f19..6b59ec6fedd 100644 --- a/docs/en/operations/performance_test.md +++ b/docs/en/operations/performance_test.md @@ -63,7 +63,7 @@ With this instruction you can run basic ClickHouse performance test on any serve ./clickhouse client --query "SELECT count() FROM hits_100m_obfuscated" 100000000 -10. Edit the benchmark-new.sh, change “clickhouse-client” to “./clickhouse client” and add “–max\_memory\_usage 100000000000” parameter. +10. Edit the benchmark-new.sh, change `clickhouse-client` to `./clickhouse client` and add `–-max_memory_usage 100000000000` parameter. From 1526722333d46e75aa3cc4f327bbb4b2b072744c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 18:54:16 +0300 Subject: [PATCH 099/208] Enforce that there is no machine translation to russian #10191 --- utils/check-style/check-style | 3 +++ 1 file changed, 3 insertions(+) diff --git a/utils/check-style/check-style b/utils/check-style/check-style index 08b0e81c123..2a2e9dab42d 100755 --- a/utils/check-style/check-style +++ b/utils/check-style/check-style @@ -56,3 +56,6 @@ find $ROOT_PATH/{src,base,programs,utils} -name '*.h' -or -name '*.cpp' | while # Broken XML files (requires libxml2-utils) find $ROOT_PATH/{src,base,programs,utils} -name '*.xml' | xargs xmllint --noout --nonet + +# Machine translation to Russian is strictly prohibited +find $ROOT_PATH/docs/ru -name '*.md' | xargs grep -l -F 'machine_translated: true' From 3d1e5b4bc998d9bf4a62097673368d2d93da9158 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 19:34:24 +0300 Subject: [PATCH 100/208] Changed Slack Link (tnx. lnuynxa) --- 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 47bcbd67218..e230cac8da9 100644 --- a/website/templates/index/community.html +++ b/website/templates/index/community.html @@ -69,7 +69,7 @@
-
Date: Sat, 11 Apr 2020 01:23:27 +0300 Subject: [PATCH 101/208] Fix using the current database for access checking when the database isn't specified. --- src/Access/ContextAccess.cpp | 33 ++++++++++++++++++++------------- src/Access/ContextAccess.h | 8 +++++++- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Access/ContextAccess.cpp b/src/Access/ContextAccess.cpp index cf788a0a63e..915593f58f0 100644 --- a/src/Access/ContextAccess.cpp +++ b/src/Access/ContextAccess.cpp @@ -196,7 +196,7 @@ bool ContextAccess::isClientHostAllowed() const template -bool ContextAccess::checkAccessImpl(Poco::Logger * log_, const AccessFlags & flags, const Args &... args) const +bool ContextAccess::calculateResultAccessAndCheck(Poco::Logger * log_, const AccessFlags & flags, const Args &... args) const { auto access = calculateResultAccess(grant_option); bool is_granted = access->isGranted(flags, args...); @@ -267,6 +267,22 @@ bool ContextAccess::checkAccessImpl(Poco::Logger * log_, const AccessFlags & fla } +template +bool ContextAccess::checkAccessImpl(Poco::Logger * log_, const AccessFlags & flags) const +{ + return calculateResultAccessAndCheck(log_, flags); +} + +template +bool ContextAccess::checkAccessImpl(Poco::Logger * log_, const AccessFlags & flags, const std::string_view & database, const Args &... args) const +{ + if (database.empty()) + return calculateResultAccessAndCheck(log_, flags, params.current_database, args...); + else + return calculateResultAccessAndCheck(log_, flags, database, args...); +} + + template bool ContextAccess::checkAccessImpl(Poco::Logger * log_, const AccessRightsElement & element) const { @@ -276,24 +292,15 @@ bool ContextAccess::checkAccessImpl(Poco::Logger * log_, const AccessRightsEleme } else if (element.any_table) { - if (element.database.empty()) - return checkAccessImpl(log_, element.access_flags, params.current_database); - else - return checkAccessImpl(log_, element.access_flags, element.database); + return checkAccessImpl(log_, element.access_flags, element.database); } else if (element.any_column) { - if (element.database.empty()) - return checkAccessImpl(log_, element.access_flags, params.current_database, element.table); - else - return checkAccessImpl(log_, element.access_flags, element.database, element.table); + return checkAccessImpl(log_, element.access_flags, element.database, element.table); } else { - if (element.database.empty()) - return checkAccessImpl(log_, element.access_flags, params.current_database, element.table, element.columns); - else - return checkAccessImpl(log_, element.access_flags, element.database, element.table, element.columns); + return checkAccessImpl(log_, element.access_flags, element.database, element.table, element.columns); } } diff --git a/src/Access/ContextAccess.h b/src/Access/ContextAccess.h index bee63103793..e0fbf58dbe8 100644 --- a/src/Access/ContextAccess.h +++ b/src/Access/ContextAccess.h @@ -130,8 +130,11 @@ private: void setRolesInfo(const std::shared_ptr & roles_info_) const; void setSettingsAndConstraints() const; + template + bool checkAccessImpl(Poco::Logger * log_, const AccessFlags & flags) const; + template - bool checkAccessImpl(Poco::Logger * log_, const AccessFlags & flags, const Args &... args) const; + bool checkAccessImpl(Poco::Logger * log_, const AccessFlags & flags, const std::string_view & database, const Args &... args) const; template bool checkAccessImpl(Poco::Logger * log_, const AccessRightsElement & element) const; @@ -139,6 +142,9 @@ private: template bool checkAccessImpl(Poco::Logger * log_, const AccessRightsElements & elements) const; + template + bool calculateResultAccessAndCheck(Poco::Logger * log_, const AccessFlags & flags, const Args &... args) const; + boost::shared_ptr calculateResultAccess(bool grant_option) const; boost::shared_ptr calculateResultAccess(bool grant_option, UInt64 readonly_, bool allow_ddl_, bool allow_introspection_) const; From 1e2206bdd9cf4c025853151a25a247a619a29562 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 11 Apr 2020 20:54:10 +0300 Subject: [PATCH 102/208] Update security_changelog.md --- docs/ru/whats_new/security_changelog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ru/whats_new/security_changelog.md b/docs/ru/whats_new/security_changelog.md index c8f66bf0475..9a2dab8ba14 100644 --- a/docs/ru/whats_new/security_changelog.md +++ b/docs/ru/whats_new/security_changelog.md @@ -1,3 +1,5 @@ +# Security Changelog + ## Исправлено в релизе 19.14.3.3, 2019-09-10 {#ispravleno-v-relize-19-14-3-3-2019-09-10} ### CVE-2019-15024 {#cve-2019-15024} From 53199ae546ae20381a0c0c1fea19534364745311 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 11 Apr 2020 22:51:04 +0300 Subject: [PATCH 103/208] Fix various small issues in interactive mode of clickhouse-client #10189 #5908 --- programs/client/Client.cpp | 45 +++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp index 9cd1332b513..fef89d9df35 100644 --- a/programs/client/Client.cpp +++ b/programs/client/Client.cpp @@ -82,16 +82,8 @@ #endif /// http://en.wikipedia.org/wiki/ANSI_escape_code - -/// Similar codes \e[s, \e[u don't work in VT100 and Mosh. -#define SAVE_CURSOR_POSITION "\033""7" -#define RESTORE_CURSOR_POSITION "\033""8" - #define CLEAR_TO_END_OF_LINE "\033[K" -/// This codes are possibly not supported everywhere. -#define DISABLE_LINE_WRAPPING "\033[?7l" -#define ENABLE_LINE_WRAPPING "\033[?7h" namespace DB { @@ -133,8 +125,6 @@ private: bool stdin_is_a_tty = false; /// stdin is a terminal. bool stdout_is_a_tty = false; /// stdout is a terminal. - uint16_t terminal_width = 0; /// Terminal width is needed to render progress bar. - std::unique_ptr connection; /// Connection to DB. String query_id; /// Current query_id. String query; /// Current query. @@ -1122,11 +1112,16 @@ private: /// to avoid losing sync. if (!cancelled) { - auto cancel_query = [&] { + auto cancel_query = [&] + { connection->sendCancel(); cancelled = true; if (is_interactive) + { + if (written_progress_chars) + clearProgress(); std::cout << "Cancelling query." << std::endl; + } /// Pressing Ctrl+C twice results in shut down. interrupt_listener.unblock(); @@ -1436,7 +1431,7 @@ private: { written_progress_chars = 0; if (!send_logs) - std::cerr << RESTORE_CURSOR_POSITION CLEAR_TO_END_OF_LINE; + std::cerr << "\r" CLEAR_TO_END_OF_LINE; } @@ -1461,20 +1456,14 @@ private: "\033[1m↗\033[0m", }; - if (!send_logs) - { - if (written_progress_chars) - message << RESTORE_CURSOR_POSITION CLEAR_TO_END_OF_LINE; - else - message << SAVE_CURSOR_POSITION; - } + auto indicator = indicators[increment % 8]; - message << DISABLE_LINE_WRAPPING; + if (!send_logs && written_progress_chars) + message << '\r'; size_t prefix_size = message.count(); - message << indicators[increment % 8] - << " Progress: "; + message << indicator << " Progress: "; message << formatReadableQuantity(progress.read_rows) << " rows, " @@ -1488,7 +1477,7 @@ private: else message << ". "; - written_progress_chars = message.count() - prefix_size - (increment % 8 == 7 ? 10 : 13); /// Don't count invisible output (escape sequences). + written_progress_chars = message.count() - prefix_size - (strlen(indicator) - 2); /// Don't count invisible output (escape sequences). /// If the approximate number of rows to process is known, we can display a progress bar and percentage. if (progress.total_rows_to_read > 0) @@ -1506,7 +1495,7 @@ private: if (show_progress_bar) { - ssize_t width_of_progress_bar = static_cast(terminal_width) - written_progress_chars - strlen(" 99%"); + ssize_t width_of_progress_bar = static_cast(getTerminalWidth()) - written_progress_chars - strlen(" 99%"); if (width_of_progress_bar > 0) { std::string bar = UnicodeBar::render(UnicodeBar::getWidth(progress.read_rows, 0, total_rows_corrected, width_of_progress_bar)); @@ -1521,7 +1510,8 @@ private: message << ' ' << (99 * progress.read_rows / total_rows_corrected) << '%'; } - message << ENABLE_LINE_WRAPPING; + message << CLEAR_TO_END_OF_LINE; + if (send_logs) message << '\n'; @@ -1589,7 +1579,11 @@ private: resetOutput(); if (is_interactive && !written_first_block) + { + if (written_progress_chars) + clearProgress(); std::cout << "Ok." << std::endl; + } } static void showClientVersion() @@ -1687,6 +1681,7 @@ public: stdin_is_a_tty = isatty(STDIN_FILENO); stdout_is_a_tty = isatty(STDOUT_FILENO); + uint64_t terminal_width = 0; if (stdin_is_a_tty) terminal_width = getTerminalWidth(); From e63fe6da8404f29a26da91fdc12753feaf31996e Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sat, 11 Apr 2020 23:07:11 +0300 Subject: [PATCH 104/208] Update msgpack.cmake --- cmake/find/msgpack.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/find/msgpack.cmake b/cmake/find/msgpack.cmake index 093555bebc0..46344fc162f 100644 --- a/cmake/find/msgpack.cmake +++ b/cmake/find/msgpack.cmake @@ -2,7 +2,7 @@ option (USE_INTERNAL_MSGPACK_LIBRARY "Set to FALSE to use system msgpack library if (USE_INTERNAL_MSGPACK_LIBRARY) if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/msgpack-c/include/msgpack.hpp") - message(WARNING "submodule contrib/msgpack-c is missing. To fix try run: \n git submodule update --init --recursive") + message(WARNING "Submodule contrib/msgpack-c is missing. To fix try run: \n git submodule update --init --recursive") set(USE_INTERNAL_MSGPACK_LIBRARY 0) set(MISSING_INTERNAL_MSGPACK_LIBRARY 1) endif() From 121bf7b8c2bbfc2f09379afa2232a8b1b8754844 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 00:37:19 +0300 Subject: [PATCH 105/208] Whitespace #9968 --- src/Storages/MergeTree/MergeTreeIndexFullText.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storages/MergeTree/MergeTreeIndexFullText.cpp b/src/Storages/MergeTree/MergeTreeIndexFullText.cpp index 93553e0619e..e42ac942362 100644 --- a/src/Storages/MergeTree/MergeTreeIndexFullText.cpp +++ b/src/Storages/MergeTree/MergeTreeIndexFullText.cpp @@ -627,7 +627,7 @@ bool SplitTokenExtractor::next(const char * data, size_t len, size_t * pos, size // With the help of https://www.strchr.com/strcmp_and_strlen_using_sse_4.2 const auto alnum_chars_ranges = _mm_set_epi8(0, 0, 0, 0, 0, 0, 0, 0, '\xFF', '\x80', 'z', 'a', 'Z', 'A', '9', '0'); - // Every bit represents if `haystack` character is in the ranges (1) or not(0) + // Every bit represents if `haystack` character is in the ranges (1) or not (0) const int result_bitmask = _mm_cvtsi128_si32(_mm_cmpestrm(alnum_chars_ranges, 8, haystack, haystack_length, _SIDD_CMP_RANGES)); #else // NOTE: -1 and +1 required since SSE2 has no `>=` and `<=` instructions on packed 8-bit integers (epi8). From 85448f4b133527e60af4ff56500f9d8fc1181dc7 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 12 Apr 2020 00:41:52 +0300 Subject: [PATCH 106/208] Add test from the #2610 (closes: #2610) --- .../01227_distributed_global_in_issue_2610.reference | 3 +++ .../0_stateless/01227_distributed_global_in_issue_2610.sql | 6 ++++++ 2 files changed, 9 insertions(+) create mode 100644 tests/queries/0_stateless/01227_distributed_global_in_issue_2610.reference create mode 100644 tests/queries/0_stateless/01227_distributed_global_in_issue_2610.sql diff --git a/tests/queries/0_stateless/01227_distributed_global_in_issue_2610.reference b/tests/queries/0_stateless/01227_distributed_global_in_issue_2610.reference new file mode 100644 index 00000000000..083edaac248 --- /dev/null +++ b/tests/queries/0_stateless/01227_distributed_global_in_issue_2610.reference @@ -0,0 +1,3 @@ +2 +2 +2 diff --git a/tests/queries/0_stateless/01227_distributed_global_in_issue_2610.sql b/tests/queries/0_stateless/01227_distributed_global_in_issue_2610.sql new file mode 100644 index 00000000000..a063e417e3a --- /dev/null +++ b/tests/queries/0_stateless/01227_distributed_global_in_issue_2610.sql @@ -0,0 +1,6 @@ +-- Test from the issue https://github.com/ClickHouse/ClickHouse/issues/2610 +drop table if exists data_01227; +create table data_01227 (key Int) Engine=MergeTree() order by key; +insert into data_01227 select * from numbers(10); +select * from remote('127.1', currentDatabase(), data_01227) prewhere key global in (select key from data_01227 prewhere key = 2); +select * from cluster('test_cluster_two_shards', currentDatabase(), data_01227) prewhere key global in (select key from data_01227 prewhere key = 2); From cf9f00644e2a4365eeb8386deb1d5ecc06aad5ff Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 01:13:06 +0300 Subject: [PATCH 107/208] Fix the issue with arrayJoin and PREWHERE optimization #10092 --- src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp b/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp index fa29494d1c9..749c0d64525 100644 --- a/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp +++ b/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp @@ -202,10 +202,10 @@ void MergeTreeWhereOptimizer::optimize(ASTSelectQuery & select) const prewhere_conditions.splice(prewhere_conditions.end(), where_conditions, cond_it); total_size_of_moved_conditions += cond_it->columns_size; - /// Move all other conditions that depend on the same set of columns. + /// Move all other viable conditions that depend on the same set of columns. for (auto jt = where_conditions.begin(); jt != where_conditions.end();) { - if (jt->columns_size == cond_it->columns_size && jt->identifiers == cond_it->identifiers) + if (jt->viable && jt->columns_size == cond_it->columns_size && jt->identifiers == cond_it->identifiers) prewhere_conditions.splice(prewhere_conditions.end(), where_conditions, jt++); else ++jt; From cf483b7ecc95d9f0cf1bccd11e53ceb0291c11af Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 01:14:55 +0300 Subject: [PATCH 108/208] Added a test --- .../1_stateful/00093_prewhere_array_join.reference | 0 tests/queries/1_stateful/00093_prewhere_array_join.sql | 9 +++++++++ 2 files changed, 9 insertions(+) create mode 100644 tests/queries/1_stateful/00093_prewhere_array_join.reference create mode 100644 tests/queries/1_stateful/00093_prewhere_array_join.sql diff --git a/tests/queries/1_stateful/00093_prewhere_array_join.reference b/tests/queries/1_stateful/00093_prewhere_array_join.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/1_stateful/00093_prewhere_array_join.sql b/tests/queries/1_stateful/00093_prewhere_array_join.sql new file mode 100644 index 00000000000..a1263144bb1 --- /dev/null +++ b/tests/queries/1_stateful/00093_prewhere_array_join.sql @@ -0,0 +1,9 @@ +SELECT arrayJoin([SearchEngineID]) AS search_engine, URL FROM test.hits WHERE SearchEngineID != 0 AND search_engine != 0 FORMAT Null; + +SELECT + arrayJoin([0]) AS browser, + arrayJoin([SearchEngineID]) AS search_engine, + URL +FROM test.hits +WHERE 1 AND (SearchEngineID != 0) AND (browser != 0) AND (search_engine != 0) +FORMAT Null; From a332d8b01ecdd52b06abdd9f630597870a28b9fb Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 12 Apr 2020 01:22:10 +0300 Subject: [PATCH 109/208] Cover GLOBAL IN for Distributed over Distributed --- tests/queries/0_stateless/01223_dist_on_dist.reference | 2 ++ tests/queries/0_stateless/01223_dist_on_dist.sql | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/tests/queries/0_stateless/01223_dist_on_dist.reference b/tests/queries/0_stateless/01223_dist_on_dist.reference index 4a5dd8f316c..aca2f070db4 100644 --- a/tests/queries/0_stateless/01223_dist_on_dist.reference +++ b/tests/queries/0_stateless/01223_dist_on_dist.reference @@ -99,3 +99,5 @@ merge() distributed_group_by_no_merge 33 33 +GLOBAL IN +1 diff --git a/tests/queries/0_stateless/01223_dist_on_dist.sql b/tests/queries/0_stateless/01223_dist_on_dist.sql index 1b9175f622e..65a240fd48b 100644 --- a/tests/queries/0_stateless/01223_dist_on_dist.sql +++ b/tests/queries/0_stateless/01223_dist_on_dist.sql @@ -82,6 +82,10 @@ select count() from merge_dist_01223; select 'distributed_group_by_no_merge'; select count() from merge_dist_01223 settings distributed_group_by_no_merge=1; +-- global in +select 'GLOBAL IN'; +select distinct * from dist_01223 where key global in (select toInt32(1)); + drop table merge_dist_01223; drop table dist_01223; drop table dist_layer_01223; From 29189d427604a49b3ce6eb1bd7210efb85f41d55 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 01:33:16 +0300 Subject: [PATCH 110/208] Also add stateless test to illustrate the issue more clear --- .../0_stateless/01115_prewhere_array_join.reference | 0 tests/queries/0_stateless/01115_prewhere_array_join.sql | 7 +++++++ 2 files changed, 7 insertions(+) create mode 100644 tests/queries/0_stateless/01115_prewhere_array_join.reference create mode 100644 tests/queries/0_stateless/01115_prewhere_array_join.sql diff --git a/tests/queries/0_stateless/01115_prewhere_array_join.reference b/tests/queries/0_stateless/01115_prewhere_array_join.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01115_prewhere_array_join.sql b/tests/queries/0_stateless/01115_prewhere_array_join.sql new file mode 100644 index 00000000000..e614bdf402b --- /dev/null +++ b/tests/queries/0_stateless/01115_prewhere_array_join.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS prewhere; + +CREATE TABLE prewhere (light UInt8, heavy String) ENGINE = MergeTree ORDER BY tuple(); +INSERT INTO prewhere SELECT 0, randomPrintableASCII(10000) FROM numbers(10000); +SELECT arrayJoin([light]) != 0 AS cond, length(heavy) FROM prewhere WHERE light != 0 AND cond != 0; + +DROP TABLE prewhere; From 2adeabd3c77b63b89b17ef00ec1e182c53aeb106 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 12 Apr 2020 01:58:45 +0300 Subject: [PATCH 111/208] Update Settings.h --- src/Core/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 342d9bef58e..8138af31d5f 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -406,7 +406,7 @@ struct Settings : public SettingsCollection M(SettingBool, validate_polygons, true, "Throw exception if polygon is invalid in function pointInPolygon (e.g. self-tangent, self-intersecting). If the setting is false, the function will accept invalid polygons but may silently return wrong result.", 0) \ M(SettingUInt64, max_parser_depth, 1000, "Maximum parser depth.", 0) \ M(SettingSeconds, temporary_live_view_timeout, DEFAULT_TEMPORARY_LIVE_VIEW_TIMEOUT_SEC, "Timeout after which temporary live view is deleted.", 0) \ - M(SettingBool, transform_null_in, false, "Enable null verification of the 'IN' operator.", 0) \ + M(SettingBool, transform_null_in, false, "If enabled, NULL values will be matched with 'IN' operator as if they are considered equal.", 0) \ M(SettingBool, allow_nondeterministic_mutations, false, "Allow non-deterministic functions in ALTER UPDATE/ALTER DELETE statements", 0) \ M(SettingSeconds, lock_acquire_timeout, DBMS_DEFAULT_LOCK_ACQUIRE_TIMEOUT_SEC, "How long locking request should wait before failing", 0) \ \ From 194dcc01fb96f5e808d7ba3b22523037b7d2e98a Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 12 Apr 2020 00:28:04 +0300 Subject: [PATCH 112/208] Allow literals for GLOBAL IN --- src/Interpreters/GlobalSubqueriesVisitor.h | 15 ++++++++++++++- .../01226_dist_on_dist_global_in.reference | 6 ++++++ .../01226_dist_on_dist_global_in.sql | 10 ++++++++++ .../01224_dist_on_dist_global_in.reference | 4 ---- .../bugs/01224_dist_on_dist_global_in.sql | 18 ------------------ 5 files changed, 30 insertions(+), 23 deletions(-) create mode 100644 tests/queries/0_stateless/01226_dist_on_dist_global_in.reference create mode 100644 tests/queries/0_stateless/01226_dist_on_dist_global_in.sql delete mode 100644 tests/queries/bugs/01224_dist_on_dist_global_in.reference delete mode 100644 tests/queries/bugs/01224_dist_on_dist_global_in.sql diff --git a/src/Interpreters/GlobalSubqueriesVisitor.h b/src/Interpreters/GlobalSubqueriesVisitor.h index e577219629c..78d98805814 100644 --- a/src/Interpreters/GlobalSubqueriesVisitor.h +++ b/src/Interpreters/GlobalSubqueriesVisitor.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -166,7 +167,19 @@ private: { if (func.name == "globalIn" || func.name == "globalNotIn") { - data.addExternalStorage(func.arguments->children[1]); + ASTPtr & ast = func.arguments->children[1]; + + /// Literal can use regular IN + if (ast->as()) + { + if (func.name == "globalIn") + func.name = "in"; + else + func.name = "notIn"; + return; + } + + data.addExternalStorage(ast); data.has_global_subqueries = true; } } diff --git a/tests/queries/0_stateless/01226_dist_on_dist_global_in.reference b/tests/queries/0_stateless/01226_dist_on_dist_global_in.reference new file mode 100644 index 00000000000..3d8d7fb770d --- /dev/null +++ b/tests/queries/0_stateless/01226_dist_on_dist_global_in.reference @@ -0,0 +1,6 @@ +GLOBAL IN +0 +0 +0 +0 +GLOBAL NOT IN diff --git a/tests/queries/0_stateless/01226_dist_on_dist_global_in.sql b/tests/queries/0_stateless/01226_dist_on_dist_global_in.sql new file mode 100644 index 00000000000..588ea9c1048 --- /dev/null +++ b/tests/queries/0_stateless/01226_dist_on_dist_global_in.sql @@ -0,0 +1,10 @@ +SELECT 'GLOBAL IN'; +select * from remote('localhost', system.one) where dummy global in (0); +select * from remote('localhost', system.one) where toUInt64(dummy) global in numbers(1); +select * from remote('localhost', system.one) where dummy global in system.one; +select * from remote('localhost', system.one) where dummy global in (select 0); +SELECT 'GLOBAL NOT IN'; +select * from remote('localhost', system.one) where dummy global not in (0); +select * from remote('localhost', system.one) where toUInt64(dummy) global not in numbers(1); +select * from remote('localhost', system.one) where dummy global not in system.one; +select * from remote('localhost', system.one) where dummy global not in (select 0); diff --git a/tests/queries/bugs/01224_dist_on_dist_global_in.reference b/tests/queries/bugs/01224_dist_on_dist_global_in.reference deleted file mode 100644 index 7f75aa873cb..00000000000 --- a/tests/queries/bugs/01224_dist_on_dist_global_in.reference +++ /dev/null @@ -1,4 +0,0 @@ -GLOBAL IN distributed_group_by_no_merge -1 -GLOBAL IN -1 diff --git a/tests/queries/bugs/01224_dist_on_dist_global_in.sql b/tests/queries/bugs/01224_dist_on_dist_global_in.sql deleted file mode 100644 index e363fef2d2b..00000000000 --- a/tests/queries/bugs/01224_dist_on_dist_global_in.sql +++ /dev/null @@ -1,18 +0,0 @@ -create table if not exists data_01224 (key Int) Engine=Memory(); -create table if not exists dist_layer_01224 as data_01224 Engine=Distributed(test_cluster_two_shards, currentDatabase(), data_01224); -create table if not exists dist_01224 as data_01224 Engine=Distributed(test_cluster_two_shards, currentDatabase(), dist_layer_01224); - -select * from dist_01224; -insert into data_01224 select * from numbers(3); - --- "Table expression is undefined, Method: ExpressionAnalyzer::interpretSubquery" -select 'GLOBAL IN distributed_group_by_no_merge'; -select distinct * from dist_01224 where key global in (1) settings distributed_group_by_no_merge=1; - --- requires #9923 -select 'GLOBAL IN'; -select distinct * from dist_01224 where key global in (1); - -drop table dist_01224; -drop table dist_layer_01224; -drop table data_01224; From c5c1a8def75e1b47fd8e77553fdbdf980631ffc9 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 03:03:05 +0300 Subject: [PATCH 113/208] Added a test from Andrey #2641 --- .../01116_asof_join_dolbyzerr.reference | 3 +++ .../0_stateless/01116_asof_join_dolbyzerr.sql | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/queries/0_stateless/01116_asof_join_dolbyzerr.reference create mode 100644 tests/queries/0_stateless/01116_asof_join_dolbyzerr.sql diff --git a/tests/queries/0_stateless/01116_asof_join_dolbyzerr.reference b/tests/queries/0_stateless/01116_asof_join_dolbyzerr.reference new file mode 100644 index 00000000000..1055a67ea5b --- /dev/null +++ b/tests/queries/0_stateless/01116_asof_join_dolbyzerr.reference @@ -0,0 +1,3 @@ +v1 o1 ['s2','s1'] +v1 o2 ['s4'] +v2 o3 ['s5','s3'] diff --git a/tests/queries/0_stateless/01116_asof_join_dolbyzerr.sql b/tests/queries/0_stateless/01116_asof_join_dolbyzerr.sql new file mode 100644 index 00000000000..8a94b6ddd24 --- /dev/null +++ b/tests/queries/0_stateless/01116_asof_join_dolbyzerr.sql @@ -0,0 +1,18 @@ +CREATE TEMPORARY TABLE sessions (date DateTime, visitorId String, sessionId String); +CREATE TEMPORARY TABLE orders (date DateTime, visitorId String, orderId String); + +INSERT INTO sessions VALUES ('2018-01-01 00:00:00', 'v1', 's1'), ('2018-01-02 00:00:00', 'v1', 's2'), ('2018-01-03 00:00:00', 'v2', 's3'), ('2018-01-04 00:00:00', 'v1', 's4'), ('2018-01-05 00:00:00', 'v2', 's5'), ('2018-01-06 00:00:00', 'v3', 's6'); +INSERT INTO orders VALUES ('2018-01-03 00:00:00', 'v1', 'o1'), ('2018-01-05 00:00:00', 'v1', 'o2'), ('2018-01-06 00:00:00', 'v2', 'o3'); + +SELECT + visitorId, + orderId, + groupUniqArray(sessionId) +FROM sessions +ASOF INNER JOIN orders ON (sessions.visitorId = orders.visitorId) AND (sessions.date <= orders.date) +GROUP BY + visitorId, + orderId +ORDER BY + visitorId ASC, + orderId ASC; From dec3e0f9861f7876ee8a9dd3a97b9f88240cd284 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 03:38:25 +0300 Subject: [PATCH 114/208] Make least and greatest functions case insensitive for compatibility with MySQL --- src/Functions/greatest.cpp | 2 +- src/Functions/least.cpp | 2 +- tests/queries/0_stateless/01117_greatest_least_case.reference | 2 ++ tests/queries/0_stateless/01117_greatest_least_case.sql | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 tests/queries/0_stateless/01117_greatest_least_case.reference create mode 100644 tests/queries/0_stateless/01117_greatest_least_case.sql diff --git a/src/Functions/greatest.cpp b/src/Functions/greatest.cpp index 6eb123708a4..9abf85e751b 100644 --- a/src/Functions/greatest.cpp +++ b/src/Functions/greatest.cpp @@ -57,7 +57,7 @@ using FunctionGreatest = FunctionBinaryArithmetic; void registerFunctionGreatest(FunctionFactory & factory) { - factory.registerFunction(); + factory.registerFunction(FunctionFactory::CaseInsensitive); } } diff --git a/src/Functions/least.cpp b/src/Functions/least.cpp index 47af759c956..f2e7c1f15d2 100644 --- a/src/Functions/least.cpp +++ b/src/Functions/least.cpp @@ -57,7 +57,7 @@ using FunctionLeast = FunctionBinaryArithmetic; void registerFunctionLeast(FunctionFactory & factory) { - factory.registerFunction(); + factory.registerFunction(FunctionFactory::CaseInsensitive); } } diff --git a/tests/queries/0_stateless/01117_greatest_least_case.reference b/tests/queries/0_stateless/01117_greatest_least_case.reference new file mode 100644 index 00000000000..4bbcfcf5682 --- /dev/null +++ b/tests/queries/0_stateless/01117_greatest_least_case.reference @@ -0,0 +1,2 @@ +2 +-1 diff --git a/tests/queries/0_stateless/01117_greatest_least_case.sql b/tests/queries/0_stateless/01117_greatest_least_case.sql new file mode 100644 index 00000000000..21bfd240f5a --- /dev/null +++ b/tests/queries/0_stateless/01117_greatest_least_case.sql @@ -0,0 +1,2 @@ +SELECT GREATEST(1, 2); +SELECT LEAST(1, -1); From 754967bde6178ef7fd358b0fd7c37b92ce264b94 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 04:24:00 +0300 Subject: [PATCH 115/208] Add function "isConstant" --- src/Functions/isConstant.cpp | 52 +++++++++++++++++++ .../registerFunctionsMiscellaneous.cpp | 2 + .../0_stateless/01118_is_constant.reference | 9 ++++ .../queries/0_stateless/01118_is_constant.sql | 10 ++++ 4 files changed, 73 insertions(+) create mode 100644 src/Functions/isConstant.cpp create mode 100644 tests/queries/0_stateless/01118_is_constant.reference create mode 100644 tests/queries/0_stateless/01118_is_constant.sql diff --git a/src/Functions/isConstant.cpp b/src/Functions/isConstant.cpp new file mode 100644 index 00000000000..705b4eaac78 --- /dev/null +++ b/src/Functions/isConstant.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include + + +namespace DB +{ + +/// Returns 1 if and only if the argument is constant expression. +/// This function is exists for development, debugging and demonstration purposes. +class FunctionIsConstant : public IFunction +{ +public: + static constexpr auto name = "isConstant"; + static FunctionPtr create(const Context &) + { + return std::make_shared(); + } + + String getName() const override + { + return name; + } + + bool useDefaultImplementationForNulls() const override { return false; } + + size_t getNumberOfArguments() const override + { + return 1; + } + + DataTypePtr getReturnTypeImpl(const DataTypes & /*arguments*/) const override + { + return std::make_shared(); + } + + void executeImpl(Block & block, const ColumnNumbers & arguments, size_t result, size_t input_rows_count) override + { + const auto & elem = block.getByPosition(arguments[0]); + block.getByPosition(result).column = ColumnUInt8::create(input_rows_count, isColumnConst(*elem.column)); + } +}; + + +void registerFunctionIsConstant(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} + diff --git a/src/Functions/registerFunctionsMiscellaneous.cpp b/src/Functions/registerFunctionsMiscellaneous.cpp index 44e26542c7d..30cab4cc53a 100644 --- a/src/Functions/registerFunctionsMiscellaneous.cpp +++ b/src/Functions/registerFunctionsMiscellaneous.cpp @@ -56,6 +56,7 @@ void registerFunctionBasename(FunctionFactory &); void registerFunctionTransform(FunctionFactory &); void registerFunctionGetMacro(FunctionFactory &); void registerFunctionGetScalar(FunctionFactory &); +void registerFunctionIsConstant(FunctionFactory &); #if USE_ICU void registerFunctionConvertCharset(FunctionFactory &); @@ -114,6 +115,7 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory) registerFunctionTransform(factory); registerFunctionGetMacro(factory); registerFunctionGetScalar(factory); + registerFunctionIsConstant(factory); #if USE_ICU registerFunctionConvertCharset(factory); diff --git a/tests/queries/0_stateless/01118_is_constant.reference b/tests/queries/0_stateless/01118_is_constant.reference new file mode 100644 index 00000000000..aba2b912a08 --- /dev/null +++ b/tests/queries/0_stateless/01118_is_constant.reference @@ -0,0 +1,9 @@ +1 +1 +0 +1 +1 +--- +0 +0 +--- diff --git a/tests/queries/0_stateless/01118_is_constant.sql b/tests/queries/0_stateless/01118_is_constant.sql new file mode 100644 index 00000000000..5cbff986dd2 --- /dev/null +++ b/tests/queries/0_stateless/01118_is_constant.sql @@ -0,0 +1,10 @@ +select isConstant(1); +select isConstant([1]); +select isConstant(arrayJoin([1])); +SELECT isConstant((SELECT 1)); +SELECT isConstant(x) FROM (SELECT 1 x); +SELECT '---'; +SELECT isConstant(x) FROM (SELECT 1 x UNION ALL SELECT 2); +SELECT '---'; +select isConstant(); -- { serverError 42 } +select isConstant(1, 2); -- { serverError 42 } From 716ddc4580381ca173824f3d5733c898f65b1777 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 12 Apr 2020 04:26:11 +0300 Subject: [PATCH 116/208] Update isConstant.cpp --- src/Functions/isConstant.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Functions/isConstant.cpp b/src/Functions/isConstant.cpp index 705b4eaac78..5416fbd2d3e 100644 --- a/src/Functions/isConstant.cpp +++ b/src/Functions/isConstant.cpp @@ -8,7 +8,7 @@ namespace DB { /// Returns 1 if and only if the argument is constant expression. -/// This function is exists for development, debugging and demonstration purposes. +/// This function exists for development, debugging and demonstration purposes. class FunctionIsConstant : public IFunction { public: From 01bc88a85113cf7b47a2026a06a090ec86c4e230 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 05:05:30 +0300 Subject: [PATCH 117/208] Fix wrong whitespaces in debug output --- src/Interpreters/ColumnNamesContext.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Interpreters/ColumnNamesContext.cpp b/src/Interpreters/ColumnNamesContext.cpp index 4d23c6f0e8b..380d5f9ebc3 100644 --- a/src/Interpreters/ColumnNamesContext.cpp +++ b/src/Interpreters/ColumnNamesContext.cpp @@ -87,6 +87,7 @@ std::ostream & operator << (std::ostream & os, const ColumnNamesContext & cols) os << "'" << pr.first << "'"; for (auto & alias : pr.second.aliases) os << "/'" << alias << "'"; + os << ", "; } os << " source_tables: "; for (const auto & x : cols.tables) @@ -94,24 +95,24 @@ std::ostream & operator << (std::ostream & os, const ColumnNamesContext & cols) auto alias = x.alias(); auto name = x.name(); if (alias && name) - os << "'" << *alias << "'/'" << *name << "' "; + os << "'" << *alias << "'/'" << *name << "', "; else if (alias) - os << "'" << *alias << "' "; + os << "'" << *alias << "', "; else if (name) - os << "'" << *name << "' "; + os << "'" << *name << "', "; } os << "table_aliases: "; for (const auto & x : cols.table_aliases) - os << "'" << x << "' "; + os << "'" << x << "', "; os << "complex_aliases: "; for (const auto & x : cols.complex_aliases) - os << "'" << x << "' "; + os << "'" << x << "', "; os << "masked_columns: "; for (const auto & x : cols.masked_columns) - os << "'" << x << "' "; + os << "'" << x << "', "; os << "array_join_columns: "; for (const auto & x : cols.array_join_columns) - os << "'" << x << "' "; + os << "'" << x << "', "; return os; } From f8e1f1b69bd565111a7c8b748ef6d96380485ad7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 05:06:58 +0300 Subject: [PATCH 118/208] Fix wrong whitespaces in debug output --- src/Interpreters/ColumnNamesContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Interpreters/ColumnNamesContext.cpp b/src/Interpreters/ColumnNamesContext.cpp index 380d5f9ebc3..c8fde183d96 100644 --- a/src/Interpreters/ColumnNamesContext.cpp +++ b/src/Interpreters/ColumnNamesContext.cpp @@ -89,7 +89,7 @@ std::ostream & operator << (std::ostream & os, const ColumnNamesContext & cols) os << "/'" << alias << "'"; os << ", "; } - os << " source_tables: "; + os << "source_tables: "; for (const auto & x : cols.tables) { auto alias = x.alias(); From d43903211aad13b46ca2cf45b036b30a30fb5983 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 05:51:56 +0300 Subject: [PATCH 119/208] Better exception message #9810 --- src/Functions/FunctionsConversion.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index d201b967fb1..b493aef4cac 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -2394,10 +2394,17 @@ protected: DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments) const override { - const auto type_col = checkAndGetColumnConst(arguments.back().column.get()); + const auto & column = arguments.back().column; + if (!column) + throw Exception("Second argument to " + getName() + " must be a constant string describing type." + " Instead there is non-constant column of type " + arguments.back().type->getName(), + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + + const auto type_col = checkAndGetColumnConst(column.get()); if (!type_col) - throw Exception("Second argument to " + getName() + " must be a constant string describing type", - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + throw Exception("Second argument to " + getName() + " must be a constant string describing type." + " Instead there is a column with the following structure: " + column->dumpStructure(), + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); return DataTypeFactory::instance().get(type_col->getValue()); } From d6544159ba78930b268229a810a44581c3e6b035 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 12 Apr 2020 06:18:21 +0300 Subject: [PATCH 120/208] Update HashJoin.cpp --- src/Interpreters/HashJoin.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index d8c0d239c96..16d4932bb14 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -1162,15 +1162,15 @@ DataTypePtr HashJoin::joinGetReturnType(const String & column_name, bool or_null if (!sample_block_with_columns_to_add.has(column_name)) throw Exception("StorageJoin doesn't contain column " + column_name, ErrorCodes::LOGICAL_ERROR); - auto ctn = sample_block_with_columns_to_add.getByName(column_name); + auto elem = sample_block_with_columns_to_add.getByName(column_name); if (or_null) { if (!ctn.type->canBeInsideNullable()) - throw Exception("Type " + ctn.type->getName() + "cannot be inside Nullable", ErrorCodes::LOGICAL_ERROR); + throw Exception("Type " + elem.type->getName() + " cannot be inside Nullable", ErrorCodes::LOGICAL_ERROR); else - ctn.type = makeNullable(ctn.type); + elem.type = makeNullable(elem.type); } - return ctn.type; + return elem.type; } From a2418f94df9c58e8eba9704215d1f04e299b919f Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 12 Apr 2020 06:19:13 +0300 Subject: [PATCH 121/208] Update HashJoin.cpp --- src/Interpreters/HashJoin.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index 16d4932bb14..5845fd131d2 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -1165,7 +1165,7 @@ DataTypePtr HashJoin::joinGetReturnType(const String & column_name, bool or_null auto elem = sample_block_with_columns_to_add.getByName(column_name); if (or_null) { - if (!ctn.type->canBeInsideNullable()) + if (!elem.type->canBeInsideNullable()) throw Exception("Type " + elem.type->getName() + " cannot be inside Nullable", ErrorCodes::LOGICAL_ERROR); else elem.type = makeNullable(elem.type); @@ -1194,15 +1194,15 @@ void HashJoin::joinGet(Block & block, const String & column_name, bool or_null) checkTypeOfKey(block, right_table_keys); - auto ctn = sample_block_with_columns_to_add.getByName(column_name); + auto elem = sample_block_with_columns_to_add.getByName(column_name); if (or_null) - ctn.type = makeNullable(ctn.type); - ctn.column = ctn.type->createColumn(); + elem.type = makeNullable(elem.type); + elem.column = elem.type->createColumn(); if ((strictness == ASTTableJoin::Strictness::Any || strictness == ASTTableJoin::Strictness::RightAny) && kind == ASTTableJoin::Kind::Left) { - joinGetImpl(block, {ctn}, std::get(data->maps)); + joinGetImpl(block, {elem}, std::get(data->maps)); } else throw Exception("joinGet only supports StorageJoin of type Left Any", ErrorCodes::LOGICAL_ERROR); From ca5172cc63fd8ec0c6e28e5c511f2bba86991b3b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 06:25:47 +0300 Subject: [PATCH 122/208] Merging #10094 --- src/Interpreters/HashJoin.cpp | 7 +------ .../0_stateless/01240_join_get_or_null.reference | 1 + tests/queries/0_stateless/01240_join_get_or_null.sql | 10 ++++++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Interpreters/HashJoin.cpp b/src/Interpreters/HashJoin.cpp index 5845fd131d2..b8da03acb8b 100644 --- a/src/Interpreters/HashJoin.cpp +++ b/src/Interpreters/HashJoin.cpp @@ -1164,12 +1164,7 @@ DataTypePtr HashJoin::joinGetReturnType(const String & column_name, bool or_null throw Exception("StorageJoin doesn't contain column " + column_name, ErrorCodes::LOGICAL_ERROR); auto elem = sample_block_with_columns_to_add.getByName(column_name); if (or_null) - { - if (!elem.type->canBeInsideNullable()) - throw Exception("Type " + elem.type->getName() + " cannot be inside Nullable", ErrorCodes::LOGICAL_ERROR); - else - elem.type = makeNullable(elem.type); - } + elem.type = makeNullable(elem.type); return elem.type; } diff --git a/tests/queries/0_stateless/01240_join_get_or_null.reference b/tests/queries/0_stateless/01240_join_get_or_null.reference index dec7d2fabd2..96e34d5a44c 100644 --- a/tests/queries/0_stateless/01240_join_get_or_null.reference +++ b/tests/queries/0_stateless/01240_join_get_or_null.reference @@ -1 +1,2 @@ \N +\N diff --git a/tests/queries/0_stateless/01240_join_get_or_null.sql b/tests/queries/0_stateless/01240_join_get_or_null.sql index d1b9a07540a..48fd8228b55 100644 --- a/tests/queries/0_stateless/01240_join_get_or_null.sql +++ b/tests/queries/0_stateless/01240_join_get_or_null.sql @@ -1,7 +1,13 @@ DROP TABLE IF EXISTS join_test; CREATE TABLE join_test (id UInt16, num UInt16) engine = Join(ANY, LEFT, id); - SELECT joinGetOrNull('join_test', 'num', 500); - +DROP TABLE join_test; + +CREATE TABLE join_test (id UInt16, num Nullable(UInt16)) engine = Join(ANY, LEFT, id); +SELECT joinGetOrNull('join_test', 'num', 500); +DROP TABLE join_test; + +CREATE TABLE join_test (id UInt16, num Array(UInt16)) engine = Join(ANY, LEFT, id); +SELECT joinGetOrNull('join_test', 'num', 500); -- { serverError 43 } DROP TABLE join_test; From e7f399f6527841b4352dd1e480bac3a15587fef6 Mon Sep 17 00:00:00 2001 From: BohuTANG Date: Sun, 12 Apr 2020 13:37:39 +0800 Subject: [PATCH 123/208] MySQLHandler: max_allowed_packet returned by default when server setup with select variables --- programs/server/MySQLHandler.cpp | 6 ++++-- .../test_mysql_protocol/clients/java/0.reference | 4 ++-- .../integration/test_mysql_protocol/clients/java/Test.java | 7 ++++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/programs/server/MySQLHandler.cpp b/programs/server/MySQLHandler.cpp index b72aa8104d3..bfab19061ce 100644 --- a/programs/server/MySQLHandler.cpp +++ b/programs/server/MySQLHandler.cpp @@ -284,15 +284,17 @@ void MySQLHandler::comQuery(ReadBuffer & payload) } else { - String replacement_query = "select ''"; + String replacement_query = "SELECT ''"; bool should_replace = false; bool with_output = false; // Translate query from MySQL to ClickHouse. - // This is a temporary workaround until ClickHouse supports the syntax "@@var_name". + // Required parameters when setup: + // * max_allowed_packet, default 64MB, https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_max_allowed_packet if (isFederatedServerSetupSelectVarCommand(query)) { should_replace = true; + replacement_query = "SELECT 67108864 AS max_allowed_packet"; } // This is a workaround in order to support adding ClickHouse to MySQL using federated server. diff --git a/tests/integration/test_mysql_protocol/clients/java/0.reference b/tests/integration/test_mysql_protocol/clients/java/0.reference index bcf9e3dde94..3e3e20d1ebb 100644 --- a/tests/integration/test_mysql_protocol/clients/java/0.reference +++ b/tests/integration/test_mysql_protocol/clients/java/0.reference @@ -1,5 +1,5 @@ -33jdbc -44ck +33jdbcnull +44cknull 0 1 2 diff --git a/tests/integration/test_mysql_protocol/clients/java/Test.java b/tests/integration/test_mysql_protocol/clients/java/Test.java index 50ce824f67c..89659529679 100644 --- a/tests/integration/test_mysql_protocol/clients/java/Test.java +++ b/tests/integration/test_mysql_protocol/clients/java/Test.java @@ -5,8 +5,8 @@ import java.sql.SQLException; import java.sql.Statement; class JavaConnectorTest { - private static final String CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS default.test1 (age Int32, name String) Engine = Memory"; - private static final String INSERT_SQL = "INSERT INTO default.test1 VALUES(33, 'jdbc'),(44, 'ck')"; + private static final String CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS default.test1 (`age` Int32, `name` String, `int_nullable` Nullable(Int32)) Engine = Memory"; + private static final String INSERT_SQL = "INSERT INTO default.test1(`age`, `name`) VALUES(33, 'jdbc'),(44, 'ck')"; private static final String SELECT_SQL = "SELECT * FROM default.test1"; private static final String SELECT_NUMBER_SQL = "SELECT * FROM system.numbers LIMIT 13"; private static final String DROP_TABLE_SQL = "DROP TABLE default.test1"; @@ -41,7 +41,7 @@ class JavaConnectorTest { } } - String jdbcUrl = String.format("jdbc:mysql://%s:%s/%s?maxAllowedPacket=67108864&useSSL=false", host, port, database); + String jdbcUrl = String.format("jdbc:mysql://%s:%s/%s", host, port, database); Connection conn = null; Statement stmt = null; @@ -55,6 +55,7 @@ class JavaConnectorTest { while (rs.next()) { System.out.print(rs.getString("age")); System.out.print(rs.getString("name")); + System.out.print(rs.getString("int_nullable")); System.out.println(); } From 365b5207b7d02384f4c3e28402c4b3d748f443df Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Sun, 5 Apr 2020 00:07:00 +0300 Subject: [PATCH 124/208] Add log_queries_min_type to filter which entries will be written to query_log Can be used to write into query_log only failed queries (i.e. on memory exceeded error), by using: set log_queries_min_type='EXCEPTION_WHILE_PROCESSING' --- docs/en/operations/settings/settings.md | 18 +++++++++++++++++ src/Core/Settings.h | 2 +- src/Core/SettingsCollection.cpp | 7 +++++++ src/Core/SettingsCollection.h | 10 ++++++++++ src/Interpreters/QueryLog.h | 9 ++------- src/Interpreters/executeQuery.cpp | 20 +++++++++---------- .../01231_log_queries_min_type.reference | 5 +++++ .../01231_log_queries_min_type.sql | 15 ++++++++++++++ 8 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 tests/queries/0_stateless/01231_log_queries_min_type.reference create mode 100644 tests/queries/0_stateless/01231_log_queries_min_type.sql diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 69c444ebaef..37b4c713f91 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -507,6 +507,24 @@ Example: log_queries=1 ``` +## log\_queries\_min\_type {#settings-log-queries-min-type} + +`query_log` minimal type to log. + +Possible values: +- `QUERY_START` (`=1`) +- `QUERY_FINISH` (`=2`) +- `EXCEPTION_BEFORE_START` (`=3`) +- `EXCEPTION_WHILE_PROCESSING` (`=4`) + +Default value: `QUERY_START`. + +Can be used to limit which entiries will goes to `query_log`, say you are interesting only in errors, then you can use `EXCEPTION_WHILE_PROCESSING`: + +``` text +log_queries_min_type='EXCEPTION_WHILE_PROCESSING' +``` + ## log\_query\_threads {#settings-log-query-threads} Setting up query threads logging. diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 8138af31d5f..725171d4a1b 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -149,7 +149,7 @@ struct Settings : public SettingsCollection M(SettingInt64, os_thread_priority, 0, "If non zero - set corresponding 'nice' value for query processing threads. Can be used to adjust query priority for OS scheduler.", 0) \ \ M(SettingBool, log_queries, 0, "Log requests and write the log to the system table.", 0) \ - \ + M(SettingLogQueriesType, log_queries_min_type, QueryLogElementType::QUERY_START, "query_log minimal type to log, possible values (from low to high): QUERY_START, QUERY_FINISH, EXCEPTION_BEFORE_START, EXCEPTION_WHILE_PROCESSING.", 0) \ M(SettingUInt64, log_queries_cut_to_length, 100000, "If query length is greater than specified threshold (in bytes), then cut query when writing to query log. Also limit length of printed query in ordinary text log.", 0) \ \ M(SettingDistributedProductMode, distributed_product_mode, DistributedProductMode::DENY, "How are distributed subqueries performed inside IN or JOIN sections?", IMPORTANT) \ diff --git a/src/Core/SettingsCollection.cpp b/src/Core/SettingsCollection.cpp index 6d879b27181..238ac1c3c62 100644 --- a/src/Core/SettingsCollection.cpp +++ b/src/Core/SettingsCollection.cpp @@ -542,6 +542,13 @@ IMPLEMENT_SETTING_ENUM(FormatSettings::DateTimeInputFormat, DATE_TIME_INPUT_FORM M(trace, "trace") IMPLEMENT_SETTING_ENUM(LogsLevel, LOGS_LEVEL_LIST_OF_NAMES, ErrorCodes::BAD_ARGUMENTS) +#define LOG_QUERIES_TYPE_LIST_OF_NAMES(M) \ + M(QUERY_START, "QUERY_START") \ + M(QUERY_FINISH, "QUERY_FINISH") \ + M(EXCEPTION_BEFORE_START, "EXCEPTION_BEFORE_START") \ + M(EXCEPTION_WHILE_PROCESSING, "EXCEPTION_WHILE_PROCESSING") +IMPLEMENT_SETTING_ENUM(QueryLogElementType, LOG_QUERIES_TYPE_LIST_OF_NAMES, ErrorCodes::BAD_ARGUMENTS) + namespace details { diff --git a/src/Core/SettingsCollection.h b/src/Core/SettingsCollection.h index da21412b7c1..d93772e86ed 100644 --- a/src/Core/SettingsCollection.h +++ b/src/Core/SettingsCollection.h @@ -298,6 +298,16 @@ enum class LogsLevel }; using SettingLogsLevel = SettingEnum; +// Make it signed for compatibility with DataTypeEnum8 +enum QueryLogElementType : int8_t +{ + QUERY_START = 1, + QUERY_FINISH = 2, + EXCEPTION_BEFORE_START = 3, + EXCEPTION_WHILE_PROCESSING = 4, +}; +using SettingLogQueriesType = SettingEnum; + enum class SettingsBinaryFormat { diff --git a/src/Interpreters/QueryLog.h b/src/Interpreters/QueryLog.h index 836b37095e9..ec14f5e97fb 100644 --- a/src/Interpreters/QueryLog.h +++ b/src/Interpreters/QueryLog.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace ProfileEvents @@ -22,13 +23,7 @@ namespace DB /// A struct which will be inserted as row into query_log table struct QueryLogElement { - enum Type : int8_t // Make it signed for compatibility with DataTypeEnum8 - { - QUERY_START = 1, - QUERY_FINISH = 2, - EXCEPTION_BEFORE_START = 3, - EXCEPTION_WHILE_PROCESSING = 4, - }; + using Type = QueryLogElementType; Type type = QUERY_START; diff --git a/src/Interpreters/executeQuery.cpp b/src/Interpreters/executeQuery.cpp index c9c66832f08..68bebb83619 100644 --- a/src/Interpreters/executeQuery.cpp +++ b/src/Interpreters/executeQuery.cpp @@ -157,7 +157,7 @@ static void onExceptionBeforeStart(const String & query_for_logging, Context & c /// Log the start of query execution into the table if necessary. QueryLogElement elem; - elem.type = QueryLogElement::EXCEPTION_BEFORE_START; + elem.type = QueryLogElementType::EXCEPTION_BEFORE_START; elem.event_time = current_time; elem.query_start_time = current_time; @@ -175,7 +175,7 @@ static void onExceptionBeforeStart(const String & query_for_logging, Context & c /// Update performance counters before logging to query_log CurrentThread::finalizePerformanceCounters(); - if (settings.log_queries) + if (settings.log_queries && elem.type >= settings.log_queries_min_type) if (auto query_log = context.getQueryLog()) query_log->add(elem); } @@ -400,7 +400,7 @@ static std::tuple executeQueryImpl( { QueryLogElement elem; - elem.type = QueryLogElement::QUERY_START; + elem.type = QueryLogElementType::QUERY_START; elem.event_time = current_time; elem.query_start_time = current_time; @@ -412,7 +412,7 @@ static std::tuple executeQueryImpl( bool log_queries = settings.log_queries && !internal; /// Log into system table start of query execution, if need. - if (log_queries) + if (log_queries && elem.type >= settings.log_queries_min_type) { if (settings.log_query_settings) elem.query_settings = std::make_shared(context.getSettingsRef()); @@ -422,7 +422,7 @@ static std::tuple executeQueryImpl( } /// Also make possible for caller to log successful query finish and exception during execution. - auto finish_callback = [elem, &context, log_queries] (IBlockInputStream * stream_in, IBlockOutputStream * stream_out) mutable + auto finish_callback = [elem, &context, log_queries, log_queries_min_type = settings.log_queries_min_type] (IBlockInputStream * stream_in, IBlockOutputStream * stream_out) mutable { QueryStatus * process_list_elem = context.getProcessListElement(); @@ -436,7 +436,7 @@ static std::tuple executeQueryImpl( double elapsed_seconds = info.elapsed_seconds; - elem.type = QueryLogElement::QUERY_FINISH; + elem.type = QueryLogElementType::QUERY_FINISH; elem.event_time = time(nullptr); elem.query_duration_ms = elapsed_seconds * 1000; @@ -484,19 +484,19 @@ static std::tuple executeQueryImpl( elem.thread_ids = std::move(info.thread_ids); elem.profile_counters = std::move(info.profile_counters); - if (log_queries) + if (log_queries && elem.type >= log_queries_min_type) { if (auto query_log = context.getQueryLog()) query_log->add(elem); } }; - auto exception_callback = [elem, &context, log_queries, quota(quota)] () mutable + auto exception_callback = [elem, &context, log_queries, log_queries_min_type = settings.log_queries_min_type, quota(quota)] () mutable { if (quota) quota->used(Quota::ERRORS, 1, /* check_exceeded = */ false); - elem.type = QueryLogElement::EXCEPTION_WHILE_PROCESSING; + elem.type = QueryLogElementType::EXCEPTION_WHILE_PROCESSING; elem.event_time = time(nullptr); elem.query_duration_ms = 1000 * (elem.event_time - elem.query_start_time); @@ -529,7 +529,7 @@ static std::tuple executeQueryImpl( logException(context, elem); /// In case of exception we log internal queries also - if (log_queries) + if (log_queries && elem.type >= log_queries_min_type) { if (auto query_log = context.getQueryLog()) query_log->add(elem); diff --git a/tests/queries/0_stateless/01231_log_queries_min_type.reference b/tests/queries/0_stateless/01231_log_queries_min_type.reference new file mode 100644 index 00000000000..a358d022033 --- /dev/null +++ b/tests/queries/0_stateless/01231_log_queries_min_type.reference @@ -0,0 +1,5 @@ +01231_log_queries_min_type/QUERY_START +2 +01231_log_queries_min_type/EXCEPTION_BEFORE_START +2 +3 diff --git a/tests/queries/0_stateless/01231_log_queries_min_type.sql b/tests/queries/0_stateless/01231_log_queries_min_type.sql new file mode 100644 index 00000000000..f2229c94a8a --- /dev/null +++ b/tests/queries/0_stateless/01231_log_queries_min_type.sql @@ -0,0 +1,15 @@ +set log_queries=1; + +select '01231_log_queries_min_type/QUERY_START'; +system flush logs; +select count() from system.query_log where query like '%01231_log_queries_min_type/%' and query not like '%system.query_log%' and event_date = today() and event_time >= now() - interval 1 minute; + +set log_queries_min_type='EXCEPTION_BEFORE_START'; +select '01231_log_queries_min_type/EXCEPTION_BEFORE_START'; +system flush logs; +select count() from system.query_log where query like '%01231_log_queries_min_type/%' and query not like '%system.query_log%' and event_date = today() and event_time >= now() - interval 1 minute; + +set log_queries_min_type='EXCEPTION_WHILE_PROCESSING'; +select '01231_log_queries_min_type/', max(number) from system.numbers limit 1e6 settings max_rows_to_read='100K'; -- { serverError 158; } +system flush logs; +select count() from system.query_log where query like '%01231_log_queries_min_type/%' and query not like '%system.query_log%' and event_date = today() and event_time >= now() - interval 1 minute; From 676964de658b21e56a49408d708dcad689c14616 Mon Sep 17 00:00:00 2001 From: Maroun Maroun Date: Sun, 12 Apr 2020 12:26:06 +0300 Subject: [PATCH 125/208] Fix typo in the getting started tutorial: "it's" -> "its" (#10201) --- docs/en/getting_started/tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/en/getting_started/tutorial.md b/docs/en/getting_started/tutorial.md index 08cca45d21d..9763f814d59 100644 --- a/docs/en/getting_started/tutorial.md +++ b/docs/en/getting_started/tutorial.md @@ -108,7 +108,7 @@ Syntax for creating tables is way more complicated compared to databases (see [r 1. Name of table to create. 2. Table schema, i.e. list of columns and their [data types](../sql_reference/data_types/index.md). -3. [Table engine](../engines/table_engines/index.md) and it’s settings, which determines all the details on how queries to this table will be physically executed. +3. [Table engine](../engines/table_engines/index.md) and its settings, which determines all the details on how queries to this table will be physically executed. Yandex.Metrica is a web analytics service, and sample dataset doesn’t cover its full functionality, so there are only two tables to create: From f5c463e9adccea74507720c71f0456d44c4a54d6 Mon Sep 17 00:00:00 2001 From: BohuTANG Date: Sun, 12 Apr 2020 21:28:36 +0800 Subject: [PATCH 126/208] Fix path and typo in the tests.md --- docs/en/development/tests.md | 12 ++++++------ docs/es/development/tests.md | 6 +++--- docs/fa/development/tests.md | 6 +++--- docs/fr/development/tests.md | 6 +++--- docs/ja/development/tests.md | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/en/development/tests.md b/docs/en/development/tests.md index 02620b92367..45adb221b5b 100644 --- a/docs/en/development/tests.md +++ b/docs/en/development/tests.md @@ -15,7 +15,7 @@ Tests are located in `queries` directory. There are two subdirectories: `statele Each test can be one of two types: `.sql` and `.sh`. `.sql` test is the simple SQL script that is piped to `clickhouse-client --multiquery --testmode`. `.sh` test is a script that is run by itself. -To run all tests, use `testskhouse-test` tool. Look `--help` for the list of possible options. You can simply run all tests or run subset of tests filtered by substring in test name: `./clickhouse-test substring`. +To run all tests, use `clickhouse-test` tool. Look `--help` for the list of possible options. You can simply run all tests or run subset of tests filtered by substring in test name: `./clickhouse-test substring`. The most simple way to invoke functional tests is to copy `clickhouse-client` to `/usr/bin/`, run `clickhouse-server` and then run `./clickhouse-test` from its own directory. @@ -34,13 +34,13 @@ disable these groups of tests using `--no-zookeeper`, `--no-shard` and ## Known Bugs {#known-bugs} -If we know some bugs that can be easily reproduced by functional tests, we place prepared functional tests in `queries/bugs` directory. These tests will be moved to `teststests_stateless` when bugs are fixed. +If we know some bugs that can be easily reproduced by functional tests, we place prepared functional tests in `tests/queries/bugs` directory. These tests will be moved to `tests/queries/0_stateless` when bugs are fixed. ## Integration Tests {#integration-tests} Integration tests allow to test ClickHouse in clustered configuration and ClickHouse interaction with other servers like MySQL, Postgres, MongoDB. They are useful to emulate network splits, packet drops, etc. These tests are run under Docker and create multiple containers with various software. -See `testsgration/README.md` on how to run these tests. +See `tests/integration/README.md` on how to run these tests. Note that integration of ClickHouse with third-party drivers is not tested. Also we currently don’t have integration tests with our JDBC and ODBC drivers. @@ -54,7 +54,7 @@ It’s not necessarily to have unit tests if the code is already covered by func Performance tests allow to measure and compare performance of some isolated part of ClickHouse on synthetic queries. Tests are located at `tests/performance`. Each test is represented by `.xml` file with description of test case. Tests are run with `clickhouse performance-test` tool (that is embedded in `clickhouse` binary). See `--help` for invocation. -Each test run one or miltiple queries (possibly with combinations of parameters) in a loop with some conditions for stop (like “maximum execution speed is not changing in three seconds”) and measure some metrics about query performance (like “maximum execution speed”). Some tests can contain preconditions on preloaded test dataset. +Each test run one or multiple queries (possibly with combinations of parameters) in a loop with some conditions for stop (like “maximum execution speed is not changing in three seconds”) and measure some metrics about query performance (like “maximum execution speed”). Some tests can contain preconditions on preloaded test dataset. If you want to improve performance of ClickHouse in some scenario, and if improvements can be observed on simple queries, it is highly recommended to write a performance test. It always makes sense to use `perf top` or other perf tools during your tests. @@ -64,13 +64,13 @@ Some programs in `tests` directory are not prepared tests, but are test tools. F You can also place pair of files `.sh` and `.reference` along with the tool to run it on some predefined input - then script result can be compared to `.reference` file. These kind of tests are not automated. -## Miscellanous Tests {#miscellanous-tests} +## Miscellaneous Tests {#miscellaneous-tests} There are tests for external dictionaries located at `tests/external_dictionaries` and for machine learned models in `tests/external_models`. These tests are not updated and must be transferred to integration tests. There is separate test for quorum inserts. This test run ClickHouse cluster on separate servers and emulate various failure cases: network split, packet drop (between ClickHouse nodes, between ClickHouse and ZooKeeper, between ClickHouse server and client, etc.), `kill -9`, `kill -STOP` and `kill -CONT` , like [Jepsen](https://aphyr.com/tags/Jepsen). Then the test checks that all acknowledged inserts was written and all rejected inserts was not. -Quorum test was written by separate team before ClickHouse was open-sourced. This team no longer work with ClickHouse. Test was accidentially written in Java. For these reasons, quorum test must be rewritten and moved to integration tests. +Quorum test was written by separate team before ClickHouse was open-sourced. This team no longer work with ClickHouse. Test was accidentally written in Java. For these reasons, quorum test must be rewritten and moved to integration tests. ## Manual Testing {#manual-testing} diff --git a/docs/es/development/tests.md b/docs/es/development/tests.md index 388931e9436..12afbb68f2e 100644 --- a/docs/es/development/tests.md +++ b/docs/es/development/tests.md @@ -17,7 +17,7 @@ Las pruebas se encuentran en `queries` directorio. Hay dos subdirectorios: `stat Cada prueba puede ser de dos tipos: `.sql` y `.sh`. `.sql` test es el script SQL simple que se canaliza a `clickhouse-client --multiquery --testmode`. `.sh` test es un script que se ejecuta por sí mismo. -Para ejecutar todas las pruebas, use `testskhouse-test` herramienta. Mira `--help` para la lista de posibles opciones. Simplemente puede ejecutar todas las pruebas o ejecutar un subconjunto de pruebas filtradas por subcadena en el nombre de la prueba: `./clickhouse-test substring`. +Para ejecutar todas las pruebas, use `clickhouse-test` herramienta. Mira `--help` para la lista de posibles opciones. Simplemente puede ejecutar todas las pruebas o ejecutar un subconjunto de pruebas filtradas por subcadena en el nombre de la prueba: `./clickhouse-test substring`. La forma más sencilla de invocar pruebas funcionales es copiar `clickhouse-client` a `/usr/bin/`, ejecutar `clickhouse-server` y luego ejecutar `./clickhouse-test` de su propio directorio. @@ -36,13 +36,13 @@ deshabilitar estos grupos de pruebas utilizando `--no-zookeeper`, `--no-shard` y ## Bugs conocidos {#known-bugs} -Si conocemos algunos errores que se pueden reproducir fácilmente mediante pruebas funcionales, colocamos pruebas funcionales preparadas en `queries/bugs` directorio. Estas pruebas se moverán a `teststests_stateless` cuando se corrigen errores. +Si conocemos algunos errores que se pueden reproducir fácilmente mediante pruebas funcionales, colocamos pruebas funcionales preparadas en `tests/queries/bugs` directorio. Estas pruebas se moverán a `tests/queries/0_stateless` cuando se corrigen errores. ## Pruebas de integración {#integration-tests} Las pruebas de integración permiten probar ClickHouse en la configuración agrupada y la interacción de ClickHouse con otros servidores como MySQL, Postgres, MongoDB. Son útiles para emular divisiones de red, caídas de paquetes, etc. Estas pruebas se ejecutan bajo Docker y crean múltiples contenedores con varios software. -Ver `testsgration/README.md` sobre cómo ejecutar estas pruebas. +Ver `tests/integration/README.md` sobre cómo ejecutar estas pruebas. Tenga en cuenta que la integración de ClickHouse con controladores de terceros no se ha probado. Además, actualmente no tenemos pruebas de integración con nuestros controladores JDBC y ODBC. diff --git a/docs/fa/development/tests.md b/docs/fa/development/tests.md index 874ac3063b9..922bc43fd46 100644 --- a/docs/fa/development/tests.md +++ b/docs/fa/development/tests.md @@ -18,7 +18,7 @@ toc_title: "\u0646\u062D\u0648\u0647 \u0627\u062C\u0631\u0627\u06CC \u062A\u0633 هر تست می تواند یکی از دو نوع باشد: `.sql` و `.sh`. `.sql` تست اسکریپت ساده مربع است که به لوله کشی است `clickhouse-client --multiquery --testmode`. `.sh` تست یک اسکریپت است که به خودی خود اجرا است. -برای اجرای تمام تست ها استفاده کنید `testskhouse-test` ابزار. نگاه کن `--help` برای لیستی از گزینه های ممکن. شما به سادگی می توانید تمام تست ها را اجرا کنید یا زیر مجموعه ای از تست های فیلتر شده توسط زیر رشته را در نام تست اجرا کنید: `./clickhouse-test substring`. +برای اجرای تمام تست ها استفاده کنید `clickhouse-test` ابزار. نگاه کن `--help` برای لیستی از گزینه های ممکن. شما به سادگی می توانید تمام تست ها را اجرا کنید یا زیر مجموعه ای از تست های فیلتر شده توسط زیر رشته را در نام تست اجرا کنید: `./clickhouse-test substring`. ساده ترین راه برای فراخوانی تست های کاربردی کپی است `clickhouse-client` به `/usr/bin/` فرار کن `clickhouse-server` و سپس اجرا کنید `./clickhouse-test` از دایرکتوری خود را. @@ -37,13 +37,13 @@ toc_title: "\u0646\u062D\u0648\u0647 \u0627\u062C\u0631\u0627\u06CC \u062A\u0633 ## اشکالات شناخته شده {#known-bugs} -اگر ما می دانیم برخی از اشکالات است که می تواند به راحتی توسط تست های کاربردی تکثیر, ما تست های عملکردی تهیه شده در `queries/bugs` فهرست راهنما. این تست خواهد شد به نقل مکان کرد `teststests_stateless` هنگامی که اشکالات ثابت هستند. +اگر ما می دانیم برخی از اشکالات است که می تواند به راحتی توسط تست های کاربردی تکثیر, ما تست های عملکردی تهیه شده در `tests/queries/bugs` فهرست راهنما. این تست خواهد شد به نقل مکان کرد `tests/queries/0_stateless` هنگامی که اشکالات ثابت هستند. ## تست های ادغام {#integration-tests} ادغام آزمون اجازه می دهد برای تست clickhouse در خوشه پیکربندی و clickhouse تعامل با سرور های دیگر مانند mysql, postgres, mongodb. مفید برای تقلید انشعابات شبکه قطره بسته و غیره هستند. این تست ها تحت کارگر بارانداز اجرا و ایجاد ظروف متعدد با نرم افزار های مختلف. -ببینید `testsgration/README.md` در مورد چگونگی اجرای این تست. +ببینید `tests/integration/README.md` در مورد چگونگی اجرای این تست. توجه داشته باشید که ادغام کلیک با رانندگان شخص ثالث تست نشده است. همچنین ما در حال حاضر تست های یکپارچه سازی با رانندگان جی بی سی و بی سی ما ندارد. diff --git a/docs/fr/development/tests.md b/docs/fr/development/tests.md index e5c8a50fa31..6637e9546fe 100644 --- a/docs/fr/development/tests.md +++ b/docs/fr/development/tests.md @@ -17,7 +17,7 @@ Les Tests sont situés dans `queries` répertoire. Il y a deux sous-répertoires Chaque test peut être de deux types: `.sql` et `.sh`. `.sql` test est le script SQL simple qui est canalisé vers `clickhouse-client --multiquery --testmode`. `.sh` test est un script qui est exécuté par lui-même. -Pour exécuter tous les tests, utilisez `testskhouse-test` outil. Regarder `--help` pour la liste des options possibles. Vous pouvez simplement exécuter tous les tests ou exécuter un sous ensemble de tests filtrés par sous chaîne dans le nom du test: `./clickhouse-test substring`. +Pour exécuter tous les tests, utilisez `clickhouse-test` outil. Regarder `--help` pour la liste des options possibles. Vous pouvez simplement exécuter tous les tests ou exécuter un sous ensemble de tests filtrés par sous chaîne dans le nom du test: `./clickhouse-test substring`. Le moyen le plus simple d'invoquer des tests fonctionnels est de copier `clickhouse-client` de `/usr/bin/`, exécuter `clickhouse-server` et puis exécutez `./clickhouse-test` à partir de son propre répertoire. @@ -36,13 +36,13 @@ désactivez ces groupes de tests en utilisant `--no-zookeeper`, `--no-shard` et ## Bugs connus {#known-bugs} -Si nous connaissons des bugs qui peuvent être facilement reproduits par des tests fonctionnels, nous plaçons des tests fonctionnels préparés dans `queries/bugs` répertoire. Ces tests seront déplacés à `teststests_stateless` quand les bugs sont corrigés. +Si nous connaissons des bugs qui peuvent être facilement reproduits par des tests fonctionnels, nous plaçons des tests fonctionnels préparés dans `tests/queries/bugs` répertoire. Ces tests seront déplacés à `tests/queries/0_stateless` quand les bugs sont corrigés. ## Les Tests D'Intégration {#integration-tests} Les tests d'intégration permettent de tester ClickHouse en configuration cluster et clickhouse interaction avec D'autres serveurs comme MySQL, Postgres, MongoDB. Ils sont utiles pour émuler les splits réseau, les chutes de paquets, etc. Ces tests sont exécutés sous Docker et créent plusieurs conteneurs avec divers logiciels. -Voir `testsgration/README.md` sur la façon d'exécuter ces tests. +Voir `tests/integration/README.md` sur la façon d'exécuter ces tests. Notez que l'intégration de ClickHouse avec des pilotes tiers n'est pas testée. De plus, nous n'avons actuellement pas de tests d'intégration avec nos pilotes JDBC et ODBC. diff --git a/docs/ja/development/tests.md b/docs/ja/development/tests.md index 27b8870461e..b6c5abea621 100644 --- a/docs/ja/development/tests.md +++ b/docs/ja/development/tests.md @@ -17,7 +17,7 @@ toc_title: "ClickHouse\u30C6\u30B9\u30C8\u3092\u5B9F\u884C\u3059\u308B\u65B9\u6C それぞれの試験できるの種類: `.sql` と `.sh`. `.sql` testは、パイプ処理される単純なSQLスクリプトです `clickhouse-client --multiquery --testmode`. `.sh` テストは、単独で実行されるスクリプトです。 -すべてのテストを実行するには、 `testskhouse-test` ツール。 見て! `--help` 可能なオプションのリストについて。 できるだけ実行すべての試験または実行のサブセットの試験フィルター部分文字列の試験名: `./clickhouse-test substring`. +すべてのテストを実行するには、 `clickhouse-test` ツール。 見て! `--help` 可能なオプションのリストについて。 できるだけ実行すべての試験または実行のサブセットの試験フィルター部分文字列の試験名: `./clickhouse-test substring`. 機能テストを呼び出す最も簡単な方法は、コピーすることです `clickhouse-client` に `/usr/bin/`、実行 `clickhouse-server` そして、実行 `./clickhouse-test` 独自のディレクトリから。 @@ -36,13 +36,13 @@ toc_title: "ClickHouse\u30C6\u30B9\u30C8\u3092\u5B9F\u884C\u3059\u308B\u65B9\u6C ## 既知のバグ {#known-bugs} -機能テストで簡単に再現できるいくつかのバグを知っていれば、準備された機能テストを `queries/bugs` ディレクトリ。 これらのテストはに移動されます `teststests_stateless` バグが修正されたとき。 +機能テストで簡単に再現できるいくつかのバグを知っていれば、準備された機能テストを `tests/queries/bugs` ディレクトリ。 これらのテストはに移動されます `tests/queries/0_stateless` バグが修正されたとき。 ## 統合テスト {#integration-tests} 統合テストでは、クラスター化された設定でclickhouseをテストし、mysql、postgres、mongodbのような他のサーバーとのclickhouseの相互作用を可能にします。 それらはネットワークの割れ目、包みの低下、等を競争して有用である。 これらの試験する方向に作用しdockerを複数の容器を様々なソフトウェアです。 -見る `testsgration/README.md` これらのテストを実行する方法について。 +見る `tests/integration/README.md` これらのテストを実行する方法について。 ClickHouseとサードパーティドライバの統合はテストされていません。 また、現在、JDBCおよびODBCドライバとの統合テストはありません。 From eaba5c6c73f06c96856743e50dd9a47694418e7f Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev Date: Sat, 11 Apr 2020 13:57:13 +0300 Subject: [PATCH 127/208] Remove mutable defaults from helpers/cluster.py --- tests/integration/helpers/cluster.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/integration/helpers/cluster.py b/tests/integration/helpers/cluster.py index 5dc93cb338a..717fab11449 100644 --- a/tests/integration/helpers/cluster.py +++ b/tests/integration/helpers/cluster.py @@ -139,12 +139,12 @@ class ClickHouseCluster: cmd += " client" return cmd - def add_instance(self, name, config_dir=None, main_configs=[], user_configs=[], macros={}, + def add_instance(self, name, config_dir=None, main_configs=None, user_configs=None, macros=None, with_zookeeper=False, with_mysql=False, with_kafka=False, clickhouse_path_dir=None, with_odbc_drivers=False, with_postgres=False, with_hdfs=False, with_mongo=False, with_redis=False, with_minio=False, - hostname=None, env_variables={}, image="yandex/clickhouse-integration-test", - stay_alive=False, ipv4_address=None, ipv6_address=None, with_installed_binary=False, tmpfs=[]): + hostname=None, env_variables=None, image="yandex/clickhouse-integration-test", + stay_alive=False, ipv4_address=None, ipv6_address=None, with_installed_binary=False, tmpfs=None): """Add an instance to the cluster. name - the name of the instance directory and the value of the 'instance' macro in ClickHouse. @@ -161,13 +161,14 @@ class ClickHouseCluster: raise Exception("Can\'t add instance `%s': there is already an instance with the same name!" % name) instance = ClickHouseInstance( - self, self.base_dir, name, config_dir, main_configs, user_configs, macros, with_zookeeper, + self, self.base_dir, name, config_dir, main_configs or [], user_configs or [], macros or {}, + with_zookeeper, self.zookeeper_config_path, with_mysql, with_kafka, with_mongo, with_redis, with_minio, self.base_configs_dir, self.server_bin_path, self.odbc_bridge_bin_path, clickhouse_path_dir, with_odbc_drivers, hostname=hostname, - env_variables=env_variables, image=image, stay_alive=stay_alive, ipv4_address=ipv4_address, + env_variables=env_variables or {}, image=image, stay_alive=stay_alive, ipv4_address=ipv4_address, ipv6_address=ipv6_address, - with_installed_binary=with_installed_binary, tmpfs=tmpfs) + with_installed_binary=with_installed_binary, tmpfs=tmpfs or []) self.instances[name] = instance if ipv4_address is not None or ipv6_address is not None: @@ -580,17 +581,17 @@ class ClickHouseInstance: self, cluster, base_path, name, custom_config_dir, custom_main_configs, custom_user_configs, macros, with_zookeeper, zookeeper_config_path, with_mysql, with_kafka, with_mongo, with_redis, with_minio, base_configs_dir, server_bin_path, odbc_bridge_bin_path, - clickhouse_path_dir, with_odbc_drivers, hostname=None, env_variables={}, + clickhouse_path_dir, with_odbc_drivers, hostname=None, env_variables=None, image="yandex/clickhouse-integration-test", - stay_alive=False, ipv4_address=None, ipv6_address=None, with_installed_binary=False, tmpfs=[]): + stay_alive=False, ipv4_address=None, ipv6_address=None, with_installed_binary=False, tmpfs=None): self.name = name - self.base_cmd = cluster.base_cmd[:] + self.base_cmd = cluster.base_cmd self.docker_id = cluster.get_instance_docker_id(self.name) self.cluster = cluster self.hostname = hostname if hostname is not None else self.name - self.tmpfs = tmpfs[:] + self.tmpfs = tmpfs or [] self.custom_config_dir = p.abspath(p.join(base_path, custom_config_dir)) if custom_config_dir else None self.custom_main_config_paths = [p.abspath(p.join(base_path, c)) for c in custom_main_configs] self.custom_user_config_paths = [p.abspath(p.join(base_path, c)) for c in custom_user_configs] @@ -611,7 +612,7 @@ class ClickHouseInstance: self.path = p.join(self.cluster.instances_dir, name) self.docker_compose_path = p.join(self.path, 'docker_compose.yml') - self.env_variables = env_variables + self.env_variables = env_variables or {} if with_odbc_drivers: self.odbc_ini_path = os.path.dirname(self.docker_compose_path) + "/odbc.ini:/etc/odbc.ini" self.with_mysql = True @@ -1041,4 +1042,4 @@ class ClickHouseKiller(object): self.clickhouse_node.kill_clickhouse() def __exit__(self, exc_type, exc_val, exc_tb): - self.clickhouse_node.restore_clickhouse() \ No newline at end of file + self.clickhouse_node.restore_clickhouse() From 4da19d122d7532ff4a68cf39ed2147029ef5ace3 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Sun, 12 Apr 2020 18:02:17 +0300 Subject: [PATCH 128/208] Added IProcessor::onUpdatePorts --- src/Processors/Executors/PipelineExecutor.cpp | 2 ++ src/Processors/IProcessor.h | 4 ++++ src/Processors/Sources/SourceFromInputStream.h | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/src/Processors/Executors/PipelineExecutor.cpp b/src/Processors/Executors/PipelineExecutor.cpp index f2d2477991e..78229e4d379 100644 --- a/src/Processors/Executors/PipelineExecutor.cpp +++ b/src/Processors/Executors/PipelineExecutor.cpp @@ -263,6 +263,8 @@ bool PipelineExecutor::tryAddProcessorToStackIfUpdated(Edge & edge, Queue & queu node.status = ExecStatus::Preparing; return prepareProcessor(edge.to, thread_number, queue, std::move(lock)); } + else + graph[edge.to].processor->onUpdatePorts(); return true; } diff --git a/src/Processors/IProcessor.h b/src/Processors/IProcessor.h index a613e8008d0..8f43a5e149b 100644 --- a/src/Processors/IProcessor.h +++ b/src/Processors/IProcessor.h @@ -233,6 +233,10 @@ public: onCancel(); } + /// Additional method which is called in case if ports were updated while work() method. + /// May be used to stop execution in rare cases. + virtual void onUpdatePorts() {}; + virtual ~IProcessor() = default; auto & getInputs() { return inputs; } diff --git a/src/Processors/Sources/SourceFromInputStream.h b/src/Processors/Sources/SourceFromInputStream.h index b547e6a6d1f..13d42c937f3 100644 --- a/src/Processors/Sources/SourceFromInputStream.h +++ b/src/Processors/Sources/SourceFromInputStream.h @@ -37,6 +37,13 @@ public: void setProgressCallback(const ProgressCallback & callback) final { stream->setProgressCallback(callback); } void addTotalRowsApprox(size_t value) final { stream->addTotalRowsApprox(value); } + /// Stop reading from stream if output port is finished. + void onUpdatePorts() override + { + if (getPort().isFinished()) + onCancel(); + } + protected: void onCancel() override { stream->cancel(false); } From bff1f24cf717e004a2b04abaea28a6d82bd2c721 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Sun, 12 Apr 2020 18:21:21 +0300 Subject: [PATCH 129/208] Added IProcessor::onUpdatePorts --- src/Processors/Sources/SourceFromInputStream.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Processors/Sources/SourceFromInputStream.h b/src/Processors/Sources/SourceFromInputStream.h index 13d42c937f3..88a045e65a2 100644 --- a/src/Processors/Sources/SourceFromInputStream.h +++ b/src/Processors/Sources/SourceFromInputStream.h @@ -41,7 +41,7 @@ public: void onUpdatePorts() override { if (getPort().isFinished()) - onCancel(); + cancel(); } protected: From 2b052a44d98bb91981f97ec8b0664283e9dafbbc Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Sun, 12 Apr 2020 18:25:51 +0300 Subject: [PATCH 130/208] Added test --- .../01245_limit_infinite_sources.reference | 1 + .../0_stateless/01245_limit_infinite_sources.sql | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 tests/queries/0_stateless/01245_limit_infinite_sources.reference create mode 100644 tests/queries/0_stateless/01245_limit_infinite_sources.sql diff --git a/tests/queries/0_stateless/01245_limit_infinite_sources.reference b/tests/queries/0_stateless/01245_limit_infinite_sources.reference new file mode 100644 index 00000000000..d00491fd7e5 --- /dev/null +++ b/tests/queries/0_stateless/01245_limit_infinite_sources.reference @@ -0,0 +1 @@ +1 diff --git a/tests/queries/0_stateless/01245_limit_infinite_sources.sql b/tests/queries/0_stateless/01245_limit_infinite_sources.sql new file mode 100644 index 00000000000..803a2d14c39 --- /dev/null +++ b/tests/queries/0_stateless/01245_limit_infinite_sources.sql @@ -0,0 +1,11 @@ +SELECT number +FROM +( + SELECT zero AS number + FROM remote('127.0.0.2', system.zeros) + UNION ALL + SELECT number + sleep(0.5) + FROM system.numbers +) +WHERE number = 1 +LIMIT 1 From d4a3ef2fdc342cf0951022f9183844505548a5b3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 19:15:53 +0300 Subject: [PATCH 131/208] Fixed wrong code (no changes in behaviour) --- src/IO/parseDateTimeBestEffort.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/IO/parseDateTimeBestEffort.cpp b/src/IO/parseDateTimeBestEffort.cpp index 6e747b13b3f..84a40144155 100644 --- a/src/IO/parseDateTimeBestEffort.cpp +++ b/src/IO/parseDateTimeBestEffort.cpp @@ -69,7 +69,6 @@ template inline void readDecimalNumber(T & res, size_t num_digits, const char * src) { #define READ_DECIMAL_NUMBER(N) do { res *= common::exp10_i32(N); readDecimalNumber(res, src); src += (N); num_digits -= (N); } while (false) - while (num_digits) { switch (num_digits) @@ -80,7 +79,7 @@ inline void readDecimalNumber(T & res, size_t num_digits, const char * src) default: READ_DECIMAL_NUMBER(4); break; } } -#undef DECIMAL_NUMBER_CASE +#undef READ_DECIMAL_NUMBER } struct DateTimeSubsecondPart From 6de712f0f4a7e854c9c881b2121b88d4ee450ea2 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 06:20:15 +0300 Subject: [PATCH 132/208] Fix joined constants, development --- src/Interpreters/ColumnNamesContext.cpp | 4 ++++ src/Interpreters/ExpressionAnalyzer.cpp | 3 +++ src/Interpreters/RequiredSourceColumnsVisitor.cpp | 2 ++ src/Interpreters/SyntaxAnalyzer.cpp | 7 +++++++ src/Interpreters/TableJoin.cpp | 10 +++++++++- src/Interpreters/TranslateQualifiedNamesVisitor.cpp | 9 +++++++-- 6 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/Interpreters/ColumnNamesContext.cpp b/src/Interpreters/ColumnNamesContext.cpp index c8fde183d96..d577fea97ae 100644 --- a/src/Interpreters/ColumnNamesContext.cpp +++ b/src/Interpreters/ColumnNamesContext.cpp @@ -24,6 +24,8 @@ bool ColumnNamesContext::addColumnAliasIfAny(const IAST & ast) if (required_names.count(alias)) masked_columns.insert(alias); + std::cerr << "Alias: " << alias << "\n"; + complex_aliases.insert(alias); return true; } @@ -33,6 +35,8 @@ void ColumnNamesContext::addColumnIdentifier(const ASTIdentifier & node) if (!IdentifierSemantic::getColumnName(node)) return; + std::cerr << "Identifier: " << node.name << "\n"; + /// There should be no complex cases after query normalization. Names to aliases: one-to-many. String alias = node.tryGetAlias(); required_names[node.name].addInclusion(alias); diff --git a/src/Interpreters/ExpressionAnalyzer.cpp b/src/Interpreters/ExpressionAnalyzer.cpp index 9ec32737fdc..4ea762c0d6e 100644 --- a/src/Interpreters/ExpressionAnalyzer.cpp +++ b/src/Interpreters/ExpressionAnalyzer.cpp @@ -559,6 +559,9 @@ JoinPtr SelectQueryExpressionAnalyzer::makeTableJoin(const ASTTablesInSelectQuer /// Actions which need to be calculated on joined block. ExpressionActionsPtr joined_block_actions = createJoinedBlockActions(context, analyzedJoin()); + std::cerr << "Joined block actions: " << joined_block_actions->getSampleBlock().dumpStructure() + << "\n\n" << toString(joined_block_actions->getRequiredColumns()) << "\n"; + if (!subquery_for_join.source) { NamesWithAliases required_columns_with_aliases = diff --git a/src/Interpreters/RequiredSourceColumnsVisitor.cpp b/src/Interpreters/RequiredSourceColumnsVisitor.cpp index 5a740805560..469a5852fa5 100644 --- a/src/Interpreters/RequiredSourceColumnsVisitor.cpp +++ b/src/Interpreters/RequiredSourceColumnsVisitor.cpp @@ -88,12 +88,14 @@ void RequiredSourceColumnsMatcher::visit(const ASTPtr & ast, Data & data) visit(*t, ast, data); return; } + if (auto * t = ast->as()) { data.addTableAliasIfAny(*ast); visit(*t, ast, data); return; } + if (ast->as()) { data.addTableAliasIfAny(*ast); diff --git a/src/Interpreters/SyntaxAnalyzer.cpp b/src/Interpreters/SyntaxAnalyzer.cpp index 5c1b6c7e62b..bd317d61668 100644 --- a/src/Interpreters/SyntaxAnalyzer.cpp +++ b/src/Interpreters/SyntaxAnalyzer.cpp @@ -638,9 +638,13 @@ void SyntaxAnalyzerResult::collectUsedColumns(const ASTPtr & query) /// We calculate required_source_columns with source_columns modifications and swap them on exit required_source_columns = source_columns; + std::cerr << queryToString(query) << "\n"; + RequiredSourceColumnsVisitor::Data columns_context; RequiredSourceColumnsVisitor(columns_context).visit(query); + std::cerr << columns_context << "\n"; + NameSet source_column_names; for (const auto & column : source_columns) source_column_names.insert(column.name); @@ -922,6 +926,9 @@ void SyntaxAnalyzer::normalize(ASTPtr & query, Aliases & aliases, const Settings /// Creates a dictionary `aliases`: alias -> ASTPtr QueryAliasesVisitor(aliases).visit(query); + for (const auto & alias : aliases) + std::cerr << "Alias: " << alias.first << ": " << queryToString(alias.second) << "\n"; + /// Mark table ASTIdentifiers with not a column marker MarkTableIdentifiersVisitor::Data identifiers_data{aliases}; MarkTableIdentifiersVisitor(identifiers_data).visit(query); diff --git a/src/Interpreters/TableJoin.cpp b/src/Interpreters/TableJoin.cpp index 30b5e8e4483..3286bbbefd1 100644 --- a/src/Interpreters/TableJoin.cpp +++ b/src/Interpreters/TableJoin.cpp @@ -1,3 +1,5 @@ +#include + #include #include @@ -5,6 +7,8 @@ #include #include +#include + #include @@ -79,7 +83,9 @@ void TableJoin::deduplicateAndQualifyColumnNames(const NameSet & left_table_colu dedup_columns.push_back(column); auto & inserted = dedup_columns.back(); - if (left_table_columns.count(column.name)) + /// Also qualify unusual column names - that does not look like identifiers. + + if (left_table_columns.count(column.name) || !isValidIdentifierBegin(column.name.at(0))) inserted.name = right_table_prefix + column.name; original_names[inserted.name] = column.name; @@ -157,6 +163,8 @@ NamesWithAliases TableJoin::getRequiredColumns(const Block & sample, const Names void TableJoin::addJoinedColumn(const NameAndTypePair & joined_column) { + std::cerr << "Adding " << joined_column.name << "\n"; + if (join_use_nulls && isLeftOrFull(table_join.kind)) { auto type = joined_column.type->canBeInsideNullable() ? makeNullable(joined_column.type) : joined_column.type; diff --git a/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index 17b1bc004f8..b97aa01826c 100644 --- a/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include namespace DB @@ -107,8 +109,9 @@ void TranslateQualifiedNamesMatcher::visit(ASTIdentifier & identifier, ASTPtr &, IdentifierSemantic::setMembership(identifier, table_pos); /// In case if column from the joined table are in source columns, change it's name to qualified. + /// Also always leave unusual identifiers qualified. auto & table = data.tables[table_pos].table; - if (table_pos && data.hasColumn(short_name)) + if (table_pos && (data.hasColumn(short_name) || !isValidIdentifierBegin(short_name.at(0)))) IdentifierSemantic::setColumnLongName(identifier, table); else IdentifierSemantic::setColumnShortName(identifier, table); @@ -128,7 +131,7 @@ void TranslateQualifiedNamesMatcher::visit(ASTFunction & node, const ASTPtr &, D func_arguments->children.clear(); } -void TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAsterisk & , const ASTPtr & ast, Data & data) +void TranslateQualifiedNamesMatcher::visit(const ASTQualifiedAsterisk &, const ASTPtr & ast, Data & data) { if (ast->children.size() != 1) throw Exception("Logical error: qualified asterisk must have exactly one child", ErrorCodes::LOGICAL_ERROR); @@ -174,6 +177,8 @@ static void addIdentifier(ASTs & nodes, const DatabaseAndTableWithAlias & table, String table_name = table.getQualifiedNamePrefix(false); auto identifier = std::make_shared(std::vector{table_name, column_name}); + std::cerr << "Expanded identifier: " << queryToString(identifier) << "\n"; + bool added = false; if (aliases && aliases->count(identifier->name)) { From ec4889e43e4c564de279c0af61e0d61fb98533bf Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 19:20:12 +0300 Subject: [PATCH 133/208] Remove debug output --- src/Interpreters/ColumnNamesContext.cpp | 4 ---- src/Interpreters/ExpressionAnalyzer.cpp | 3 --- src/Interpreters/SyntaxAnalyzer.cpp | 7 ------- src/Interpreters/TableJoin.cpp | 4 ---- src/Interpreters/TranslateQualifiedNamesVisitor.cpp | 3 --- 5 files changed, 21 deletions(-) diff --git a/src/Interpreters/ColumnNamesContext.cpp b/src/Interpreters/ColumnNamesContext.cpp index d577fea97ae..c8fde183d96 100644 --- a/src/Interpreters/ColumnNamesContext.cpp +++ b/src/Interpreters/ColumnNamesContext.cpp @@ -24,8 +24,6 @@ bool ColumnNamesContext::addColumnAliasIfAny(const IAST & ast) if (required_names.count(alias)) masked_columns.insert(alias); - std::cerr << "Alias: " << alias << "\n"; - complex_aliases.insert(alias); return true; } @@ -35,8 +33,6 @@ void ColumnNamesContext::addColumnIdentifier(const ASTIdentifier & node) if (!IdentifierSemantic::getColumnName(node)) return; - std::cerr << "Identifier: " << node.name << "\n"; - /// There should be no complex cases after query normalization. Names to aliases: one-to-many. String alias = node.tryGetAlias(); required_names[node.name].addInclusion(alias); diff --git a/src/Interpreters/ExpressionAnalyzer.cpp b/src/Interpreters/ExpressionAnalyzer.cpp index 4ea762c0d6e..9ec32737fdc 100644 --- a/src/Interpreters/ExpressionAnalyzer.cpp +++ b/src/Interpreters/ExpressionAnalyzer.cpp @@ -559,9 +559,6 @@ JoinPtr SelectQueryExpressionAnalyzer::makeTableJoin(const ASTTablesInSelectQuer /// Actions which need to be calculated on joined block. ExpressionActionsPtr joined_block_actions = createJoinedBlockActions(context, analyzedJoin()); - std::cerr << "Joined block actions: " << joined_block_actions->getSampleBlock().dumpStructure() - << "\n\n" << toString(joined_block_actions->getRequiredColumns()) << "\n"; - if (!subquery_for_join.source) { NamesWithAliases required_columns_with_aliases = diff --git a/src/Interpreters/SyntaxAnalyzer.cpp b/src/Interpreters/SyntaxAnalyzer.cpp index bd317d61668..5c1b6c7e62b 100644 --- a/src/Interpreters/SyntaxAnalyzer.cpp +++ b/src/Interpreters/SyntaxAnalyzer.cpp @@ -638,13 +638,9 @@ void SyntaxAnalyzerResult::collectUsedColumns(const ASTPtr & query) /// We calculate required_source_columns with source_columns modifications and swap them on exit required_source_columns = source_columns; - std::cerr << queryToString(query) << "\n"; - RequiredSourceColumnsVisitor::Data columns_context; RequiredSourceColumnsVisitor(columns_context).visit(query); - std::cerr << columns_context << "\n"; - NameSet source_column_names; for (const auto & column : source_columns) source_column_names.insert(column.name); @@ -926,9 +922,6 @@ void SyntaxAnalyzer::normalize(ASTPtr & query, Aliases & aliases, const Settings /// Creates a dictionary `aliases`: alias -> ASTPtr QueryAliasesVisitor(aliases).visit(query); - for (const auto & alias : aliases) - std::cerr << "Alias: " << alias.first << ": " << queryToString(alias.second) << "\n"; - /// Mark table ASTIdentifiers with not a column marker MarkTableIdentifiersVisitor::Data identifiers_data{aliases}; MarkTableIdentifiersVisitor(identifiers_data).visit(query); diff --git a/src/Interpreters/TableJoin.cpp b/src/Interpreters/TableJoin.cpp index 3286bbbefd1..339fe2dceb3 100644 --- a/src/Interpreters/TableJoin.cpp +++ b/src/Interpreters/TableJoin.cpp @@ -1,5 +1,3 @@ -#include - #include #include @@ -163,8 +161,6 @@ NamesWithAliases TableJoin::getRequiredColumns(const Block & sample, const Names void TableJoin::addJoinedColumn(const NameAndTypePair & joined_column) { - std::cerr << "Adding " << joined_column.name << "\n"; - if (join_use_nulls && isLeftOrFull(table_join.kind)) { auto type = joined_column.type->canBeInsideNullable() ? makeNullable(joined_column.type) : joined_column.type; diff --git a/src/Interpreters/TranslateQualifiedNamesVisitor.cpp b/src/Interpreters/TranslateQualifiedNamesVisitor.cpp index b97aa01826c..7c31a6db546 100644 --- a/src/Interpreters/TranslateQualifiedNamesVisitor.cpp +++ b/src/Interpreters/TranslateQualifiedNamesVisitor.cpp @@ -18,7 +18,6 @@ #include #include #include -#include namespace DB @@ -177,8 +176,6 @@ static void addIdentifier(ASTs & nodes, const DatabaseAndTableWithAlias & table, String table_name = table.getQualifiedNamePrefix(false); auto identifier = std::make_shared(std::vector{table_name, column_name}); - std::cerr << "Expanded identifier: " << queryToString(identifier) << "\n"; - bool added = false; if (aliases && aliases->count(identifier->name)) { From 66d9ba93894eac80d316da1e1f4ce04e5c2d9d98 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 19:24:16 +0300 Subject: [PATCH 134/208] Added a test --- .../0_stateless/01120_join_constants.reference | 2 ++ .../0_stateless/01120_join_constants.sql | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 tests/queries/0_stateless/01120_join_constants.reference create mode 100644 tests/queries/0_stateless/01120_join_constants.sql diff --git a/tests/queries/0_stateless/01120_join_constants.reference b/tests/queries/0_stateless/01120_join_constants.reference new file mode 100644 index 00000000000..a16427fbdf7 --- /dev/null +++ b/tests/queries/0_stateless/01120_join_constants.reference @@ -0,0 +1,2 @@ +1 hello 1 world world 1 +2 hello 0 world 1 diff --git a/tests/queries/0_stateless/01120_join_constants.sql b/tests/queries/0_stateless/01120_join_constants.sql new file mode 100644 index 00000000000..443559c3ea1 --- /dev/null +++ b/tests/queries/0_stateless/01120_join_constants.sql @@ -0,0 +1,17 @@ +SELECT + t1.*, + t2.*, + 'world', + isConstant('world') +FROM +( + SELECT + arrayJoin([1, 2]) AS k, + 'hello' +) AS t1 +LEFT JOIN +( + SELECT + arrayJoin([1, 3]) AS k, + 'world' +) AS t2 ON t1.k = t2.k; From b00330b5db5e95ba8be818885a95d2c7eee322b8 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 19:25:20 +0300 Subject: [PATCH 135/208] Added bug --- tests/queries/bugs/join_constants_on.sql | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 tests/queries/bugs/join_constants_on.sql diff --git a/tests/queries/bugs/join_constants_on.sql b/tests/queries/bugs/join_constants_on.sql new file mode 100644 index 00000000000..ae967e07adb --- /dev/null +++ b/tests/queries/bugs/join_constants_on.sql @@ -0,0 +1,2 @@ +select cast(1, 'UInt8') from (select arrayJoin([1, 2]) as a) t1 left join (select 1 as b) t2 on b = ignore('UInt8'); +select isConstant('UInt8'), toFixedString('hello', toUInt8(substring('UInt8', 5, 1))) from (select arrayJoin([1, 2]) as a) t1 left join (select 1 as b) t2 on b = ignore('UInt8'); From ea7eb2f4afae6890bf23a7f74c19391d4cb67a7f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 19:33:44 +0300 Subject: [PATCH 136/208] Removed old command line option for client --- programs/client/Client.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp index fef89d9df35..e01eef98006 100644 --- a/programs/client/Client.cpp +++ b/programs/client/Client.cpp @@ -1710,7 +1710,6 @@ public: ("database,d", po::value(), "database") ("pager", po::value(), "pager") ("disable_suggestion,A", "Disable loading suggestion data. Note that suggestion data is loaded asynchronously through a second connection to ClickHouse server. Also it is reasonable to disable suggestion if you want to paste a query with TAB characters. Shorthand option -A is for those who get used to mysql client.") - ("always_load_suggestion_data", "Load suggestion data even if clickhouse-client is run in non-interactive mode. Used for testing.") ("suggestion_limit", po::value()->default_value(10000), "Suggestion limit for how many databases, tables and columns to fetch.") ("multiline,m", "multiline") From d252c59513db55439ee912690427e1a2f6041ff6 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Sun, 12 Apr 2020 20:04:52 +0300 Subject: [PATCH 137/208] Added a test that produces segfault in StorageSystemTables --- ...ecreate_reattach_and_show_tables.reference | 1 + ...rrent_recreate_reattach_and_show_tables.sh | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100755 tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.reference create mode 100755 tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.sh diff --git a/tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.reference b/tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.reference new file mode 100755 index 00000000000..678f9a34e6f --- /dev/null +++ b/tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.reference @@ -0,0 +1 @@ +Test OK diff --git a/tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.sh b/tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.sh new file mode 100755 index 00000000000..8bf21d3cb02 --- /dev/null +++ b/tests/queries/0_stateless/01014_lazy_database_concurrent_recreate_reattach_and_show_tables.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. $CURDIR/../shell_config.sh + +export CURR_DATABASE="test_lazy_01014_concurrent_${CLICKHOUSE_DATABASE}" + + +function recreate_lazy_func1() +{ + $CLICKHOUSE_CLIENT -q " + CREATE TABLE $CURR_DATABASE.log (a UInt64, b UInt64) ENGINE = Log; + "; + + while true; do + $CLICKHOUSE_CLIENT -q " + DETACH TABLE $CURR_DATABASE.log; + "; + + $CLICKHOUSE_CLIENT -q " + ATTACH TABLE $CURR_DATABASE.log; + "; + done +} + +function recreate_lazy_func2() +{ + while true; do + $CLICKHOUSE_CLIENT -q " + CREATE TABLE $CURR_DATABASE.tlog (a UInt64, b UInt64) ENGINE = TinyLog; + "; + + $CLICKHOUSE_CLIENT -q " + DROP TABLE $CURR_DATABASE.tlog; + "; + done +} + +function recreate_lazy_func3() +{ + $CLICKHOUSE_CLIENT -q " + CREATE TABLE $CURR_DATABASE.slog (a UInt64, b UInt64) ENGINE = StripeLog; + "; + + while true; do + $CLICKHOUSE_CLIENT -q " + ATTACH TABLE $CURR_DATABASE.slog; + "; + + $CLICKHOUSE_CLIENT -q " + DETACH TABLE $CURR_DATABASE.slog; + "; + done +} + +function recreate_lazy_func4() +{ + while true; do + $CLICKHOUSE_CLIENT -q " + CREATE TABLE $CURR_DATABASE.tlog2 (a UInt64, b UInt64) ENGINE = TinyLog; + "; + + $CLICKHOUSE_CLIENT -q " + DROP TABLE $CURR_DATABASE.tlog2; + "; + done +} + +function show_tables_func() +{ + while true; do + $CLICKHOUSE_CLIENT -q "SELECT * FROM system.tables WHERE database = '$CURR_DATABASE' FORMAT Null"; + done +} + + +export -f recreate_lazy_func1; +export -f recreate_lazy_func2; +export -f recreate_lazy_func3; +export -f recreate_lazy_func4; +export -f show_tables_func; + + +${CLICKHOUSE_CLIENT} -n -q " + DROP DATABASE IF EXISTS $CURR_DATABASE; + CREATE DATABASE $CURR_DATABASE ENGINE = Lazy(1); +" + + +TIMEOUT=30 + +timeout $TIMEOUT bash -c recreate_lazy_func1 2> /dev/null & +timeout $TIMEOUT bash -c recreate_lazy_func2 2> /dev/null & +timeout $TIMEOUT bash -c recreate_lazy_func3 2> /dev/null & +timeout $TIMEOUT bash -c recreate_lazy_func4 2> /dev/null & +timeout $TIMEOUT bash -c show_tables_func 2> /dev/null & + +wait +sleep 1 + +${CLICKHOUSE_CLIENT} -n -q " + DROP TABLE IF EXISTS $CURR_DATABASE.log; + DROP TABLE IF EXISTS $CURR_DATABASE.slog; + DROP TABLE IF EXISTS $CURR_DATABASE.tlog; + DROP TABLE IF EXISTS $CURR_DATABASE.tlog2; +" +# DROP DATABASE $CURR_DATABASE; -- This fails for some reason + +echo "Test OK" From 2eb2e4cf41909dc82ccf5cd30c02f81941e40e36 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Sun, 12 Apr 2020 20:17:41 +0300 Subject: [PATCH 138/208] Added proper nullptr check --- src/Storages/System/StorageSystemTables.cpp | 23 +++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Storages/System/StorageSystemTables.cpp b/src/Storages/System/StorageSystemTables.cpp index f4ce4a8b717..81ff6a03e12 100644 --- a/src/Storages/System/StorageSystemTables.cpp +++ b/src/Storages/System/StorageSystemTables.cpp @@ -239,20 +239,25 @@ protected: StoragePtr table = nullptr; TableStructureReadLockHolder lock; - try + if (need_lock_structure) { - if (need_lock_structure) + table = tables_it->table(); + if (table == nullptr) + { + // Table might have just been removed or detached for Lazy engine (see DatabaseLazy::tryGetTable()) + continue; + } + try { - table = tables_it->table(); lock = table->lockStructureForShare( false, context.getCurrentQueryId(), context.getSettingsRef().lock_acquire_timeout); } - } - catch (const Exception & e) - { - if (e.code() == ErrorCodes::TABLE_IS_DROPPED) - continue; - throw; + catch (const Exception & e) + { + if (e.code() == ErrorCodes::TABLE_IS_DROPPED) + continue; + throw; + } } ++rows_count; From 718e4bcdf89c96375ff655b233241eee9e12fda4 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 12 Apr 2020 22:01:02 +0300 Subject: [PATCH 139/208] Update IProcessor.h --- src/Processors/IProcessor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Processors/IProcessor.h b/src/Processors/IProcessor.h index 8f43a5e149b..b7c230cb6de 100644 --- a/src/Processors/IProcessor.h +++ b/src/Processors/IProcessor.h @@ -235,7 +235,7 @@ public: /// Additional method which is called in case if ports were updated while work() method. /// May be used to stop execution in rare cases. - virtual void onUpdatePorts() {}; + virtual void onUpdatePorts() {} virtual ~IProcessor() = default; From b56945fa1b4d5cd74aa9daf0b98f15645c19899f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 22:07:16 +0300 Subject: [PATCH 140/208] Remove some bugs --- .../0_stateless/01121_remote_scalar_subquery.reference | 2 ++ .../01121_remote_scalar_subquery.sql} | 0 .../01122_totals_rollup_having_block_header.reference | 0 .../01122_totals_rollup_having_block_header.sql} | 6 ++---- tests/queries/bugs/00938_client_suggestions.sh | 6 ------ 5 files changed, 4 insertions(+), 10 deletions(-) create mode 100644 tests/queries/0_stateless/01121_remote_scalar_subquery.reference rename tests/queries/{bugs/remote_scalar_subquery.sql => 0_stateless/01121_remote_scalar_subquery.sql} (100%) create mode 100644 tests/queries/0_stateless/01122_totals_rollup_having_block_header.reference rename tests/queries/{bugs/totals_rollup_having_block_header.sql => 0_stateless/01122_totals_rollup_having_block_header.sql} (75%) delete mode 100755 tests/queries/bugs/00938_client_suggestions.sh diff --git a/tests/queries/0_stateless/01121_remote_scalar_subquery.reference b/tests/queries/0_stateless/01121_remote_scalar_subquery.reference new file mode 100644 index 00000000000..6ed281c757a --- /dev/null +++ b/tests/queries/0_stateless/01121_remote_scalar_subquery.reference @@ -0,0 +1,2 @@ +1 +1 diff --git a/tests/queries/bugs/remote_scalar_subquery.sql b/tests/queries/0_stateless/01121_remote_scalar_subquery.sql similarity index 100% rename from tests/queries/bugs/remote_scalar_subquery.sql rename to tests/queries/0_stateless/01121_remote_scalar_subquery.sql diff --git a/tests/queries/0_stateless/01122_totals_rollup_having_block_header.reference b/tests/queries/0_stateless/01122_totals_rollup_having_block_header.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/bugs/totals_rollup_having_block_header.sql b/tests/queries/0_stateless/01122_totals_rollup_having_block_header.sql similarity index 75% rename from tests/queries/bugs/totals_rollup_having_block_header.sql rename to tests/queries/0_stateless/01122_totals_rollup_having_block_header.sql index 4f7f9692fd0..4f4f3355912 100644 --- a/tests/queries/bugs/totals_rollup_having_block_header.sql +++ b/tests/queries/0_stateless/01122_totals_rollup_having_block_header.sql @@ -1,5 +1,3 @@ --- triggers assertion in debug build - DROP TABLE IF EXISTS test.rollup_having; CREATE TABLE test.rollup_having ( a Nullable(String), @@ -10,7 +8,7 @@ INSERT INTO test.rollup_having VALUES (NULL, NULL); INSERT INTO test.rollup_having VALUES ('a', NULL); INSERT INTO test.rollup_having VALUES ('a', 'b'); -SELECT a, b, count(*) FROM test.rollup_having GROUP BY a, b WITH ROLLUP WITH TOTALS HAVING a IS NOT NULL; -SELECT a, b, count(*) FROM test.rollup_having GROUP BY a, b WITH ROLLUP WITH TOTALS HAVING a IS NOT NULL and b IS NOT NULL; +SELECT a, b, count(*) FROM test.rollup_having GROUP BY a, b WITH ROLLUP WITH TOTALS HAVING a IS NOT NULL; -- { serverError 48 } +SELECT a, b, count(*) FROM test.rollup_having GROUP BY a, b WITH ROLLUP WITH TOTALS HAVING a IS NOT NULL and b IS NOT NULL; -- { serverError 48 } DROP TABLE test.rollup_having; diff --git a/tests/queries/bugs/00938_client_suggestions.sh b/tests/queries/bugs/00938_client_suggestions.sh deleted file mode 100755 index b4bd9e4480d..00000000000 --- a/tests/queries/bugs/00938_client_suggestions.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -. $CURDIR/../shell_config.sh - -for i in {1..100}; do $CLICKHOUSE_CLIENT --always_load_suggestion_data --query="SELECT 1 FORMAT Null"; done From 8cb4dd275a1554f2f995dd27472f42f7b4359b53 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 22:23:59 +0300 Subject: [PATCH 141/208] Remove default argument (harmful) #10082 --- src/IO/parseDateTimeBestEffort.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/IO/parseDateTimeBestEffort.cpp b/src/IO/parseDateTimeBestEffort.cpp index 84a40144155..2924ad88506 100644 --- a/src/IO/parseDateTimeBestEffort.cpp +++ b/src/IO/parseDateTimeBestEffort.cpp @@ -89,7 +89,12 @@ struct DateTimeSubsecondPart }; template -ReturnType parseDateTimeBestEffortImpl(time_t & res, ReadBuffer & in, const DateLUTImpl & local_time_zone, const DateLUTImpl & utc_time_zone, DateTimeSubsecondPart * fractional = nullptr) +ReturnType parseDateTimeBestEffortImpl( + time_t & res, + ReadBuffer & in, + const DateLUTImpl & local_time_zone, + const DateLUTImpl & utc_time_zone, + DateTimeSubsecondPart * fractional) { auto on_error = [](const std::string & message [[maybe_unused]], int code [[maybe_unused]]) { @@ -581,12 +586,12 @@ ReturnType parseDateTime64BestEffortImpl(DateTime64 & res, UInt32 scale, ReadBuf void parseDateTimeBestEffort(time_t & res, ReadBuffer & in, const DateLUTImpl & local_time_zone, const DateLUTImpl & utc_time_zone) { - parseDateTimeBestEffortImpl(res, in, local_time_zone, utc_time_zone); + parseDateTimeBestEffortImpl(res, in, local_time_zone, utc_time_zone, nullptr); } bool tryParseDateTimeBestEffort(time_t & res, ReadBuffer & in, const DateLUTImpl & local_time_zone, const DateLUTImpl & utc_time_zone) { - return parseDateTimeBestEffortImpl(res, in, local_time_zone, utc_time_zone); + return parseDateTimeBestEffortImpl(res, in, local_time_zone, utc_time_zone, nullptr); } void parseDateTime64BestEffort(DateTime64 & res, UInt32 scale, ReadBuffer & in, const DateLUTImpl & local_time_zone, const DateLUTImpl & utc_time_zone) From 142087c4f7538d42a652294524f7351b71a9d0c3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 22:34:04 +0300 Subject: [PATCH 142/208] Fix "parseDateTimeBestEffort" for strings in RFC-2822 when day of week is Thuesday or Thursday #10082 --- src/IO/parseDateTimeBestEffort.cpp | 5 ++++- .../01123_parse_date_time_best_effort_even_more.reference | 2 ++ .../01123_parse_date_time_best_effort_even_more.sql | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.reference create mode 100644 tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.sql diff --git a/src/IO/parseDateTimeBestEffort.cpp b/src/IO/parseDateTimeBestEffort.cpp index 2924ad88506..68565782edf 100644 --- a/src/IO/parseDateTimeBestEffort.cpp +++ b/src/IO/parseDateTimeBestEffort.cpp @@ -371,7 +371,10 @@ ReturnType parseDateTimeBestEffortImpl( { char c = *in.position(); - if (c == ' ' || c == 'T') + /// 'T' is a separator between date and time according to ISO 8601. + /// But don't skip it if we didn't read the date part yet, because 'T' is also a prefix or 'Tue' and 'Thu'. + + if (c == ' ' || (c == 'T' && year && !has_time)) { ++in.position(); } diff --git a/tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.reference b/tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.reference new file mode 100644 index 00000000000..558ba34abcd --- /dev/null +++ b/tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.reference @@ -0,0 +1,2 @@ +2018-08-18 07:22:16 +2018-08-16 07:22:16 diff --git a/tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.sql b/tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.sql new file mode 100644 index 00000000000..a4f6f173402 --- /dev/null +++ b/tests/queries/0_stateless/01123_parse_date_time_best_effort_even_more.sql @@ -0,0 +1,2 @@ +SELECT toTimeZone(parseDateTimeBestEffort('Thu, 18 Aug 2018 07:22:16 GMT'), 'UTC'); +SELECT toTimeZone(parseDateTimeBestEffort('Tue, 16 Aug 2018 07:22:16 GMT'), 'UTC'); From 3f1658c0e931e8c7467ac959ec2ab175a90d3663 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Sun, 12 Apr 2020 22:35:23 +0300 Subject: [PATCH 143/208] Update parseDateTimeBestEffort.cpp --- src/IO/parseDateTimeBestEffort.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/IO/parseDateTimeBestEffort.cpp b/src/IO/parseDateTimeBestEffort.cpp index 68565782edf..7e40909226c 100644 --- a/src/IO/parseDateTimeBestEffort.cpp +++ b/src/IO/parseDateTimeBestEffort.cpp @@ -372,7 +372,7 @@ ReturnType parseDateTimeBestEffortImpl( char c = *in.position(); /// 'T' is a separator between date and time according to ISO 8601. - /// But don't skip it if we didn't read the date part yet, because 'T' is also a prefix or 'Tue' and 'Thu'. + /// But don't skip it if we didn't read the date part yet, because 'T' is also a prefix for 'Tue' and 'Thu'. if (c == ' ' || (c == 'T' && year && !has_time)) { From 20dcc4decd4baf058cc9e754516c659f98dcf2cc Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 23:05:58 +0300 Subject: [PATCH 144/208] Fixed build on FreeBSD according to the advice from Vitaly @hellvesper --- src/Processors/RowsBeforeLimitCounter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Processors/RowsBeforeLimitCounter.h b/src/Processors/RowsBeforeLimitCounter.h index abee5a09405..36ea4a557a8 100644 --- a/src/Processors/RowsBeforeLimitCounter.h +++ b/src/Processors/RowsBeforeLimitCounter.h @@ -17,7 +17,7 @@ public: uint64_t get() const { return rows_before_limit.load(std::memory_order_acquire); } - void setAppliedLimit() { has_applied_limit.store(true, std::memory_order::release); } + void setAppliedLimit() { has_applied_limit.store(true, std::memory_order_release); } bool hasAppliedLimit() const { return has_applied_limit.load(std::memory_order_acquire); } private: From ceb5c1964af484bfdfdab15a6e385cd73049b9c7 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 12 Apr 2020 23:48:51 +0300 Subject: [PATCH 145/208] Update cctz just in case #10211 --- contrib/cctz | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/cctz b/contrib/cctz index 4f9776a310f..44541cf2b85 160000 --- a/contrib/cctz +++ b/contrib/cctz @@ -1 +1 @@ -Subproject commit 4f9776a310f4952454636363def82c2bf6641d5f +Subproject commit 44541cf2b85ced2a6e5ad4276183a9812d1a54ab From 983950d4ec79cc07c945424d687e72a97b0c979c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 00:07:11 +0300 Subject: [PATCH 146/208] Convert types in Views --- src/Storages/StorageView.cpp | 10 ++++++++-- .../queries/0_stateless/01124_view_bad_types.reference | 10 ++++++++++ .../01124_view_bad_types.sql} | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 tests/queries/0_stateless/01124_view_bad_types.reference rename tests/queries/{bugs/view_bad_types.sql => 0_stateless/01124_view_bad_types.sql} (84%) diff --git a/src/Storages/StorageView.cpp b/src/Storages/StorageView.cpp index 05feeb7d786..78e3c50a879 100644 --- a/src/Storages/StorageView.cpp +++ b/src/Storages/StorageView.cpp @@ -12,13 +12,12 @@ #include #include -#include - #include #include #include #include +#include namespace DB @@ -78,8 +77,15 @@ Pipes StorageView::read( /// It's expected that the columns read from storage are not constant. /// Because method 'getSampleBlockForColumns' is used to obtain a structure of result in InterpreterSelectQuery. for (auto & pipe : pipes) + { pipe.addSimpleTransform(std::make_shared(pipe.getHeader())); + /// And also convert to expected structure. + pipe.addSimpleTransform(std::make_shared( + pipe.getHeader(), getSampleBlockForColumns(column_names), + ConvertingTransform::MatchColumnsMode::Name, context)); + } + return pipes; } diff --git a/tests/queries/0_stateless/01124_view_bad_types.reference b/tests/queries/0_stateless/01124_view_bad_types.reference new file mode 100644 index 00000000000..af98bcd6397 --- /dev/null +++ b/tests/queries/0_stateless/01124_view_bad_types.reference @@ -0,0 +1,10 @@ +0 0 +1 1 +2 2 +3 3 +4 4 +5 5 +6 6 +7 7 +8 8 +9 9 diff --git a/tests/queries/bugs/view_bad_types.sql b/tests/queries/0_stateless/01124_view_bad_types.sql similarity index 84% rename from tests/queries/bugs/view_bad_types.sql rename to tests/queries/0_stateless/01124_view_bad_types.sql index 38daabfd6b8..81fc53930c1 100644 --- a/tests/queries/bugs/view_bad_types.sql +++ b/tests/queries/0_stateless/01124_view_bad_types.sql @@ -5,7 +5,7 @@ INSERT INTO test.table SELECT * FROM system.numbers LIMIT 10; DROP TABLE IF EXISTS test.view; CREATE VIEW test.view (x UInt64) AS SELECT * FROM test.table; -SELECT x, any(x) FROM test.view GROUP BY x; +SELECT x, any(x) FROM test.view GROUP BY x ORDER BY x; DROP TABLE test.view; DROP TABLE test.table; From 3215257a90e914cf00a8399336493252e66056d1 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 00:27:11 +0300 Subject: [PATCH 147/208] Fixed "generateRandom" function for Date type #9973 --- src/Storages/StorageGenerateRandom.cpp | 5 ++++- .../0_stateless/01125_generate_random_qoega.reference | 1 + tests/queries/0_stateless/01125_generate_random_qoega.sql | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/01125_generate_random_qoega.reference create mode 100644 tests/queries/0_stateless/01125_generate_random_qoega.sql diff --git a/src/Storages/StorageGenerateRandom.cpp b/src/Storages/StorageGenerateRandom.cpp index 1fd2d4ec2d8..d0772254045 100644 --- a/src/Storages/StorageGenerateRandom.cpp +++ b/src/Storages/StorageGenerateRandom.cpp @@ -205,7 +205,10 @@ ColumnPtr fillColumnWithRandomData( { auto column = ColumnUInt16::create(); column->getData().resize(limit); - fillBufferWithRandomData(reinterpret_cast(column->getData().data()), limit * sizeof(UInt16), rng); + + for (size_t i = 0; i < limit; ++i) + column->getData()[i] = rng() % (DATE_LUT_MAX_DAY_NUM + 1); /// Slow + return column; } case TypeIndex::UInt32: [[fallthrough]]; diff --git a/tests/queries/0_stateless/01125_generate_random_qoega.reference b/tests/queries/0_stateless/01125_generate_random_qoega.reference new file mode 100644 index 00000000000..1cb416a722b --- /dev/null +++ b/tests/queries/0_stateless/01125_generate_random_qoega.reference @@ -0,0 +1 @@ +100 4456446406473339606 diff --git a/tests/queries/0_stateless/01125_generate_random_qoega.sql b/tests/queries/0_stateless/01125_generate_random_qoega.sql new file mode 100644 index 00000000000..7fb586ad2b5 --- /dev/null +++ b/tests/queries/0_stateless/01125_generate_random_qoega.sql @@ -0,0 +1,5 @@ +DROP TABLE IF EXISTS mass_table_117; +CREATE TABLE mass_table_117 (`dt` Date, `site_id` Int32, `site_key` String) ENGINE = MergeTree(dt, (site_id, site_key, dt), 8192); +INSERT INTO mass_table_117 SELECT * FROM generateRandom('`dt` Date,`site_id` Int32,`site_key` String', 1, 10, 2) LIMIT 100; +SELECT count(), sum(cityHash64(*)) FROM mass_table_117; +DROP TABLE mass_table_117; From 4788eb3423a575dc23f207963bf22c79acac1088 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 01:00:03 +0300 Subject: [PATCH 148/208] Make the assertion in code consistent with the real partition expression --- src/Storages/MergeTree/MergeTreeDataWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Storages/MergeTree/MergeTreeDataWriter.cpp b/src/Storages/MergeTree/MergeTreeDataWriter.cpp index 34c615994f0..23a60ddab78 100644 --- a/src/Storages/MergeTree/MergeTreeDataWriter.cpp +++ b/src/Storages/MergeTree/MergeTreeDataWriter.cpp @@ -210,8 +210,8 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataWriter::writeTempPart(BlockWithPa const auto & date_lut = DateLUT::instance(); - DayNum min_month = date_lut.toFirstDayNumOfMonth(DayNum(min_date)); - DayNum max_month = date_lut.toFirstDayNumOfMonth(DayNum(max_date)); + auto min_month = date_lut.toNumYYYYMM(min_date); + auto max_month = date_lut.toNumYYYYMM(max_date); if (min_month != max_month) throw Exception("Logical error: part spans more than one month.", ErrorCodes::LOGICAL_ERROR); From d1eaa34cd9f24341fb3e9e96a09d38a5b894eb4b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 01:00:10 +0300 Subject: [PATCH 149/208] Added a test --- .../01126_month_partitioning_consistent_code.reference | 0 .../0_stateless/01126_month_partitioning_consistent_code.sql | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 tests/queries/0_stateless/01126_month_partitioning_consistent_code.reference create mode 100644 tests/queries/0_stateless/01126_month_partitioning_consistent_code.sql diff --git a/tests/queries/0_stateless/01126_month_partitioning_consistent_code.reference b/tests/queries/0_stateless/01126_month_partitioning_consistent_code.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01126_month_partitioning_consistent_code.sql b/tests/queries/0_stateless/01126_month_partitioning_consistent_code.sql new file mode 100644 index 00000000000..c9bfbbe5111 --- /dev/null +++ b/tests/queries/0_stateless/01126_month_partitioning_consistent_code.sql @@ -0,0 +1,4 @@ +DROP TABLE IF EXISTS mt; +CREATE TABLE mt (d Date, x UInt8) ENGINE = MergeTree(d, x, 8192); +INSERT INTO mt VALUES (52392, 1), (62677, 2); +DROP TABLE mt; From 860e9092f19b379c4dbb53174c513159507aced5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 01:25:41 +0300 Subject: [PATCH 150/208] Fixed another inconsistency in partition names --- base/common/DateLUTImpl.cpp | 16 ++++++++++++++-- base/common/DateLUTImpl.h | 2 +- src/Storages/MergeTree/MergeTreePartInfo.cpp | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/base/common/DateLUTImpl.cpp b/base/common/DateLUTImpl.cpp index d7ab0046992..a7ca21c984e 100644 --- a/base/common/DateLUTImpl.cpp +++ b/base/common/DateLUTImpl.cpp @@ -133,7 +133,10 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_) } /// Fill lookup table for years and months. - for (size_t day = 0; day < DATE_LUT_SIZE && lut[day].year <= DATE_LUT_MAX_YEAR; ++day) + size_t year_months_lut_index = 0; + size_t first_day_of_last_month = 0; + + for (size_t day = 0; day < DATE_LUT_SIZE; ++day) { const Values & values = lut[day]; @@ -141,7 +144,16 @@ DateLUTImpl::DateLUTImpl(const std::string & time_zone_) { if (values.month == 1) years_lut[values.year - DATE_LUT_MIN_YEAR] = day; - years_months_lut[(values.year - DATE_LUT_MIN_YEAR) * 12 + values.month - 1] = day; + + year_months_lut_index = (values.year - DATE_LUT_MIN_YEAR) * 12 + values.month - 1; + years_months_lut[year_months_lut_index] = day; + first_day_of_last_month = day; } } + + /// Fill the rest of lookup table with the same last month (2106-02-01). + for (; year_months_lut_index < DATE_LUT_YEARS * 12; ++year_months_lut_index) + { + years_months_lut[year_months_lut_index] = first_day_of_last_month; + } } diff --git a/base/common/DateLUTImpl.h b/base/common/DateLUTImpl.h index d9d27c56ee3..ec32d62bcad 100644 --- a/base/common/DateLUTImpl.h +++ b/base/common/DateLUTImpl.h @@ -12,7 +12,7 @@ /// Table size is bigger than DATE_LUT_MAX_DAY_NUM to fill all indices within UInt16 range: this allows to remove extra check. #define DATE_LUT_SIZE 0x10000 #define DATE_LUT_MIN_YEAR 1970 -#define DATE_LUT_MAX_YEAR 2105 /// Last supported year +#define DATE_LUT_MAX_YEAR 2106 /// Last supported year (incomplete) #define DATE_LUT_YEARS (1 + DATE_LUT_MAX_YEAR - DATE_LUT_MIN_YEAR) /// Number of years in lookup table #if defined(__PPC__) diff --git a/src/Storages/MergeTree/MergeTreePartInfo.cpp b/src/Storages/MergeTree/MergeTreePartInfo.cpp index 43bd9538e3e..d30f6470bb1 100644 --- a/src/Storages/MergeTree/MergeTreePartInfo.cpp +++ b/src/Storages/MergeTree/MergeTreePartInfo.cpp @@ -120,8 +120,8 @@ void MergeTreePartInfo::parseMinMaxDatesFromPartName(const String & part_name, D min_date = date_lut.YYYYMMDDToDayNum(min_yyyymmdd); max_date = date_lut.YYYYMMDDToDayNum(max_yyyymmdd); - DayNum min_month = date_lut.toFirstDayNumOfMonth(min_date); - DayNum max_month = date_lut.toFirstDayNumOfMonth(max_date); + auto min_month = date_lut.toNumYYYYMM(min_date); + auto max_month = date_lut.toNumYYYYMM(max_date); if (min_month != max_month) throw Exception("Part name " + part_name + " contains different months", ErrorCodes::BAD_DATA_PART_NAME); From a517111259af9a7a03d9e94045335d72d01286f3 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 01:30:10 +0300 Subject: [PATCH 151/208] Added one more test --- ...month_partitioning_consistency_select.reference | 4 ++++ ...01127_month_partitioning_consistency_select.sql | 14 ++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 tests/queries/0_stateless/01127_month_partitioning_consistency_select.reference create mode 100644 tests/queries/0_stateless/01127_month_partitioning_consistency_select.sql diff --git a/tests/queries/0_stateless/01127_month_partitioning_consistency_select.reference b/tests/queries/0_stateless/01127_month_partitioning_consistency_select.reference new file mode 100644 index 00000000000..1b08e7f2d6f --- /dev/null +++ b/tests/queries/0_stateless/01127_month_partitioning_consistency_select.reference @@ -0,0 +1,4 @@ +Q1 2106-02-07 Hello +Q2 0000-00-00 World +Q1 2106-02-07 Hello +Q2 0000-00-00 World diff --git a/tests/queries/0_stateless/01127_month_partitioning_consistency_select.sql b/tests/queries/0_stateless/01127_month_partitioning_consistency_select.sql new file mode 100644 index 00000000000..59edd0c37b8 --- /dev/null +++ b/tests/queries/0_stateless/01127_month_partitioning_consistency_select.sql @@ -0,0 +1,14 @@ +DROP TABLE IF EXISTS mt; +CREATE TABLE mt (d Date, x String) ENGINE = MergeTree(d, x, 8192); +INSERT INTO mt VALUES ('2106-02-07', 'Hello'), ('1970-01-01', 'World'); + +SELECT 'Q1', * FROM mt WHERE d = '2106-02-07'; +SELECT 'Q2', * FROM mt WHERE d = '1970-01-01'; + +DETACH TABLE mt; +ATTACH TABLE mt; + +SELECT 'Q1', * FROM mt WHERE d = '2106-02-07'; +SELECT 'Q2', * FROM mt WHERE d = '1970-01-01'; + +DROP TABLE mt; From 8ad89a82d4522ab84d32068ef3d8d9a063165d3b Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 02:08:32 +0300 Subject: [PATCH 152/208] Support Nested types in "generateRandom" --- src/Storages/StorageGenerateRandom.cpp | 28 +++++++++++++++---- .../01128_generate_random_nested.reference | 2 ++ .../01128_generate_random_nested.sql | 8 ++++++ 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 tests/queries/0_stateless/01128_generate_random_nested.reference create mode 100644 tests/queries/0_stateless/01128_generate_random_nested.sql diff --git a/src/Storages/StorageGenerateRandom.cpp b/src/Storages/StorageGenerateRandom.cpp index d0772254045..70b84c076b7 100644 --- a/src/Storages/StorageGenerateRandom.cpp +++ b/src/Storages/StorageGenerateRandom.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,12 @@ void fillBufferWithRandomData(char * __restrict data, size_t size, pcg64 & rng) ColumnPtr fillColumnWithRandomData( - const DataTypePtr type, UInt64 limit, UInt64 max_array_length, UInt64 max_string_length, pcg64 & rng, const Context & context) + const DataTypePtr type, + UInt64 limit, + UInt64 max_array_length, + UInt64 max_string_length, + pcg64 & rng, + const Context & context) { TypeIndex idx = type->getTypeId(); @@ -340,14 +346,24 @@ public: protected: Chunk generate() override { + /// To support Nested types, we will collect them to single Array of Tuple. + auto names_and_types = Nested::collect(block_header.getNamesAndTypesList()); + Columns columns; - columns.reserve(block_header.columns()); - DataTypes types = block_header.getDataTypes(); + columns.reserve(names_and_types.size()); - for (const auto & type : types) - columns.emplace_back(fillColumnWithRandomData(type, block_size, max_array_length, max_string_length, rng, context)); + Block compact_block; + for (const auto & elem : names_and_types) + { + compact_block.insert( + { + fillColumnWithRandomData(elem.type, block_size, max_array_length, max_string_length, rng, context), + elem.type, + elem.name + }); + } - return {std::move(columns), block_size}; + return {Nested::flatten(compact_block).getColumns(), block_size}; } private: diff --git a/tests/queries/0_stateless/01128_generate_random_nested.reference b/tests/queries/0_stateless/01128_generate_random_nested.reference new file mode 100644 index 00000000000..d9d2b251702 --- /dev/null +++ b/tests/queries/0_stateless/01128_generate_random_nested.reference @@ -0,0 +1,2 @@ +100 12366141706519416319 +109 2990700419202507835 diff --git a/tests/queries/0_stateless/01128_generate_random_nested.sql b/tests/queries/0_stateless/01128_generate_random_nested.sql new file mode 100644 index 00000000000..2af52e69893 --- /dev/null +++ b/tests/queries/0_stateless/01128_generate_random_nested.sql @@ -0,0 +1,8 @@ +DROP TABLE IF EXISTS mass_table_312; +CREATE TABLE mass_table_312 (d Date DEFAULT '2000-01-01', x UInt64, n Nested(a String, b String)) ENGINE = MergeTree(d, x, 1); +INSERT INTO mass_table_312 SELECT * FROM generateRandom('`d` Date,`x` UInt64,`n.a` Array(String),`n.b` Array(String)', 1, 10, 2) LIMIT 100; + +SELECT count(), sum(cityHash64(*)) FROM mass_table_312; +SELECT count(), sum(cityHash64(*)) FROM mass_table_312 ARRAY JOIN n; + +DROP TABLE mass_table_312; From 0cf882f4dfb09790e09635601b210c8e5814d0d0 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 02:20:49 +0300 Subject: [PATCH 153/208] Update test --- .../01087_table_function_generate.reference | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tests/queries/0_stateless/01087_table_function_generate.reference b/tests/queries/0_stateless/01087_table_function_generate.reference index 68238faee48..d7cc6b0a933 100644 --- a/tests/queries/0_stateless/01087_table_function_generate.reference +++ b/tests/queries/0_stateless/01087_table_function_generate.reference @@ -1,14 +1,14 @@ UInt64 Int64 UInt32 Int32 UInt16 Int16 UInt8 Int8 -2804162938822577320 -2776833771540858 3467776823 1163715250 23903 13655 137 -41 -7885388429666205427 -1363628932535403038 484159052 -308788249 56810 -22227 51 -41 -4357435422797280898 1355609803008819271 4126129912 -852056475 64304 -11401 139 86 -5935810273536892891 -804738887697332962 3109335413 -80126721 258 12889 18 88 -368066018677693974 -4927165984347126295 1015254922 2026080544 44305 21973 16 0 -8124171311239967992 -1179703908046100129 1720727300 -138469036 61343 10573 252 -32 -15657812979985370729 -5733276247123822513 3254757884 -500590428 45913 19153 105 -102 -18371568619324220532 -6793779541583578394 1686821450 -455892108 49050 -28603 248 80 -821735343441964030 3148260644406230976 256251035 -885069056 58858 -29361 58 61 -9558594037060121162 -2907172753635797124 4276198376 1947296644 26801 -13531 204 -66 +2804162938822577320 -2776833771540858 3467776823 1163715250 31161 -2916 220 -117 +7885388429666205427 -1363628932535403038 484159052 -308788249 43346 13638 143 -105 +4357435422797280898 1355609803008819271 4126129912 -852056475 34184 9166 49 33 +5935810273536892891 -804738887697332962 3109335413 -80126721 47877 -31421 186 -77 +368066018677693974 -4927165984347126295 1015254922 2026080544 46037 -29626 240 108 +8124171311239967992 -1179703908046100129 1720727300 -138469036 33028 -12819 138 16 +15657812979985370729 -5733276247123822513 3254757884 -500590428 3829 30527 3 -81 +18371568619324220532 -6793779541583578394 1686821450 -455892108 43475 2284 252 -90 +821735343441964030 3148260644406230976 256251035 -885069056 11643 11455 176 90 +9558594037060121162 -2907172753635797124 4276198376 1947296644 45922 26632 97 43 - Enum8(\'hello\' = 1, \'world\' = 5) hello @@ -47,16 +47,16 @@ h o - Date DateTime DateTime(\'Europe/Moscow\') -2106-02-07 2050-12-17 02:46:35 2096-02-16 22:18:22 -2106-02-07 2013-10-17 23:35:26 1976-01-24 12:52:48 -2039-08-16 1974-11-17 23:22:46 1980-03-04 21:02:50 -1997-04-11 1972-09-18 23:44:08 2040-07-10 14:46:42 -2103-11-03 2044-11-23 20:57:12 1970-10-09 02:30:14 -2066-11-19 2029-12-10 03:13:55 2106-01-30 21:52:44 -2064-08-14 2016-07-14 11:33:45 2096-12-12 00:40:50 -2046-09-13 2085-07-10 18:51:14 2096-01-15 16:31:33 -2008-03-16 2047-05-16 23:28:36 2103-02-11 16:44:39 -2000-07-07 2105-07-19 19:29:06 1980-01-02 05:18:22 +2077-09-17 1970-10-09 02:30:14 2074-08-12 11:31:27 +2005-11-19 2106-01-30 21:52:44 2097-05-25 07:54:35 +2007-02-24 2096-12-12 00:40:50 1988-08-10 11:16:31 +2019-06-30 2096-01-15 16:31:33 2063-10-20 08:48:17 +2039-01-16 2103-02-11 16:44:39 2036-10-09 04:29:10 +1994-11-03 1980-01-02 05:18:22 2055-12-23 12:33:52 +2083-08-20 2079-06-11 16:29:02 2000-12-05 17:46:24 +2030-06-25 2100-03-01 18:50:22 1993-03-25 01:19:12 +2087-03-16 2034-08-25 19:46:33 2045-12-10 16:47:40 +2006-04-30 2069-09-30 16:07:48 2084-08-26 03:33:12 - DateTime64(3) DateTime64(6) DateTime64(6, \'Europe/Moscow\') 1978-06-07 23:50:57.320 2013-08-28 10:21:54.010758 1991-08-25 16:23:26.140215 @@ -225,14 +225,14 @@ RL,{Xs\\tw [114] -84125.1554 ('2023-06-06 06:55:06.492','bf9ab359-ef9f-ad11-7e6c-160368b1e5ea') [124] -114719.5228 ('2010-11-11 22:57:23.722','c1046ffb-3415-cc3a-509a-e0005856d7d7') - -[] 1900051923 { -189530.5846 h -5.6279699579452485e47 ('1984-12-06','2028-08-17 06:05:01','2036-04-02 23:52:28.468','4b3d498c-dd44-95c1-5b75-921504ec5d8d') F743 -[-102,-118] 392272782 Eb -14818.0200 o -2.664492247169164e59 ('2082-12-26','2052-09-09 06:50:50','2088-04-21 05:07:08.245','aeb9c26e-0ee7-2b8e-802b-2a96319b8e60') CBF4 -[-71] 775049089 \N -158115.1178 w 4.1323844687113747e-305 ('2106-02-07','2090-07-31 16:45:26','2076-07-10 09:11:06.385','57c69bc6-dddd-0975-e932-a7b5173a1304') EB1D -[-28,100] 3675466147 { -146685.1749 h 3.6676044396877755e142 ('2017-10-25','2100-02-28 18:07:18','2055-10-14 06:36:20.056','14949dae-dfa8-a124-af83-887348b2f609') 6D88 -[-23] 2514120753 (`u, -119659.6174 w 1.3231258347475906e34 ('2106-02-07','2074-08-10 06:25:12','1976-12-04 18:31:55.745','86a9b3c1-4593-4d56-7762-3aa1dd22cbbf') AD43 -[11,-36] 3308237300 \N 171205.1896 \N 5.634708707075817e195 ('1974-10-31','1993-12-24 09:38:45','2038-07-15 05:22:51.805','63d999b8-8cca-e237-c4a4-4dd7d0096f65') 609E -[39] 1614362420 `4A8P 157144.0630 o -1.1843143253872814e-255 ('2106-02-07','2072-09-28 18:27:27','2073-07-10 12:19:58.146','6483f5c0-8733-364c-4fa0-9948d32e8903') A886 -[48,-120] 3848918261 1 Date: Sun, 5 Apr 2020 00:07:00 +0300 Subject: [PATCH 154/208] Add log_queries_min_type to filter which entries will be written to query_log Can be used to write into query_log only failed queries (i.e. on memory exceeded error), by using: set log_queries_min_type='EXCEPTION_WHILE_PROCESSING' --- docs/en/operations/settings/settings.md | 18 +++++++++++++++++ src/Core/Settings.h | 2 +- src/Core/SettingsCollection.cpp | 7 +++++++ src/Core/SettingsCollection.h | 10 ++++++++++ src/Interpreters/QueryLog.h | 9 ++------- src/Interpreters/executeQuery.cpp | 20 +++++++++---------- .../01231_log_queries_min_type.reference | 5 +++++ .../01231_log_queries_min_type.sql | 15 ++++++++++++++ 8 files changed, 68 insertions(+), 18 deletions(-) create mode 100644 tests/queries/0_stateless/01231_log_queries_min_type.reference create mode 100644 tests/queries/0_stateless/01231_log_queries_min_type.sql diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index 69c444ebaef..37b4c713f91 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -507,6 +507,24 @@ Example: log_queries=1 ``` +## log\_queries\_min\_type {#settings-log-queries-min-type} + +`query_log` minimal type to log. + +Possible values: +- `QUERY_START` (`=1`) +- `QUERY_FINISH` (`=2`) +- `EXCEPTION_BEFORE_START` (`=3`) +- `EXCEPTION_WHILE_PROCESSING` (`=4`) + +Default value: `QUERY_START`. + +Can be used to limit which entiries will goes to `query_log`, say you are interesting only in errors, then you can use `EXCEPTION_WHILE_PROCESSING`: + +``` text +log_queries_min_type='EXCEPTION_WHILE_PROCESSING' +``` + ## log\_query\_threads {#settings-log-query-threads} Setting up query threads logging. diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 8138af31d5f..725171d4a1b 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -149,7 +149,7 @@ struct Settings : public SettingsCollection M(SettingInt64, os_thread_priority, 0, "If non zero - set corresponding 'nice' value for query processing threads. Can be used to adjust query priority for OS scheduler.", 0) \ \ M(SettingBool, log_queries, 0, "Log requests and write the log to the system table.", 0) \ - \ + M(SettingLogQueriesType, log_queries_min_type, QueryLogElementType::QUERY_START, "query_log minimal type to log, possible values (from low to high): QUERY_START, QUERY_FINISH, EXCEPTION_BEFORE_START, EXCEPTION_WHILE_PROCESSING.", 0) \ M(SettingUInt64, log_queries_cut_to_length, 100000, "If query length is greater than specified threshold (in bytes), then cut query when writing to query log. Also limit length of printed query in ordinary text log.", 0) \ \ M(SettingDistributedProductMode, distributed_product_mode, DistributedProductMode::DENY, "How are distributed subqueries performed inside IN or JOIN sections?", IMPORTANT) \ diff --git a/src/Core/SettingsCollection.cpp b/src/Core/SettingsCollection.cpp index 6d879b27181..238ac1c3c62 100644 --- a/src/Core/SettingsCollection.cpp +++ b/src/Core/SettingsCollection.cpp @@ -542,6 +542,13 @@ IMPLEMENT_SETTING_ENUM(FormatSettings::DateTimeInputFormat, DATE_TIME_INPUT_FORM M(trace, "trace") IMPLEMENT_SETTING_ENUM(LogsLevel, LOGS_LEVEL_LIST_OF_NAMES, ErrorCodes::BAD_ARGUMENTS) +#define LOG_QUERIES_TYPE_LIST_OF_NAMES(M) \ + M(QUERY_START, "QUERY_START") \ + M(QUERY_FINISH, "QUERY_FINISH") \ + M(EXCEPTION_BEFORE_START, "EXCEPTION_BEFORE_START") \ + M(EXCEPTION_WHILE_PROCESSING, "EXCEPTION_WHILE_PROCESSING") +IMPLEMENT_SETTING_ENUM(QueryLogElementType, LOG_QUERIES_TYPE_LIST_OF_NAMES, ErrorCodes::BAD_ARGUMENTS) + namespace details { diff --git a/src/Core/SettingsCollection.h b/src/Core/SettingsCollection.h index da21412b7c1..d93772e86ed 100644 --- a/src/Core/SettingsCollection.h +++ b/src/Core/SettingsCollection.h @@ -298,6 +298,16 @@ enum class LogsLevel }; using SettingLogsLevel = SettingEnum; +// Make it signed for compatibility with DataTypeEnum8 +enum QueryLogElementType : int8_t +{ + QUERY_START = 1, + QUERY_FINISH = 2, + EXCEPTION_BEFORE_START = 3, + EXCEPTION_WHILE_PROCESSING = 4, +}; +using SettingLogQueriesType = SettingEnum; + enum class SettingsBinaryFormat { diff --git a/src/Interpreters/QueryLog.h b/src/Interpreters/QueryLog.h index 836b37095e9..ec14f5e97fb 100644 --- a/src/Interpreters/QueryLog.h +++ b/src/Interpreters/QueryLog.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace ProfileEvents @@ -22,13 +23,7 @@ namespace DB /// A struct which will be inserted as row into query_log table struct QueryLogElement { - enum Type : int8_t // Make it signed for compatibility with DataTypeEnum8 - { - QUERY_START = 1, - QUERY_FINISH = 2, - EXCEPTION_BEFORE_START = 3, - EXCEPTION_WHILE_PROCESSING = 4, - }; + using Type = QueryLogElementType; Type type = QUERY_START; diff --git a/src/Interpreters/executeQuery.cpp b/src/Interpreters/executeQuery.cpp index c9c66832f08..68bebb83619 100644 --- a/src/Interpreters/executeQuery.cpp +++ b/src/Interpreters/executeQuery.cpp @@ -157,7 +157,7 @@ static void onExceptionBeforeStart(const String & query_for_logging, Context & c /// Log the start of query execution into the table if necessary. QueryLogElement elem; - elem.type = QueryLogElement::EXCEPTION_BEFORE_START; + elem.type = QueryLogElementType::EXCEPTION_BEFORE_START; elem.event_time = current_time; elem.query_start_time = current_time; @@ -175,7 +175,7 @@ static void onExceptionBeforeStart(const String & query_for_logging, Context & c /// Update performance counters before logging to query_log CurrentThread::finalizePerformanceCounters(); - if (settings.log_queries) + if (settings.log_queries && elem.type >= settings.log_queries_min_type) if (auto query_log = context.getQueryLog()) query_log->add(elem); } @@ -400,7 +400,7 @@ static std::tuple executeQueryImpl( { QueryLogElement elem; - elem.type = QueryLogElement::QUERY_START; + elem.type = QueryLogElementType::QUERY_START; elem.event_time = current_time; elem.query_start_time = current_time; @@ -412,7 +412,7 @@ static std::tuple executeQueryImpl( bool log_queries = settings.log_queries && !internal; /// Log into system table start of query execution, if need. - if (log_queries) + if (log_queries && elem.type >= settings.log_queries_min_type) { if (settings.log_query_settings) elem.query_settings = std::make_shared(context.getSettingsRef()); @@ -422,7 +422,7 @@ static std::tuple executeQueryImpl( } /// Also make possible for caller to log successful query finish and exception during execution. - auto finish_callback = [elem, &context, log_queries] (IBlockInputStream * stream_in, IBlockOutputStream * stream_out) mutable + auto finish_callback = [elem, &context, log_queries, log_queries_min_type = settings.log_queries_min_type] (IBlockInputStream * stream_in, IBlockOutputStream * stream_out) mutable { QueryStatus * process_list_elem = context.getProcessListElement(); @@ -436,7 +436,7 @@ static std::tuple executeQueryImpl( double elapsed_seconds = info.elapsed_seconds; - elem.type = QueryLogElement::QUERY_FINISH; + elem.type = QueryLogElementType::QUERY_FINISH; elem.event_time = time(nullptr); elem.query_duration_ms = elapsed_seconds * 1000; @@ -484,19 +484,19 @@ static std::tuple executeQueryImpl( elem.thread_ids = std::move(info.thread_ids); elem.profile_counters = std::move(info.profile_counters); - if (log_queries) + if (log_queries && elem.type >= log_queries_min_type) { if (auto query_log = context.getQueryLog()) query_log->add(elem); } }; - auto exception_callback = [elem, &context, log_queries, quota(quota)] () mutable + auto exception_callback = [elem, &context, log_queries, log_queries_min_type = settings.log_queries_min_type, quota(quota)] () mutable { if (quota) quota->used(Quota::ERRORS, 1, /* check_exceeded = */ false); - elem.type = QueryLogElement::EXCEPTION_WHILE_PROCESSING; + elem.type = QueryLogElementType::EXCEPTION_WHILE_PROCESSING; elem.event_time = time(nullptr); elem.query_duration_ms = 1000 * (elem.event_time - elem.query_start_time); @@ -529,7 +529,7 @@ static std::tuple executeQueryImpl( logException(context, elem); /// In case of exception we log internal queries also - if (log_queries) + if (log_queries && elem.type >= log_queries_min_type) { if (auto query_log = context.getQueryLog()) query_log->add(elem); diff --git a/tests/queries/0_stateless/01231_log_queries_min_type.reference b/tests/queries/0_stateless/01231_log_queries_min_type.reference new file mode 100644 index 00000000000..a358d022033 --- /dev/null +++ b/tests/queries/0_stateless/01231_log_queries_min_type.reference @@ -0,0 +1,5 @@ +01231_log_queries_min_type/QUERY_START +2 +01231_log_queries_min_type/EXCEPTION_BEFORE_START +2 +3 diff --git a/tests/queries/0_stateless/01231_log_queries_min_type.sql b/tests/queries/0_stateless/01231_log_queries_min_type.sql new file mode 100644 index 00000000000..f2229c94a8a --- /dev/null +++ b/tests/queries/0_stateless/01231_log_queries_min_type.sql @@ -0,0 +1,15 @@ +set log_queries=1; + +select '01231_log_queries_min_type/QUERY_START'; +system flush logs; +select count() from system.query_log where query like '%01231_log_queries_min_type/%' and query not like '%system.query_log%' and event_date = today() and event_time >= now() - interval 1 minute; + +set log_queries_min_type='EXCEPTION_BEFORE_START'; +select '01231_log_queries_min_type/EXCEPTION_BEFORE_START'; +system flush logs; +select count() from system.query_log where query like '%01231_log_queries_min_type/%' and query not like '%system.query_log%' and event_date = today() and event_time >= now() - interval 1 minute; + +set log_queries_min_type='EXCEPTION_WHILE_PROCESSING'; +select '01231_log_queries_min_type/', max(number) from system.numbers limit 1e6 settings max_rows_to_read='100K'; -- { serverError 158; } +system flush logs; +select count() from system.query_log where query like '%01231_log_queries_min_type/%' and query not like '%system.query_log%' and event_date = today() and event_time >= now() - interval 1 minute; From c7eaaaf7fe1a340eeb20f5edfdd0f6d24aa40157 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 13 Apr 2020 04:33:05 +0300 Subject: [PATCH 155/208] Small refactoring of SystemLogs --- src/Interpreters/MetricLog.cpp | 7 +++ src/Interpreters/MetricLog.h | 2 + src/Interpreters/SystemLog.cpp | 30 +++++------ src/Interpreters/SystemLog.h | 96 +++++++++++++++++++++------------- 4 files changed, 84 insertions(+), 51 deletions(-) diff --git a/src/Interpreters/MetricLog.cpp b/src/Interpreters/MetricLog.cpp index 5622e0c65b0..bd898170705 100644 --- a/src/Interpreters/MetricLog.cpp +++ b/src/Interpreters/MetricLog.cpp @@ -70,6 +70,13 @@ void MetricLog::stopCollectMetric() } +void MetricLog::shutdown() +{ + stopCollectMetric(); + stopFlushThread(); +} + + inline UInt64 time_in_milliseconds(std::chrono::time_point timepoint) { return std::chrono::duration_cast(timepoint.time_since_epoch()).count(); diff --git a/src/Interpreters/MetricLog.h b/src/Interpreters/MetricLog.h index c55bad2c12f..a90ce923494 100644 --- a/src/Interpreters/MetricLog.h +++ b/src/Interpreters/MetricLog.h @@ -34,6 +34,8 @@ class MetricLog : public SystemLog using SystemLog::SystemLog; public: + void shutdown() override; + /// Launches a background thread to collect metrics with interval void startCollectMetric(size_t collect_interval_milliseconds_); diff --git a/src/Interpreters/SystemLog.cpp b/src/Interpreters/SystemLog.cpp index a78342f8b17..fc0f2f98125 100644 --- a/src/Interpreters/SystemLog.cpp +++ b/src/Interpreters/SystemLog.cpp @@ -83,6 +83,19 @@ SystemLogs::SystemLogs(Context & global_context, const Poco::Util::AbstractConfi size_t collect_interval_milliseconds = config.getUInt64("metric_log.collect_interval_milliseconds"); metric_log->startCollectMetric(collect_interval_milliseconds); } + + if (query_log) + logs.emplace_back(query_log.get()); + if (query_thread_log) + logs.emplace_back(query_thread_log.get()); + if (part_log) + logs.emplace_back(part_log.get()); + if (trace_log) + logs.emplace_back(trace_log.get()); + if (text_log) + logs.emplace_back(text_log.get()); + if (metric_log) + logs.emplace_back(metric_log.get()); } @@ -93,21 +106,8 @@ SystemLogs::~SystemLogs() void SystemLogs::shutdown() { - if (query_log) - query_log->shutdown(); - if (query_thread_log) - query_thread_log->shutdown(); - if (part_log) - part_log->shutdown(); - if (trace_log) - trace_log->shutdown(); - if (text_log) - text_log->shutdown(); - if (metric_log) - { - metric_log->stopCollectMetric(); - metric_log->shutdown(); - } + for (auto & log : logs) + log->shutdown(); } } diff --git a/src/Interpreters/SystemLog.h b/src/Interpreters/SystemLog.h index 87da342ae1f..7c8dc1606f7 100644 --- a/src/Interpreters/SystemLog.h +++ b/src/Interpreters/SystemLog.h @@ -2,6 +2,9 @@ #include #include +#include +#include + #include #include #include @@ -59,13 +62,20 @@ namespace ErrorCodes #define DBMS_SYSTEM_LOG_QUEUE_SIZE 1048576 + class Context; -class QueryLog; -class QueryThreadLog; -class PartLog; -class TextLog; -class TraceLog; -class MetricLog; + + +class ISystemLog +{ +public: + virtual String getName() = 0; + virtual ASTPtr getCreateTableQuery() = 0; + virtual void flush() = 0; + virtual void shutdown() = 0; + virtual ~ISystemLog() = default; +}; + /// System logs should be destroyed in destructor of the last Context and before tables, /// because SystemLog destruction makes insert query while flushing data into underlying tables @@ -82,11 +92,13 @@ struct SystemLogs std::shared_ptr trace_log; /// Used to log traces from query profiler std::shared_ptr text_log; /// Used to log all text messages. std::shared_ptr metric_log; /// Used to log all metrics. + + std::vector logs; }; template -class SystemLog : private boost::noncopyable +class SystemLog : public ISystemLog, private boost::noncopyable { public: using Self = SystemLog; @@ -106,18 +118,28 @@ public: const String & storage_def_, size_t flush_interval_milliseconds_); - ~SystemLog(); - /** Append a record into log. * Writing to table will be done asynchronously and in case of failure, record could be lost. */ void add(const LogElement & element); + void stopFlushThread(); + /// Flush data in the buffer to disk - void flush(); + void flush() override; /// Stop the background flush thread before destructor. No more data will be written. - void shutdown(); + void shutdown() override + { + stopFlushThread(); + } + + String getName() override + { + return LogElement::name(); + } + + ASTPtr getCreateTableQuery() override; protected: Logger * log; @@ -250,7 +272,7 @@ void SystemLog::flush() template -void SystemLog::shutdown() +void SystemLog::stopFlushThread() { { std::unique_lock lock(mutex); @@ -270,13 +292,6 @@ void SystemLog::shutdown() } -template -SystemLog::~SystemLog() -{ - shutdown(); -} - - template void SystemLog::savingThreadFunction() { @@ -399,7 +414,7 @@ void SystemLog::prepareTable() rename->elements.emplace_back(elem); LOG_DEBUG(log, "Existing table " << description << " for system log has obsolete or different structure." - " Renaming it to " << backQuoteIfNeed(to.table)); + " Renaming it to " << backQuoteIfNeed(to.table)); InterpreterRenameQuery(rename, context).execute(); @@ -415,22 +430,7 @@ void SystemLog::prepareTable() /// Create the table. LOG_DEBUG(log, "Creating new table " << description << " for " + LogElement::name()); - auto create = std::make_shared(); - - create->database = table_id.database_name; - create->table = table_id.table_name; - - Block sample = LogElement::createBlock(); - - auto new_columns_list = std::make_shared(); - new_columns_list->set(new_columns_list->columns, InterpreterCreateQuery::formatColumns(sample.getNamesAndTypesList())); - create->set(create->columns_list, new_columns_list); - - ParserStorage storage_parser; - ASTPtr storage_ast = parseQuery( - storage_parser, storage_def.data(), storage_def.data() + storage_def.size(), - "Storage to create table for " + LogElement::name(), 0); - create->set(create->storage, storage_ast); + auto create = getCreateTableQuery(); InterpreterCreateQuery interpreter(create, context); interpreter.setInternal(true); @@ -442,4 +442,28 @@ void SystemLog::prepareTable() is_prepared = true; } + +template +ASTPtr SystemLog::getCreateTableQuery() +{ + auto create = std::make_shared(); + + create->database = table_id.database_name; + create->table = table_id.table_name; + + Block sample = LogElement::createBlock(); + + auto new_columns_list = std::make_shared(); + new_columns_list->set(new_columns_list->columns, InterpreterCreateQuery::formatColumns(sample.getNamesAndTypesList())); + create->set(create->columns_list, new_columns_list); + + ParserStorage storage_parser; + ASTPtr storage_ast = parseQuery( + storage_parser, storage_def.data(), storage_def.data() + storage_def.size(), + "Storage to create table for " + LogElement::name(), 0); + create->set(create->storage, storage_ast); + + return create; +} + } From df28eca407d069c6730d13a6d5c3a620f68c5304 Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev Date: Mon, 13 Apr 2020 01:03:44 +0300 Subject: [PATCH 156/208] Add test for communication between ClickHouse and Zookeeper over SSL --- tests/integration/helpers/cluster.py | 10 +- .../helpers/zookeeper-ssl-entrypoint.sh | 95 +++++++++++++++++++ .../configs/zookeeper_config_with_ssl.xml | 20 ++++ .../configs_secure/client.crt | 19 ++++ .../configs_secure/client.key | 28 ++++++ .../configs_secure/conf.d/remote_servers.xml | 17 ++++ .../configs_secure/conf.d/ssl_conf.xml | 16 ++++ .../integration/test_zookeeper_config/test.py | 54 ++++++++++- 8 files changed, 255 insertions(+), 4 deletions(-) create mode 100755 tests/integration/helpers/zookeeper-ssl-entrypoint.sh create mode 100644 tests/integration/test_zookeeper_config/configs/zookeeper_config_with_ssl.xml create mode 100644 tests/integration/test_zookeeper_config/configs_secure/client.crt create mode 100644 tests/integration/test_zookeeper_config/configs_secure/client.key create mode 100644 tests/integration/test_zookeeper_config/configs_secure/conf.d/remote_servers.xml create mode 100644 tests/integration/test_zookeeper_config/configs_secure/conf.d/ssl_conf.xml diff --git a/tests/integration/helpers/cluster.py b/tests/integration/helpers/cluster.py index 717fab11449..b5cae86dc2d 100644 --- a/tests/integration/helpers/cluster.py +++ b/tests/integration/helpers/cluster.py @@ -144,7 +144,8 @@ class ClickHouseCluster: with_odbc_drivers=False, with_postgres=False, with_hdfs=False, with_mongo=False, with_redis=False, with_minio=False, hostname=None, env_variables=None, image="yandex/clickhouse-integration-test", - stay_alive=False, ipv4_address=None, ipv6_address=None, with_installed_binary=False, tmpfs=None): + stay_alive=False, ipv4_address=None, ipv6_address=None, with_installed_binary=False, tmpfs=None, + zookeeper_docker_compose_path=None): """Add an instance to the cluster. name - the name of the instance directory and the value of the 'instance' macro in ClickHouse. @@ -179,10 +180,13 @@ class ClickHouseCluster: cmds = [] if with_zookeeper and not self.with_zookeeper: + if not zookeeper_docker_compose_path: + zookeeper_docker_compose_path = p.join(HELPERS_DIR, 'docker_compose_zookeeper.yml') + self.with_zookeeper = True - self.base_cmd.extend(['--file', p.join(HELPERS_DIR, 'docker_compose_zookeeper.yml')]) + self.base_cmd.extend(['--file', zookeeper_docker_compose_path]) self.base_zookeeper_cmd = ['docker-compose', '--project-directory', self.base_dir, '--project-name', - self.project_name, '--file', p.join(HELPERS_DIR, 'docker_compose_zookeeper.yml')] + self.project_name, '--file', zookeeper_docker_compose_path] cmds.append(self.base_zookeeper_cmd) if with_mysql and not self.with_mysql: diff --git a/tests/integration/helpers/zookeeper-ssl-entrypoint.sh b/tests/integration/helpers/zookeeper-ssl-entrypoint.sh new file mode 100755 index 00000000000..3ddb21881d6 --- /dev/null +++ b/tests/integration/helpers/zookeeper-ssl-entrypoint.sh @@ -0,0 +1,95 @@ +#!/bin/bash + +set -e + +export ZOO_SERVER_CNXN_FACTORY=org.apache.zookeeper.server.NettyServerCnxnFactory +export ZOO_SSL_KEYSTORE_LOCATION=/conf/certs/zookeeper.p12 +export ZOO_SSL_KEYSTORE_PASSWORD=password +export ZOO_SSL_TRUSTSTORE_LOCATION=/conf/certs/truststore.p12 +export ZOO_SSL_TRUSTSTORE_PASSWORD=password + + +# Allow the container to be started with `--user` +if [[ "$1" = 'zkServer.sh' && "$(id -u)" = '0' ]]; then + chown -R zookeeper "$ZOO_DATA_DIR" "$ZOO_DATA_LOG_DIR" "$ZOO_LOG_DIR" "$ZOO_CONF_DIR" + exec gosu zookeeper "$0" "$@" +fi + +# Generate the config only if it doesn't exist +if [[ ! -f "$ZOO_CONF_DIR/zoo.cfg" ]]; then + CONFIG="$ZOO_CONF_DIR/zoo.cfg" + { + echo "dataDir=$ZOO_DATA_DIR" + echo "dataLogDir=$ZOO_DATA_LOG_DIR" + + echo "tickTime=$ZOO_TICK_TIME" + echo "initLimit=$ZOO_INIT_LIMIT" + echo "syncLimit=$ZOO_SYNC_LIMIT" + + echo "autopurge.snapRetainCount=$ZOO_AUTOPURGE_SNAPRETAINCOUNT" + echo "autopurge.purgeInterval=$ZOO_AUTOPURGE_PURGEINTERVAL" + echo "maxClientCnxns=$ZOO_MAX_CLIENT_CNXNS" + echo "standaloneEnabled=$ZOO_STANDALONE_ENABLED" + echo "admin.enableServer=$ZOO_ADMINSERVER_ENABLED" + } >> "$CONFIG" + if [[ -z $ZOO_SERVERS ]]; then + ZOO_SERVERS="server.1=localhost:2888:3888;2181" + fi + + for server in $ZOO_SERVERS; do + echo "$server" >> "$CONFIG" + done + + if [[ -n $ZOO_4LW_COMMANDS_WHITELIST ]]; then + echo "4lw.commands.whitelist=$ZOO_4LW_COMMANDS_WHITELIST" >> "$CONFIG" + fi + + + if [[ -n $ZOO_SSL_QUORUM ]]; then + { + echo "sslQuorum=$ZOO_SSL_QUORUM" + echo "serverCnxnFactory=$ZOO_SERVER_CNXN_FACTORY" + echo "ssl.quorum.keyStore.location=$ZOO_SSL_QUORUM_KEYSTORE_LOCATION" + echo "ssl.quorum.keyStore.password=$ZOO_SSL_QUORUM_KEYSTORE_PASSWORD" + echo "ssl.quorum.trustStore.location=$ZOO_SSL_QUORUM_TRUSTSTORE_LOCATION" + echo "ssl.quorum.trustStore.password=$ZOO_SSL_QUORUM_TRUSTSTORE_PASSWORD" + } >> "$CONFIG" + fi + + if [[ -n $ZOO_PORT_UNIFICATION ]]; then + echo "portUnification=$ZOO_PORT_UNIFICATION" >> "$CONFIG" + fi + + if [[ -n $ZOO_SECURE_CLIENT_PORT ]]; then + { + echo "secureClientPort=$ZOO_SECURE_CLIENT_PORT" + echo "serverCnxnFactory=$ZOO_SERVER_CNXN_FACTORY" + echo "ssl.keyStore.location=$ZOO_SSL_KEYSTORE_LOCATION" + echo "ssl.keyStore.password=$ZOO_SSL_KEYSTORE_PASSWORD" + echo "ssl.trustStore.location=$ZOO_SSL_TRUSTSTORE_LOCATION" + echo "ssl.trustStore.password=$ZOO_SSL_TRUSTSTORE_PASSWORD" + } >> "$CONFIG" + fi + + if [[ -n $ZOO_CLIENT_PORT_UNIFICATION ]]; then + echo "client.portUnification=$ZOO_CLIENT_PORT_UNIFICATION" >> "$CONFIG" + fi +fi + +# Write myid only if it doesn't exist +if [[ ! -f "$ZOO_DATA_DIR/myid" ]]; then + echo "${ZOO_MY_ID:-1}" > "$ZOO_DATA_DIR/myid" +fi + +mkdir -p $(dirname $ZOO_SSL_KEYSTORE_LOCATION) +mkdir -p $(dirname $ZOO_SSL_TRUSTSTORE_LOCATION) + +if [[ ! -f "$ZOO_SSL_KEYSTORE_LOCATION" ]]; then + keytool -genkeypair -alias zookeeper -keyalg RSA -validity 365 -keysize 2048 -dname "cn=zookeeper" -keypass password -keystore $ZOO_SSL_KEYSTORE_LOCATION -storepass password -deststoretype pkcs12 +fi + +if [[ ! -f "$ZOO_SSL_TRUSTSTORE_LOCATION" ]]; then + keytool -importcert -alias zookeeper -file /clickhouse-config/client.crt -keystore $ZOO_SSL_TRUSTSTORE_LOCATION -storepass password -noprompt -deststoretype pkcs12 +fi + +exec "$@" diff --git a/tests/integration/test_zookeeper_config/configs/zookeeper_config_with_ssl.xml b/tests/integration/test_zookeeper_config/configs/zookeeper_config_with_ssl.xml new file mode 100644 index 00000000000..fc03b609146 --- /dev/null +++ b/tests/integration/test_zookeeper_config/configs/zookeeper_config_with_ssl.xml @@ -0,0 +1,20 @@ + + + + zoo1 + 2281 + 1 + + + zoo2 + 2281 + 1 + + + zoo3 + 2281 + 1 + + 3000 + + diff --git a/tests/integration/test_zookeeper_config/configs_secure/client.crt b/tests/integration/test_zookeeper_config/configs_secure/client.crt new file mode 100644 index 00000000000..7ade2d96273 --- /dev/null +++ b/tests/integration/test_zookeeper_config/configs_secure/client.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIJANjx1QSR77HBMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAgFw0xODA3MzAxODE2MDhaGA8yMjkyMDUxNDE4MTYwOFow +FDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAs9uSo6lJG8o8pw0fbVGVu0tPOljSWcVSXH9uiJBwlZLQnhN4SFSFohfI +4K8U1tBDTnxPLUo/V1K9yzoLiRDGMkwVj6+4+hE2udS2ePTQv5oaMeJ9wrs+5c9T +4pOtlq3pLAdm04ZMB1nbrEysceVudHRkQbGHzHp6VG29Fw7Ga6YpqyHQihRmEkTU +7UCYNA+Vk7aDPdMS/khweyTpXYZimaK9f0ECU3/VOeG3fH6Sp2X6FN4tUj/aFXEj +sRmU5G2TlYiSIUMF2JPdhSihfk1hJVALrHPTU38SOL+GyyBRWdNcrIwVwbpvsvPg +pryMSNxnpr0AK0dFhjwnupIv5hJIOQIDAQABo1AwTjAdBgNVHQ4EFgQUjPLb3uYC +kcamyZHK4/EV8jAP0wQwHwYDVR0jBBgwFoAUjPLb3uYCkcamyZHK4/EV8jAP0wQw +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAM/ocuDvfPus/KpMVD51j +4IdlU8R0vmnYLQ+ygzOAo7+hUWP5j0yvq4ILWNmQX6HNvUggCgFv9bjwDFhb/5Vr +85ieWfTd9+LTjrOzTw4avdGwpX9G+6jJJSSq15tw5ElOIFb/qNA9O4dBiu8vn03C +L/zRSXrARhSqTW5w/tZkUcSTT+M5h28+Lgn9ysx4Ff5vi44LJ1NnrbJbEAIYsAAD ++UA+4MBFKx1r6hHINULev8+lCfkpwIaeS8RL+op4fr6kQPxnULw8wT8gkuc8I4+L +P9gg/xDHB44T3ADGZ5Ib6O0DJaNiToO6rnoaaxs0KkotbvDWvRoxEytSbXKoYjYp +0g== +-----END CERTIFICATE----- diff --git a/tests/integration/test_zookeeper_config/configs_secure/client.key b/tests/integration/test_zookeeper_config/configs_secure/client.key new file mode 100644 index 00000000000..f0fb61ac443 --- /dev/null +++ b/tests/integration/test_zookeeper_config/configs_secure/client.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCz25KjqUkbyjyn +DR9tUZW7S086WNJZxVJcf26IkHCVktCeE3hIVIWiF8jgrxTW0ENOfE8tSj9XUr3L +OguJEMYyTBWPr7j6ETa51LZ49NC/mhox4n3Cuz7lz1Pik62WreksB2bThkwHWdus +TKxx5W50dGRBsYfMenpUbb0XDsZrpimrIdCKFGYSRNTtQJg0D5WTtoM90xL+SHB7 +JOldhmKZor1/QQJTf9U54bd8fpKnZfoU3i1SP9oVcSOxGZTkbZOViJIhQwXYk92F +KKF+TWElUAusc9NTfxI4v4bLIFFZ01ysjBXBum+y8+CmvIxI3GemvQArR0WGPCe6 +ki/mEkg5AgMBAAECggEATrbIBIxwDJOD2/BoUqWkDCY3dGevF8697vFuZKIiQ7PP +TX9j4vPq0DfsmDjHvAPFkTHiTQXzlroFik3LAp+uvhCCVzImmHq0IrwvZ9xtB43f +7Pkc5P6h1l3Ybo8HJ6zRIY3TuLtLxuPSuiOMTQSGRL0zq3SQ5DKuGwkz+kVjHXUN +MR2TECFwMHKQ5VLrC+7PMpsJYyOMlDAWhRfUalxC55xOXTpaN8TxNnwQ8K2ISVY5 +212Jz/a4hn4LdwxSz3Tiu95PN072K87HLWx3EdT6vW4Ge5P/A3y+smIuNAlanMnu +plHBRtpATLiTxZt/n6npyrfQVbYjSH7KWhB8hBHtaQKBgQDh9Cq1c/KtqDtE0Ccr +/r9tZNTUwBE6VP+3OJeKdEdtsfuxjOCkS1oAjgBJiSDOiWPh1DdoDeVZjPKq6pIu +Mq12OE3Doa8znfCXGbkSzEKOb2unKZMJxzrz99kXt40W5DtrqKPNb24CNqTiY8Aa +CjtcX+3weat82VRXvph6U8ltMwKBgQDLxjiQQzNoY7qvg7CwJCjf9qq8jmLK766g +1FHXopqS+dTxDLM8eJSRrpmxGWJvNeNc1uPhsKsKgotqAMdBUQTf7rSTbt4MyoH5 +bUcRLtr+0QTK9hDWMOOvleqNXha68vATkohWYfCueNsC60qD44o8RZAS6UNy3ENq +cM1cxqe84wKBgQDKkHutWnooJtajlTxY27O/nZKT/HA1bDgniMuKaz4R4Gr1PIez +on3YW3V0d0P7BP6PWRIm7bY79vkiMtLEKdiKUGWeyZdo3eHvhDb/3DCawtau8L2K +GZsHVp2//mS1Lfz7Qh8/L/NedqCQ+L4iWiPnZ3THjjwn3CoZ05ucpvrAMwKBgB54 +nay039MUVq44Owub3KDg+dcIU62U+cAC/9oG7qZbxYPmKkc4oL7IJSNecGHA5SbU +2268RFdl/gLz6tfRjbEOuOHzCjFPdvAdbysanpTMHLNc6FefJ+zxtgk9sJh0C4Jh +vxFrw9nTKKzfEl12gQ1SOaEaUIO0fEBGbe8ZpauRAoGAMAlGV+2/K4ebvAJKOVTa +dKAzQ+TD2SJmeR1HZmKDYddNqwtZlzg3v4ZhCk4eaUmGeC1Bdh8MDuB3QQvXz4Dr +vOIP4UVaOr+uM+7TgAgVnP4/K6IeJGzUDhX93pmpWhODfdu/oojEKVcpCojmEmS1 +KCBtmIrQLqzMpnBpLNuSY+Q= +-----END PRIVATE KEY----- diff --git a/tests/integration/test_zookeeper_config/configs_secure/conf.d/remote_servers.xml b/tests/integration/test_zookeeper_config/configs_secure/conf.d/remote_servers.xml new file mode 100644 index 00000000000..01865e33a85 --- /dev/null +++ b/tests/integration/test_zookeeper_config/configs_secure/conf.d/remote_servers.xml @@ -0,0 +1,17 @@ + + + + + + node1 + 9000 + + + + node2 + 9000 + + + + + diff --git a/tests/integration/test_zookeeper_config/configs_secure/conf.d/ssl_conf.xml b/tests/integration/test_zookeeper_config/configs_secure/conf.d/ssl_conf.xml new file mode 100644 index 00000000000..5e6f5f37624 --- /dev/null +++ b/tests/integration/test_zookeeper_config/configs_secure/conf.d/ssl_conf.xml @@ -0,0 +1,16 @@ + + + + /etc/clickhouse-server/client.crt + /etc/clickhouse-server/client.key + true + true + sslv2,sslv3 + true + none + + RejectCertificateHandler + + + + diff --git a/tests/integration/test_zookeeper_config/test.py b/tests/integration/test_zookeeper_config/test.py index d9323ae16f3..4be99c8711d 100644 --- a/tests/integration/test_zookeeper_config/test.py +++ b/tests/integration/test_zookeeper_config/test.py @@ -1,7 +1,11 @@ from __future__ import print_function from helpers.cluster import ClickHouseCluster +import helpers import pytest import time +from tempfile import NamedTemporaryFile +from os import path as p, unlink + def test_chroot_with_same_root(): @@ -100,10 +104,58 @@ def test_identity(): with pytest.raises(Exception): cluster_2.start(destroy_dirs=False) node2.query(''' - CREATE TABLE simple (date Date, id UInt32) + CREATE TABLE simple (date Date, id UInt32) ENGINE = ReplicatedMergeTree('/clickhouse/tables/0/simple', '1', date, id, 8192); ''') finally: cluster_1.shutdown() cluster_2.shutdown() + + +def test_secure_connection(): + # We need absolute path in zookeeper volumes. Generate it dynamically. + TEMPLATE = ''' + zoo{zoo_id}: + image: zookeeper:3.5.6 + restart: always + environment: + ZOO_TICK_TIME: 500 + ZOO_MY_ID: {zoo_id} + ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181 + ZOO_SECURE_CLIENT_PORT: 2281 + volumes: + - {helpers_dir}/zookeeper-ssl-entrypoint.sh:/zookeeper-ssl-entrypoint.sh + - {configs_dir}:/clickhouse-config + command: ["zkServer.sh", "start-foreground"] + entrypoint: /zookeeper-ssl-entrypoint.sh + ''' + configs_dir = p.abspath(p.join(p.dirname(__file__), 'configs_secure')) + helpers_dir = p.abspath(p.dirname(helpers.__file__)) + + cluster = ClickHouseCluster(__file__, zookeeper_config_path='configs/zookeeper_config_with_ssl.xml') + + docker_compose = NamedTemporaryFile(delete=False) + + docker_compose.write( + "version: '2.2'\nservices:\n" + + TEMPLATE.format(zoo_id=1, configs_dir=configs_dir, helpers_dir=helpers_dir) + + TEMPLATE.format(zoo_id=2, configs_dir=configs_dir, helpers_dir=helpers_dir) + + TEMPLATE.format(zoo_id=3, configs_dir=configs_dir, helpers_dir=helpers_dir) + ) + docker_compose.close() + + node1 = cluster.add_instance('node1', config_dir='configs_secure', with_zookeeper=True, + zookeeper_docker_compose_path=docker_compose.name) + node2 = cluster.add_instance('node2', config_dir='configs_secure', with_zookeeper=True, + zookeeper_docker_compose_path=docker_compose.name) + + try: + cluster.start() + + assert node1.query("SELECT count() FROM system.zookeeper WHERE path = '/'") == '2\n' + assert node2.query("SELECT count() FROM system.zookeeper WHERE path = '/'") == '2\n' + + finally: + cluster.shutdown() + unlink(docker_compose.name) From f7f020263344e3c5055a630441e0673bcbff3d42 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 13 Apr 2020 08:04:57 +0000 Subject: [PATCH 157/208] Bump nltk from 3.4.5 to 3.5 in /docs/tools Bumps [nltk](https://github.com/nltk/nltk) from 3.4.5 to 3.5. - [Release notes](https://github.com/nltk/nltk/releases) - [Changelog](https://github.com/nltk/nltk/blob/develop/ChangeLog) - [Commits](https://github.com/nltk/nltk/compare/3.4.5...3.5) Signed-off-by: dependabot-preview[bot] --- docs/tools/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tools/requirements.txt b/docs/tools/requirements.txt index 0e3e3c24b5f..228229ac30d 100644 --- a/docs/tools/requirements.txt +++ b/docs/tools/requirements.txt @@ -20,7 +20,7 @@ MarkupSafe==1.1.1 mkdocs==1.1 mkdocs-htmlproofer-plugin==0.0.3 mkdocs-macros-plugin==0.4.6 -nltk==3.4.5 +nltk==3.5 nose==1.3.7 protobuf==3.11.3 numpy==1.18.2 From f1fbd60442d6b101338f4c94e9ae7578ab9e1e08 Mon Sep 17 00:00:00 2001 From: Ilya Yatsishin <2159081+qoega@users.noreply.github.com> Date: Mon, 13 Apr 2020 11:16:20 +0300 Subject: [PATCH 158/208] Add instana --- 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 f7006ae15c8..a1494c23066 100644 --- a/docs/en/introduction/adopters.md +++ b/docs/en/introduction/adopters.md @@ -76,5 +76,6 @@ toc_title: Adopters | [ЦВТ](https://htc-cs.ru/) | Software Development | Metrics, Logging | — | — | [Blog Post, March 2019, in Russian](https://vc.ru/dev/62715-kak-my-stroili-monitoring-na-prometheus-clickhouse-i-elk) | | [МКБ](https://mkb.ru/) | Bank | Web-system monitoring | — | — | [Slides in Russian, September 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup28/mkb.pdf) | | [金数据](https://jinshuju.net) | BI Analytics | Main product | — | — | [Slides in Chinese, October 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup24/3.%20金数据数据架构调整方案Public.pdf) | +| [Instana](https://www.instana.com) | APM Platform | Main product | — | — | [Twitter post](https://twitter.com/mieldonkers/status/1248884119158882304) | [Original article](https://clickhouse.tech/docs/en/introduction/adopters/) From 29fc8f145b898e2f854935e039a70e0a3c0907a6 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 13 Apr 2020 11:50:14 +0300 Subject: [PATCH 159/208] Fix tests in debug. --- src/Processors/Sources/SourceFromInputStream.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Processors/Sources/SourceFromInputStream.cpp b/src/Processors/Sources/SourceFromInputStream.cpp index e7ca28f72b9..e34fbd359ae 100644 --- a/src/Processors/Sources/SourceFromInputStream.cpp +++ b/src/Processors/Sources/SourceFromInputStream.cpp @@ -176,6 +176,9 @@ Chunk SourceFromInputStream::generate() return {}; } + if (isCancelled()) + return {}; + #ifndef NDEBUG assertBlocksHaveEqualStructure(getPort().getHeader(), block, "SourceFromInputStream"); #endif From 9a9bedc8ccd7f1ded6c1a237b7452481887651f8 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 13 Apr 2020 12:02:50 +0300 Subject: [PATCH 160/208] Fix test for streams. --- .../Executors/TreeExecutorBlockInputStream.cpp | 14 ++++++++++++-- .../Executors/TreeExecutorBlockInputStream.h | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Processors/Executors/TreeExecutorBlockInputStream.cpp b/src/Processors/Executors/TreeExecutorBlockInputStream.cpp index 84fd97f4781..f797fee3ab5 100644 --- a/src/Processors/Executors/TreeExecutorBlockInputStream.cpp +++ b/src/Processors/Executors/TreeExecutorBlockInputStream.cpp @@ -164,7 +164,7 @@ void TreeExecutorBlockInputStream::execute(bool on_totals, bool on_extremes) } }; - while (!stack.empty()) + while (!stack.empty() && !is_cancelled) { IProcessor * node = stack.top(); @@ -295,7 +295,7 @@ void TreeExecutorBlockInputStream::initRowsBeforeLimit() Block TreeExecutorBlockInputStream::readImpl() { - while (true) + while (!is_cancelled) { if (input_port->isFinished()) { @@ -338,6 +338,8 @@ Block TreeExecutorBlockInputStream::readImpl() execute(false, false); } + + return {}; } void TreeExecutorBlockInputStream::setProgressCallback(const ProgressCallback & callback) @@ -373,4 +375,12 @@ void TreeExecutorBlockInputStream::addTotalRowsApprox(size_t value) sources_with_progress.front()->addTotalRowsApprox(value); } +void TreeExecutorBlockInputStream::cancel(bool kill) +{ + IBlockInputStream::cancel(kill); + + for (auto & processor : processors) + processor->cancel(); +} + } diff --git a/src/Processors/Executors/TreeExecutorBlockInputStream.h b/src/Processors/Executors/TreeExecutorBlockInputStream.h index dfe8e66ed09..d96492b3fb8 100644 --- a/src/Processors/Executors/TreeExecutorBlockInputStream.h +++ b/src/Processors/Executors/TreeExecutorBlockInputStream.h @@ -39,6 +39,8 @@ public: String getName() const override { return "TreeExecutor"; } Block getHeader() const override { return root->getOutputs().front().getHeader(); } + void cancel(bool kill) override; + /// This methods does not affect TreeExecutor as IBlockInputStream itself. /// They just passed to all SourceWithProgress processors. void setProgressCallback(const ProgressCallback & callback) final; From 91e9a543d49a3e82dc433fdd46d284689ffc23ad Mon Sep 17 00:00:00 2001 From: Ivan <5627721+abyss7@users.noreply.github.com> Date: Mon, 13 Apr 2020 14:20:13 +0300 Subject: [PATCH 161/208] Support new vXX-backported labels (#10231) --- utils/github/__main__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/utils/github/__main__.py b/utils/github/__main__.py index e05d27c03d6..401908298eb 100644 --- a/utils/github/__main__.py +++ b/utils/github/__main__.py @@ -129,6 +129,7 @@ if bad_commits and not args.login: # TODO: check backports. if need_backporting: re_vlabel = re.compile(r'^v\d+\.\d+$') + re_vlabel_backported = re.compile(r'^v\d+\.\d+-backported$') re_vlabel_conflicts = re.compile(r'^v\d+\.\d+-conflicts$') print('\nPull-requests need to be backported:') @@ -146,8 +147,8 @@ if need_backporting: # FIXME: compatibility logic - check for a manually set label, that indicates status 'backported'. # FIXME: O(n²) - no need to iterate all labels for every `stable` for label in github.get_labels(pull_request): - if re_vlabel.match(label['name']): - if f'v{stable[0]}' == label['name']: + if re_vlabel.match(label['name']) or re_vlabel_backported.match(label['name']): + if f'v{stable[0]}' == label['name'] or f'v{stable[0]}-backported' == label['name']: backport_labeled.add(stable[0]) if re_vlabel_conflicts.match(label['name']): if f'v{stable[0]}-conflicts' == label['name']: From 6bd80a357b221bf9888ae69a75e4b420a150cbda Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Mon, 13 Apr 2020 15:00:36 +0300 Subject: [PATCH 162/208] simplified backport script --- utils/simple-backport/backport.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index a0143108383..5cd23b9b541 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -7,8 +7,8 @@ merge_base=$(git merge-base origin/master "origin/$branch") # Make lists of PRs that were merged into each branch. Use first parent here, or else # we'll get weird things like seeing older master that was merged into a PR branch # that was then merged into master. -git log "$merge_base..origin/master" --first-parent --oneline > master-log.txt -git log "$merge_base..origin/$branch" --first-parent --oneline > "$branch-log.txt" +git log "$merge_base..origin/master" --first-parent > master-log.txt +git log "$merge_base..origin/$branch" --first-parent > "$branch-log.txt" # Search for PR numbers in commit messages. First variant is normal merge, and second # variant is squashed. @@ -89,11 +89,14 @@ do continue fi + # Find merge commit SHA for convenience + merge_sha="$(jq -r .merge_commit_sha "$file")" + url="https://github.com/ClickHouse/ClickHouse/pull/$pr" - printf "%s\t%s\t%s\t%s\n" "$action" "$pr" "$url" "$file" >> "$branch-report.tsv" + printf "%s\t%s\t%s\t%s\t%s\n" "$action" "$pr" "$url" "$file" "$merge_sha" >> "$branch-report.tsv" if [ "$action" == "backport" ] then - printf "%s\t%s\n" "$action" "$url" + printf "%s\t%s\t%s\n" "$action" "$url" "$merge_sha" fi done From 204a6b2b8c8203d17cf5203e0fa79c068b4a8d30 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Mon, 13 Apr 2020 15:42:15 +0300 Subject: [PATCH 163/208] simple backport script --- utils/simple-backport/backport.sh | 38 +++++-------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index 5cd23b9b541..06ec63d25ec 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -56,38 +56,12 @@ do action="backport" fi - # Next, check the tag. They might override the decision. - matched_labels=() - for label in $(jq -r .labels[].name "$file") - do - label_action="" - case "$label" in - pr-must-backport | "v$branch-must-backport") - label_action="backport" - ;; - pr-no-backport | "v$branch-no-backport") - label_action="no-backport" - ;; - "v$branch-conflicts") - label_action="conflict" - ;; - "v$branch" | "v$branch-backported") - label_action="done" - ;; - esac - if [ "$label_action" != "" ] - then - action="$label_action" - matched_labels+=("$label") - fi - done - - # Show an error if there are conflicting labels. - if [ ${#matched_labels[@]} -gt 1 ] - then - >&2 echo "PR #$pr has conflicting labels: ${matched_labels[*]}" - continue - fi + # Next, check the tag. They might override the decision. Checks are ordered by priority. + labels="$(jq -r .labels[].name "$file")" + if echo "$labels" | grep "pr-must-backport\|v$branch-must-backport" > /dev/null; then action="backport"; fi + if echo "$labels" | grep "v$branch-conflicts" > /dev/null; then action="conflict"; fi + if echo "$labels" | grep "pr-no-backport\|v$branch-no-backport" > /dev/null; then action="no-backport"; fi + if echo "$labels" | grep "v$branch\|v$branch-backported" > /dev/null; then action="done"; fi # Find merge commit SHA for convenience merge_sha="$(jq -r .merge_commit_sha "$file")" From 8be5a1f0a5ac176ff7c1c83d9979627b6bc335b9 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Mon, 13 Apr 2020 15:54:09 +0300 Subject: [PATCH 164/208] simple backport script --- utils/simple-backport/backport.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index 06ec63d25ec..7fbd34f0a08 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -58,10 +58,10 @@ do # Next, check the tag. They might override the decision. Checks are ordered by priority. labels="$(jq -r .labels[].name "$file")" - if echo "$labels" | grep "pr-must-backport\|v$branch-must-backport" > /dev/null; then action="backport"; fi - if echo "$labels" | grep "v$branch-conflicts" > /dev/null; then action="conflict"; fi - if echo "$labels" | grep "pr-no-backport\|v$branch-no-backport" > /dev/null; then action="no-backport"; fi - if echo "$labels" | grep "v$branch\|v$branch-backported" > /dev/null; then action="done"; fi + if echo "$labels" | grep -x "pr-must-backport\|v$branch-must-backport" > /dev/null; then action="backport"; fi + if echo "$labels" | grep -x "v$branch-conflicts" > /dev/null; then action="conflict"; fi + if echo "$labels" | grep -x "pr-no-backport\|v$branch-no-backport" > /dev/null; then action="no-backport"; fi + if echo "$labels" | grep -x "v$branch\|v$branch-backported" > /dev/null; then action="done"; fi # Find merge commit SHA for convenience merge_sha="$(jq -r .merge_commit_sha "$file")" From 9cc7d0f06aa917fc87219adfb3d6f9311e72f095 Mon Sep 17 00:00:00 2001 From: alesapin Date: Mon, 13 Apr 2020 17:34:01 +0300 Subject: [PATCH 165/208] Fix 'Cannot add column' error while creating range_hashed dictionary using DDL queries --- src/Storages/StorageDictionary.cpp | 16 ++++++++- ...01125_dict_ddl_cannot_add_column.reference | 3 ++ .../01125_dict_ddl_cannot_add_column.sql | 34 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.reference create mode 100644 tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.sql diff --git a/src/Storages/StorageDictionary.cpp b/src/Storages/StorageDictionary.cpp index 396e83cc293..86831593d54 100644 --- a/src/Storages/StorageDictionary.cpp +++ b/src/Storages/StorageDictionary.cpp @@ -75,16 +75,30 @@ NamesAndTypesList StorageDictionary::getNamesAndTypes(const DictionaryStructure if (dictionary_structure.id) dictionary_names_and_types.emplace_back(dictionary_structure.id->name, std::make_shared()); + + /// In old-style (XML) configuration we don't have this attributes in the + /// main attribute list, so we have to add them to columns list explicitly. + /// In the new configuration (DDL) we have them both in range_* nodes and + /// main attribute list, but for compatibility we add them before main + /// attributes list. if (dictionary_structure.range_min) dictionary_names_and_types.emplace_back(dictionary_structure.range_min->name, dictionary_structure.range_min->type); + if (dictionary_structure.range_max) dictionary_names_and_types.emplace_back(dictionary_structure.range_max->name, dictionary_structure.range_max->type); + if (dictionary_structure.key) + { for (const auto & attribute : *dictionary_structure.key) dictionary_names_and_types.emplace_back(attribute.name, attribute.type); + } for (const auto & attribute : dictionary_structure.attributes) - dictionary_names_and_types.emplace_back(attribute.name, attribute.type); + { + /// Some attributes can be already added (range_min and range_max) + if (!dictionary_names_and_types.contains(attribute.name)) + dictionary_names_and_types.emplace_back(attribute.name, attribute.type); + } return dictionary_names_and_types; } diff --git a/tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.reference b/tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.reference new file mode 100644 index 00000000000..1a9e5685a6a --- /dev/null +++ b/tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.reference @@ -0,0 +1,3 @@ +1 2019-01-05 2020-01-10 1 +date_table +somedict diff --git a/tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.sql b/tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.sql new file mode 100644 index 00000000000..3f87235bdf4 --- /dev/null +++ b/tests/queries/0_stateless/01125_dict_ddl_cannot_add_column.sql @@ -0,0 +1,34 @@ +DROP DATABASE IF EXISTS database_for_dict; + +CREATE DATABASE database_for_dict; + +use database_for_dict; + +CREATE TABLE date_table +( + id UInt32, + val String, + start Date, + end Date +) Engine = Memory(); + +INSERT INTO date_table VALUES(1, '1', toDate('2019-01-05'), toDate('2020-01-10')); + +CREATE DICTIONARY somedict +( + id UInt32, + val String, + start Date, + end Date +) +PRIMARY KEY id +SOURCE(CLICKHOUSE(HOST 'localhost' PORT 9000 USER 'default' TABLE 'date_table' DB 'database_for_dict')) +LAYOUT(RANGE_HASHED()) +RANGE (MIN start MAX end) +LIFETIME(MIN 300 MAX 360); + +SELECT * from somedict; + +SHOW TABLES; + +DROP DATABASE IF EXISTS database_for_dict; From e05e2c76283bbc0d34abfcb0e7bf8764ab79a065 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Mon, 13 Apr 2020 17:34:11 +0300 Subject: [PATCH 166/208] Fixed check for nondeterministic functions to handle lambdas correctly --- src/Interpreters/MutationsInterpreter.cpp | 42 ++++++++++++------- ...eterministic_functions_zookeeper.reference | 2 + ...th_nondeterministic_functions_zookeeper.sh | 6 +++ 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index df0267b9450..985fda3aac7 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -36,34 +36,44 @@ namespace ErrorCodes namespace { -struct FirstNonDeterministicFuncData +/// Helps to detect situations, where non-deterministic functions may be used in mutations of Replicated*MergeTree. +class FirstNonDeterministicFuncMatcher { - using TypeToVisit = ASTFunction; +public: + struct Data { + const Context & context; + std::optional nondeterministic_function_name; + }; - explicit FirstNonDeterministicFuncData(const Context & context_) - : context{context_} - {} - - const Context & context; - std::optional nondeterministic_function_name; - - void visit(ASTFunction & function, ASTPtr &) +public: + static bool needChildVisit(const ASTPtr & /*node*/, const ASTPtr & child) { - if (nondeterministic_function_name) + return child != nullptr; + } + + static void visit(const ASTPtr & node, Data & data) + { + if (data.nondeterministic_function_name) return; - const auto func = FunctionFactory::instance().get(function.name, context); - if (!func->isDeterministic()) - nondeterministic_function_name = func->getName(); + if (const auto * function = typeid_cast(node.get())) + { + if (function->name != "lambda") + { + const auto func = FunctionFactory::instance().get(function->name, data.context); + if (!func->isDeterministic()) + data.nondeterministic_function_name = func->getName(); + } + } } }; using FirstNonDeterministicFuncFinder = - InDepthNodeVisitor, true>; + InDepthNodeVisitor; std::optional findFirstNonDeterministicFuncName(const MutationCommand & command, const Context & context) { - FirstNonDeterministicFuncData finder_data(context); + FirstNonDeterministicFuncMatcher::Data finder_data{context}; switch (command.type) { diff --git a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference index f799e8ed8f0..6bf25043399 100644 --- a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference +++ b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.reference @@ -5,3 +5,5 @@ OK OK OK OK +OK +OK diff --git a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh index 9b190855adf..68cb5e0e760 100755 --- a/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh +++ b/tests/queries/0_stateless/01017_mutations_with_nondeterministic_functions_zookeeper.sh @@ -43,6 +43,12 @@ ${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 DELETE WHERE ignore(rand())" 2>&1 ${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 UPDATE y = y + rand() % 1 WHERE not ignore()" 2>&1 \ | fgrep -q "must use only deterministic functions" && echo 'OK' || echo 'FAIL' +${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 UPDATE y = x + arrayCount(x -> (x + y) % 2, range(y)) WHERE not ignore()" 2>&1 > /dev/null \ +&& echo 'OK' || echo 'FAIL' + +${CLICKHOUSE_CLIENT} --query "ALTER TABLE $R1 UPDATE y = x + arrayCount(x -> (rand() + x) % 2, range(y)) WHERE not ignore()" 2>&1 \ +| fgrep -q "must use only deterministic functions" && echo 'OK' || echo 'FAIL' + # For regular tables we do not enforce deterministic functions ${CLICKHOUSE_CLIENT} --query "ALTER TABLE $T1 DELETE WHERE rand() = 0" 2>&1 > /dev/null \ From eacc04fc5cfbdf5cdb8bce2c9d5e9d1040e5bb07 Mon Sep 17 00:00:00 2001 From: Nikolai Kochetov Date: Mon, 13 Apr 2020 19:33:15 +0300 Subject: [PATCH 167/208] Fix race after cancel of RemoteBlockInputStream. --- src/DataStreams/RemoteBlockInputStream.cpp | 13 +++++++++---- src/DataStreams/RemoteBlockInputStream.h | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/DataStreams/RemoteBlockInputStream.cpp b/src/DataStreams/RemoteBlockInputStream.cpp index 9d9f629d463..6be189503e9 100644 --- a/src/DataStreams/RemoteBlockInputStream.cpp +++ b/src/DataStreams/RemoteBlockInputStream.cpp @@ -359,12 +359,17 @@ void RemoteBlockInputStream::sendQuery() void RemoteBlockInputStream::tryCancel(const char * reason) { - bool old_val = false; - if (!was_cancelled.compare_exchange_strong(old_val, true, std::memory_order_seq_cst, std::memory_order_relaxed)) - return; + { + std::lock_guard guard(was_cancelled_mutex); + + if (was_cancelled) + return; + + was_cancelled = true; + multiplexed_connections->sendCancel(); + } LOG_TRACE(log, "(" << multiplexed_connections->dumpAddresses() << ") " << reason); - multiplexed_connections->sendCancel(); } bool RemoteBlockInputStream::isQueryPending() const diff --git a/src/DataStreams/RemoteBlockInputStream.h b/src/DataStreams/RemoteBlockInputStream.h index 783811f2521..66b1ebbb6c3 100644 --- a/src/DataStreams/RemoteBlockInputStream.h +++ b/src/DataStreams/RemoteBlockInputStream.h @@ -135,7 +135,8 @@ private: * - data size is already satisfactory (when using LIMIT, for example) * - an exception was thrown from client side */ - std::atomic was_cancelled { false }; + bool was_cancelled { false }; + std::mutex was_cancelled_mutex; /** An exception from replica was received. No need in receiving more packets or * requesting to cancel query execution From 0aa4c85602df716a3fa4cbda23b9866e26a22dcd Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Mon, 13 Apr 2020 20:04:17 +0300 Subject: [PATCH 168/208] Fixed style checker complaint --- src/Interpreters/MutationsInterpreter.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index 985fda3aac7..2d3c01292b8 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -40,7 +40,8 @@ namespace class FirstNonDeterministicFuncMatcher { public: - struct Data { + struct Data + { const Context & context; std::optional nondeterministic_function_name; }; @@ -68,8 +69,7 @@ public: } }; -using FirstNonDeterministicFuncFinder = - InDepthNodeVisitor; +using FirstNonDeterministicFuncFinder = InDepthNodeVisitor; std::optional findFirstNonDeterministicFuncName(const MutationCommand & command, const Context & context) { From 45e85724a61b6ea80f065245b84f0ecdfbc83f43 Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Mon, 13 Apr 2020 21:33:25 +0300 Subject: [PATCH 169/208] Update MutationsInterpreter.cpp --- src/Interpreters/MutationsInterpreter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index 2d3c01292b8..1682bc11f80 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -59,6 +59,9 @@ public: if (const auto * function = typeid_cast(node.get())) { + /// Lambda functions also may be non-deterministic. But we skip them for simplicity. + /// Replication will work correctly even if non-deterministic function is used, + /// it will select any of the results and discard other. if (function->name != "lambda") { const auto func = FunctionFactory::instance().get(function->name, data.context); From def6817ede8854d7c422429d2bbe9204c134ae25 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 13 Apr 2020 22:06:07 +0300 Subject: [PATCH 170/208] Update compare.sh --- docker/test/performance-comparison/compare.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/test/performance-comparison/compare.sh b/docker/test/performance-comparison/compare.sh index f89631522f4..bf48fe467ca 100755 --- a/docker/test/performance-comparison/compare.sh +++ b/docker/test/performance-comparison/compare.sh @@ -42,9 +42,11 @@ function configure rm db0/metadata/system/* -rf ||: # Make copies of the original db for both servers. Use hardlinks instead - # of copying. + # of copying. Be careful to remove preprocessed configs or it can lead to + # weird effects. rm -r left/db ||: rm -r right/db ||: + rm -r db0/preprocessed_configs ||: cp -al db0/ left/db/ cp -al db0/ right/db/ } From d480707c12133d9d3ad0708447f08bab4bc3f995 Mon Sep 17 00:00:00 2001 From: Alexander Kazakov Date: Mon, 13 Apr 2020 23:02:44 +0300 Subject: [PATCH 171/208] Fixed clang build + tweaked comment --- src/Interpreters/MutationsInterpreter.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Interpreters/MutationsInterpreter.cpp b/src/Interpreters/MutationsInterpreter.cpp index 1682bc11f80..b1b226b157f 100644 --- a/src/Interpreters/MutationsInterpreter.cpp +++ b/src/Interpreters/MutationsInterpreter.cpp @@ -59,9 +59,8 @@ public: if (const auto * function = typeid_cast(node.get())) { - /// Lambda functions also may be non-deterministic. But we skip them for simplicity. - /// Replication will work correctly even if non-deterministic function is used, - /// it will select any of the results and discard other. + /// Property of being deterministic for lambda expression is completely determined + /// by the contents of its definition, so we just proceed to it. if (function->name != "lambda") { const auto func = FunctionFactory::instance().get(function->name, data.context); @@ -76,7 +75,7 @@ using FirstNonDeterministicFuncFinder = InDepthNodeVisitor findFirstNonDeterministicFuncName(const MutationCommand & command, const Context & context) { - FirstNonDeterministicFuncMatcher::Data finder_data{context}; + FirstNonDeterministicFuncMatcher::Data finder_data{context, std::nullopt}; switch (command.type) { From 1d843df1f3bf2619f58679c9e42e1cb7ec1c4945 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov <36882414+akuzm@users.noreply.github.com> Date: Mon, 13 Apr 2020 23:43:23 +0300 Subject: [PATCH 172/208] Changelog for v20.3.5.21 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5301de8a23..2ab006bcdd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ ## ClickHouse release v20.3 +### ClickHouse release v20.3.5.21, 2020-03-27 + +#### Bug Fix + +* Fix 'Different expressions with the same alias' error when query has PREWHERE and WHERE on distributed table and `SET distributed_product_mode = 'local'`. [#9871](https://github.com/ClickHouse/ClickHouse/pull/9871) ([Artem Zuikov](https://github.com/4ertus2)). +* Fix mutations excessive memory consumption for tables with a composite primary key. This fixes [#9850](https://github.com/ClickHouse/ClickHouse/issues/9850). [#9860](https://github.com/ClickHouse/ClickHouse/pull/9860) ([alesapin](https://github.com/alesapin)). +* Fix 'COMMA to CROSS JOIN rewriter is not enabled or cannot rewrite query' error in case of subqueries with COMMA JOIN out of tables lists (i.e. in WHERE). Fixes [#9782](https://github.com/ClickHouse/ClickHouse/issues/9782). [#9830](https://github.com/ClickHouse/ClickHouse/pull/9830) ([Artem Zuikov](https://github.com/4ertus2)). +* Fix possible exception `Got 0 in totals chunk, expected 1` on client. It happened for queries with `JOIN` in case if right joined table had zero rows. Example: `select * from system.one t1 join system.one t2 on t1.dummy = t2.dummy limit 0 FORMAT TabSeparated;`. Fixes [#9777](https://github.com/ClickHouse/ClickHouse/issues/9777). [#9823](https://github.com/ClickHouse/ClickHouse/pull/9823) ([Nikolai Kochetov](https://github.com/KochetovNicolai)). +* Fix SIGSEGV with optimize_skip_unused_shards when type cannot be converted. [#9804](https://github.com/ClickHouse/ClickHouse/pull/9804) ([Azat Khuzhin](https://github.com/azat)). +* Fix broken `ALTER TABLE DELETE COLUMN` query for compact parts. [#9779](https://github.com/ClickHouse/ClickHouse/pull/9779) ([alesapin](https://github.com/alesapin)). +* Fix max_distributed_connections (w/ and w/o Processors). [#9673](https://github.com/ClickHouse/ClickHouse/pull/9673) ([Azat Khuzhin](https://github.com/azat)). +* Fixed a few cases when timezone of the function argument wasn't used properly. [#9574](https://github.com/ClickHouse/ClickHouse/pull/9574) ([Vasily Nemkov](https://github.com/Enmk)). + +#### Improvement + +* Remove order by stage from mutations because we read from a single ordered part in a single thread. Also add check that the order of rows in mutation is ordered in sorting key order and this order is not violated. [#9886](https://github.com/ClickHouse/ClickHouse/pull/9886) ([alesapin](https://github.com/alesapin)). + + ### ClickHouse release v20.3.4.10, 2020-03-20 #### Bug Fix From 29bb9f666565129587846f1507c9a4a5dad8a24e Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Tue, 14 Apr 2020 00:15:58 +0300 Subject: [PATCH 173/208] simple backport script --- utils/simple-backport/README.md | 44 ++++++++- utils/simple-backport/backport.sh | 16 +++- utils/simple-backport/changelog.sh | 69 ++++++++++++++ utils/simple-backport/format-changelog.py | 109 ++++++++++++++++++++++ 4 files changed, 229 insertions(+), 9 deletions(-) create mode 100755 utils/simple-backport/changelog.sh create mode 100755 utils/simple-backport/format-changelog.py diff --git a/utils/simple-backport/README.md b/utils/simple-backport/README.md index 13378f93989..c5a625ca0d1 100644 --- a/utils/simple-backport/README.md +++ b/utils/simple-backport/README.md @@ -52,22 +52,56 @@ $ cat 20.1-report.tsv | cut -f1 | sort | uniq -c | sort -rn 10 no-backport ``` - ### Как разметить пулреквест? -По умолчанию бекпортируются все пулреквесты, у которых в описании указана категория чейнжлога Bug fix. Если этого недостаточно, используйте теги: -* v20.1-backported -- этот пулреквест уже бекпортирован в ветку 20.1. На случай, если автоматически не определилось. +По умолчанию бекпортируются все пулреквесты, у которых в описании указана +категория чейнжлога Bug fix. Если этого недостаточно, используйте теги: * v20.1-no-backport -- в ветку 20.1 бекпортировать не нужно. * pr-no-backport -- ни в какие ветки бекпортировать не нужно. -* v20.1-conflicts -- при бекпорте в 20.1 произошёл конфликт. Такие пулреквесты скрипт пропускает, к ним можно потом вернуться. +* v20.1-conflicts -- при бекпорте в 20.1 произошёл конфликт. Такие пулреквесты + скрипт пропускает, к ним можно потом вернуться. * pr-must-backport -- нужно бекпортировать в поддерживаемые ветки. * v20.1-must-backport -- нужно бекпортировать в 20.1. +### Я бекпортировал, почему скрипт не видит? +* Сообщение коммита должно содержать текст backport/cherry-pick #12345, или + иметь вид стандартного гитхабовского мерж-коммита для ПР #12345. +* Коммит должен быть достижим по `git log --first-parent my-branch`. Возможно, + в ветке сделали pull с merge, от чего некоторые коммиты из ветки становятся +недоступны по `--first-parent`. + +В качестве обхода, добавьте в ветку пустой коммит с текстом вроде "backport +#12345 -- real backport commit is ". ### Я поправил пулреквест, почему скрипт не видит? -В процессе работы скрипт кеширует данные о пулреквестах в текущей папке, чтобы экономить квоту гитхаба. Удалите закешированные файлы, например, для всех реквестов, которые не помечены как пропущенные: +В процессе работы скрипт кеширует данные о пулреквестах в текущей папке, чтобы +экономить квоту гитхаба. Удалите закешированные файлы, например, для всех +реквестов, которые не помечены как пропущенные: ``` $ cat <ваша-ветка>-report.tsv | grep -v "^skip" | cut -f4 $ cat <ваша-ветка>-report.tsv | grep -v "^skip" | cut -f4 | xargs rm ``` +## Как сформировать change log +В этой же папке запустите: +``` +$ time GITHUB_TOKEN=... ./changelog.sh v20.3.4.10-stable v20.3.5.21-stable +9 PRs added between v20.3.4.10-stable and v20.3.5.21-stable. +### ClickHouse release v20.3.5.21-stable FIXME as compared to v20.3.4.10-stable +#### Bug Fix + +* Fix 'Different expressions with the same alias' error when query has PREWHERE + and WHERE on distributed table and `SET distributed_product_mode = 'local'`. +[#9871](https://github.com/ClickHouse/ClickHouse/pull/9871) ([Artem +Zuikov](https://github.com/4ertus2)). +... +``` + +Скрипт выведет changelog на экран, а также сохранит его в `./changelog.md`. +Скопируйте этот текст в большой changelog, проверьте и поправьте версию и дату +релиза, вычитайте сообщения. Если сообщения неправильные, обязательно исправьте +их на гитхабе -- это поможет при последующей генерации changelog для других +версий, содержащих этот пулреквест. Чтобы скрипт подтянул изменения с гитхаба, +удалите соответствующие файлы `./pr12345.json`. Если вы часто видите +неправильно оформленные пулреквесты, это повод подумать об улучшении проверки +Description check в CI. diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index 7fbd34f0a08..b19df885c9e 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -10,10 +10,13 @@ merge_base=$(git merge-base origin/master "origin/$branch") git log "$merge_base..origin/master" --first-parent > master-log.txt git log "$merge_base..origin/$branch" --first-parent > "$branch-log.txt" +# NOTE keep in sync with ./changelog.sh. # Search for PR numbers in commit messages. First variant is normal merge, and second -# variant is squashed. +# variant is squashed. Next are some backport message variants. find_prs=(sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p; - s/^.*(#\([[:digit:]]\+\))$/\1/p") + s/^.*(#\([[:digit:]]\+\))$/\1/p; + s/^.*back[- ]*port[ ]*#\([[:digit:]]\+\).*$/\1/Ip; + s/^.*cherry[- ]*pick[ ]*#\([[:digit:]]\+\).*$/\1/Ip") "${find_prs[@]}" master-log.txt | sort -rn > master-prs.txt "${find_prs[@]}" "$branch-log.txt" | sort -rn > "$branch-prs.txt" @@ -39,7 +42,7 @@ do rm "$file" break fi - sleep 0.5 + sleep 0.1 fi if ! [ "$pr" == "$(jq -r .number "$file")" ] @@ -61,7 +64,12 @@ do if echo "$labels" | grep -x "pr-must-backport\|v$branch-must-backport" > /dev/null; then action="backport"; fi if echo "$labels" | grep -x "v$branch-conflicts" > /dev/null; then action="conflict"; fi if echo "$labels" | grep -x "pr-no-backport\|v$branch-no-backport" > /dev/null; then action="no-backport"; fi - if echo "$labels" | grep -x "v$branch\|v$branch-backported" > /dev/null; then action="done"; fi + # FIXME Ignore "backported" labels for now. If we can't find the backport commit, + # this means that the changelog script also won't be able to. An alternative + # way to mark PR as backported is to add an empty commit with text like + # "backported #12345", so that it can be found between tags and put in proper + # place in changelog. + #if echo "$labels" | grep -x "v$branch\|v$branch-backported" > /dev/null; then action="done"; fi # Find merge commit SHA for convenience merge_sha="$(jq -r .merge_commit_sha "$file")" diff --git a/utils/simple-backport/changelog.sh b/utils/simple-backport/changelog.sh new file mode 100755 index 00000000000..43a0b2d46da --- /dev/null +++ b/utils/simple-backport/changelog.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +from="$1" +to="$2" + +git log "$from..$to" --first-parent > "changelog-log.txt" + +# NOTE keep in sync with ./backport.sh. +# Search for PR numbers in commit messages. First variant is normal merge, and second +# variant is squashed. Next are some backport message variants. +find_prs=(sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p; + s/^.*(#\([[:digit:]]\+\))$/\1/p; + s/^.*back[- ]*port[ ]*#\([[:digit:]]\+\).*$/\1/Ip; + s/^.*cherry[- ]*pick[ ]*#\([[:digit:]]\+\).*$/\1/Ip") + +"${find_prs[@]}" "changelog-log.txt" | sort -rn > "changelog-prs.txt" + + +echo "$(wc -l < "changelog-prs.txt") PRs added between $from and $to." + +function github_download() +{ + local url=${1} + local file=${2} + if ! [ -f "$file" ] + then + if ! curl -H "Authorization: token $GITHUB_TOKEN" \ + -sSf "$url" \ + > "$file" + then + >&2 echo "Failed to download '$url' to '$file'. Contents: '" + >&2 cat "$file" + >&2 echo "'." + rm "$file" + return 1 + fi + sleep 0.1 + fi +} + +for pr in $(cat "changelog-prs.txt") +do + # Download PR info from github. + file="pr$pr.json" + github_download "https://api.github.com/repos/ClickHouse/ClickHouse/pulls/$pr" "$file" || continue + + if ! [ "$pr" == "$(jq -r .number "$file")" ] + then + >&2 echo "Got wrong data for PR #$pr (please check and remove '$file')." + continue + fi + + # Download author info from github. + user_id=$(jq -r .user.id "$file") + user_file="user$user_id.json" + github_download "$(jq -r .user.url "$file")" "$user_file" || continue + + if ! [ "$user_id" == "$(jq -r .id "$user_file")" ] + then + >&2 echo "Got wrong data for user #$user_id (please check and remove '$user_file')." + continue + fi +done + +echo "### ClickHouse release $to FIXME as compared to $from +" > changelog.md +./format-changelog.py changelog-prs.txt >> changelog.md +cat changelog.md diff --git a/utils/simple-backport/format-changelog.py b/utils/simple-backport/format-changelog.py new file mode 100755 index 00000000000..0f379d5529f --- /dev/null +++ b/utils/simple-backport/format-changelog.py @@ -0,0 +1,109 @@ +#!/usr/bin/python3 + +import os +import sys +import itertools +import argparse +import json +import collections +import re + +parser = argparse.ArgumentParser(description='Format changelog for given PRs.') +parser.add_argument('file', metavar='FILE', type=argparse.FileType('r', encoding='utf-8'), nargs=1, default=sys.stdin, help='File with PR numbers, one per line.') +args = parser.parse_args() + +# This function mirrors the PR description checks in ClickhousePullRequestTrigger. +# Returns False if the PR should not be mentioned changelog. +def parse_one_pull_request(item): + description = item['body'] + # Don't skip empty lines because they delimit parts of description + lines = [line for line in map(lambda x: x.strip(), description.split('\n') if description else [])] + lines = [re.sub(r'\s+', ' ', l) for l in lines] + + category = '' + entry = '' + + if lines: + i = 0 + while i < len(lines): + if re.match(r'(?i).*category.*:$', lines[i]): + i += 1 + if i >= len(lines): + break + category = re.sub(r'^[-*\s]*', '', lines[i]) + i += 1 + elif re.match(r'(?i)^\**\s*(Short description|Change\s*log entry)', lines[i]): + i += 1 + # Can have one empty line between header and the entry itself. Filter it out. + if i < len(lines) and not lines[i]: + i += 1 + # All following lines until empty one are the changelog entry. + entry_lines = [] + while i < len(lines) and lines[i]: + entry_lines.append(lines[i]) + i += 1 + entry = ' '.join(entry_lines) + else: + i += 1 + + if not category: + # Shouldn't happen, because description check in CI should catch such PRs. + # Fall through, so that it shows up in output and the user can fix it. + category = "NO CL CATEGORY" + + # Filter out the PR categories that are not for changelog. + if re.match(r'(?i)doc|((non|in|not|un)[-\s]*significant)', category): + return False + + if not entry: + # Shouldn't happen, because description check in CI should catch such PRs. + category = "NO CL ENTRY" + entry = "NO CL ENTRY: '" + item['title'] + "'" + + entry = entry.strip() + if entry[-1] != '.': + entry += '.' + + item['entry'] = entry + item['category'] = category + + return True + + +category_to_pr = collections.defaultdict(lambda: []) +users = {} +for line in args.file[0]: + pr = json.loads(open(f'pr{line.strip()}.json').read()) + assert(pr['number']) + if not parse_one_pull_request(pr): + continue + + assert(pr['category']) + category_to_pr[pr['category']].append(pr) + user_id = pr['user']['id'] + users[user_id] = json.loads(open(f'user{user_id}.json').read()) + +def print_category(category): + print("#### " + category) + print() + for pr in category_to_pr[category]: + user = users[pr["user"]["id"]] + user_name = user["name"] if user["name"] else user["login"] + + # Substitute issue links + pr["entry"] = re.sub(r'#([0-9]{4,})', r'[#\1](https://github.com/ClickHouse/ClickHouse/issues/\1)', pr["entry"]) + + print(f'* {pr["entry"]} [#{pr["number"]}]({pr["html_url"]}) ([{user_name}]({user["html_url"]})).') + + print() + +# Print categories in preferred order +categories_preferred_order = ['Backward Incompatible Change', 'New Feature', 'Bug Fix', 'Improvement', 'Performance Improvement', 'Build/Testing/Packaging Improvement', 'Other'] +for category in categories_preferred_order: + if category in category_to_pr: + print_category(category) + category_to_pr.pop(category) + +# Print the rest of the categories +for category in category_to_pr: + print_category(category) From a7c5f622ea4f5fdb6776994492533590b4789ff0 Mon Sep 17 00:00:00 2001 From: Konstantin Lebedev Date: Mon, 13 Apr 2020 10:50:00 +0300 Subject: [PATCH 174/208] Add string_utils for tests/zookeeper_impl.cpp --- src/Common/ZooKeeper/tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Common/ZooKeeper/tests/CMakeLists.txt b/src/Common/ZooKeeper/tests/CMakeLists.txt index 06716e49918..45a48ddc7a9 100644 --- a/src/Common/ZooKeeper/tests/CMakeLists.txt +++ b/src/Common/ZooKeeper/tests/CMakeLists.txt @@ -2,7 +2,7 @@ add_executable(zkutil_test_commands zkutil_test_commands.cpp) target_link_libraries(zkutil_test_commands PRIVATE clickhouse_common_zookeeper) add_executable(zkutil_test_commands_new_lib zkutil_test_commands_new_lib.cpp) -target_link_libraries(zkutil_test_commands_new_lib PRIVATE clickhouse_common_zookeeper) +target_link_libraries(zkutil_test_commands_new_lib PRIVATE clickhouse_common_zookeeper string_utils) add_executable(zkutil_test_lock zkutil_test_lock.cpp) target_link_libraries(zkutil_test_lock PRIVATE clickhouse_common_zookeeper) From 7c6a0c27e775720c5e078a4c91e3ba3c0c9a4a7a Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Tue, 14 Apr 2020 01:05:05 +0300 Subject: [PATCH 175/208] simple backport script --- utils/simple-backport/backport.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index b19df885c9e..ade0b54f24d 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -15,8 +15,8 @@ git log "$merge_base..origin/$branch" --first-parent > "$branch-log.txt" # variant is squashed. Next are some backport message variants. find_prs=(sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p; s/^.*(#\([[:digit:]]\+\))$/\1/p; - s/^.*back[- ]*port[ ]*#\([[:digit:]]\+\).*$/\1/Ip; - s/^.*cherry[- ]*pick[ ]*#\([[:digit:]]\+\).*$/\1/Ip") + s/^.*back[- ]*port[ of]*#\([[:digit:]]\+\).*$/\1/Ip; + s/^.*cherry[- ]*pick[ of]*#\([[:digit:]]\+\).*$/\1/Ip") "${find_prs[@]}" master-log.txt | sort -rn > master-prs.txt "${find_prs[@]}" "$branch-log.txt" | sort -rn > "$branch-prs.txt" From 2c88e914d704ace3fb3ca503609c55bc0398ea39 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 14 Apr 2020 02:24:33 +0300 Subject: [PATCH 176/208] Update roadmap. Also revert digital degradation due to accidential changes with automatic scripts. --- docs/ru/extended_roadmap.md | 179 ++++++++++++++++++++++++------------ 1 file changed, 122 insertions(+), 57 deletions(-) diff --git a/docs/ru/extended_roadmap.md b/docs/ru/extended_roadmap.md index 1637b54311a..135a49ca8fb 100644 --- a/docs/ru/extended_roadmap.md +++ b/docs/ru/extended_roadmap.md @@ -39,18 +39,20 @@ Upd. Большая часть задачи реализована и добав Требует 1.3. Будет делать [Александр Сапин](https://github.com/alesapin). Ура, сделано. -### 1.5. ALTER RENAME COLUMN. {#alter-rename-column} +### 1.5. + ALTER RENAME COLUMN. {#alter-rename-column} [\#6861](https://github.com/ClickHouse/ClickHouse/issues/6861) Требует 1.3. Будет делать [Александр Сапин](https://github.com/alesapin). -### 1.6. Полиморфные куски данных. {#polimorfnye-kuski-dannykh} +### 1.6. + Полиморфные куски данных. {#polimorfnye-kuski-dannykh} -Компактные куски - Q1, куски в оперативке Q1/Q2. +Компактные куски - Q1, куски в оперативке Q1/Q2 - пункт 1.7. Компактные куски реализованы, ещё не включены по-умолчанию. Первым шагом включаем по-умолчанию для системных таблиц. +Upd. Включено для системных таблиц. + Делает [Антон Попов](https://github.com/CurtizJ), первый рабочий вариант в декабре. Пререквизит чтобы снизить сложность мелких INSERT, что в свою очередь нужно для 1.12, иначе задача 1.12 не сможет нормально работать. Особенно нужно для Яндекс.Облака. Данные в таблицах типа MergeTree в ClickHouse хранятся в виде набора независимых «кусков». Внутри куска, каждый столбец, а также индекс, хранится в отдельных файлах. Это сделано для возможности быстрых манипуляций со столбцами (пример - запрос ALTER DROP COLUMN). При вставке данных (INSERT), создаётся новый кусок. Для таблиц с большим количеством столбцов, запросы INSERT с маленьким количеством строк являются неэффективными, так как требуют создания большого количества файлов в файловой системе. Это является врождённой особенностью ClickHouse - одной из первой проблем, с которыми сталкиваются пользователи. Пользователям приходится буферизовывать данные и собирать их в более крупные пачки перед вставкой в ClickHouse. @@ -61,7 +63,7 @@ Upd. Большая часть задачи реализована и добав ### 1.7. Буферизация и WAL в MergeTree. {#buferizatsiia-i-wal-v-mergetree} -Требует 1.6. +Требует 1.6. Антон Попов. Задача взята в работу. Q2. ### 1.8. + Перенос между разделами по TTL. {#perenos-mezhdu-razdelami-po-ttl} @@ -74,7 +76,7 @@ Q1. Закоммичено, но есть технический долг, ко Будет делать Сорокин Николай, ВШЭ и Яндекс. -Сейчас пользователь может задать в таблице выражение, которое определяет, сколько времени хранятся данные. Обычно это выражение задаётся относительно значения столбца с датой - например: удалять данные через три месяца. https://clickhouse.tech/docs/ru/operations/table\_engines/mergetree/\#table\_engine-mergetree-ttl +Сейчас пользователь может задать в таблице выражение, которое определяет, сколько времени хранятся данные. Обычно это выражение задаётся относительно значения столбца с датой - например: удалять данные через три месяца. https://clickhouse.tech/docs/ru/operations/table_engines/mergetree/\#table_engine-mergetree-ttl Это может быть задано для всей таблицы (тогда строки целиком удаляются после указанного времени) или для отдельных столбцов (тогда данные столбца физически удаляются с диска, а строки в таблице остаются; при чтении значений столбца, они читаются как значения по-умолчанию). @@ -88,7 +90,7 @@ Q1. Закоммичено, но есть технический долг, ко А вот пункт 2 требуется продумать. Не очевидно даже, какой лучше использовать синтаксис для этого при создании таблицы. Но мы придумаем - сразу видно несколько вариантов. -Частный случай такой задачи уже есть в https://clickhouse.tech/docs/ru/operations/table\_engines/graphitemergetree/ Но это было сделано для конкретной задачи. А надо обобщить. +Частный случай такой задачи уже есть в https://clickhouse.tech/docs/ru/operations/table_engines/graphitemergetree/ Но это было сделано для конкретной задачи. А надо обобщить. ### 1.10. Пережатие старых данных в фоне. {#perezhatie-starykh-dannykh-v-fone} @@ -100,17 +102,15 @@ Q1. Закоммичено, но есть технический долг, ко Предлагается добавить в ClickHouse настройки по пережатию данных и фоновые потоки, выполняющие эту задачу. -### 1.11. Виртуальная файловая система. {#virtualnaia-failovaia-sistema} +### 1.11. + Виртуальная файловая система. {#virtualnaia-failovaia-sistema} -В процессе реализации, сейчас на VFS переведены Log, TinyLog, StripeLog, готовится MergeTree. +На VFS переведены Log, TinyLog, StripeLog, а также MergeTree, что доказывает состоятельность реализации. -Q2. - -Нужно для Яндекс.Облака. Делает Александр, Яндекс.Облако, а также Олег Ершов, ВШЭ и Яндекс. +Нужно для Яндекс.Облака. Делает Александр, Яндекс.Облако. ClickHouse использует для хранения данных локальную файловую систему. Существует сценарий работы, в котором размещение старых (архивных) данных было бы выгодно на удалённой файловой системе. Если файловая система POSIX совместимая, то это не составляет проблем: ClickHouse успешно работает с Ceph, GlusterFS, MooseFS. Также востребованным является сценарий использования S3 (из-за доступности в облаке) или HDFS (для интеграции с Hadoop). Но эти файловые системы не являются POSIX совместимыми. Хотя для них существуют FUSE драйверы, но скорость работы сильно страдает и поддержка неполная. -ClickHouse использует небольшое подмножество функций ФС, но в то же время, и некоторые специфические части: симлинки и хардлинки, O\_DIRECT. Предлагается выделить всё взаимодействие с файловой системой в отдельный интерфейс. +ClickHouse использует небольшое подмножество функций ФС, но в то же время, и некоторые специфические части: симлинки и хардлинки, O_DIRECT. Предлагается выделить всё взаимодействие с файловой системой в отдельный интерфейс. ### 1.12. Экспериментальная реализация VFS поверх S3 и HDFS. {#eksperimentalnaia-realizatsiia-vfs-poverkh-s3-i-hdfs} @@ -121,13 +121,15 @@ Q2. Upd. Олег будет делать только часть про HDFS. +Upd. Реализация поверх S3 является рабочей на уровне PoC. + ### 1.13. Ускорение запросов с FINAL. {#uskorenie-zaprosov-s-final} -Требует 2.1. Делает [Николай Кочетов](https://github.com/KochetovNicolai). Нужно для Яндекс.Метрики. +Требует 2.1. Делает [Николай Кочетов](https://github.com/KochetovNicolai). Нужно для Яндекс.Метрики. Q2. ### 1.14. Не писать столбцы, полностью состоящие из нулей. {#ne-pisat-stolbtsy-polnostiu-sostoiashchie-iz-nulei} -Антон Попов. Q1/Q2. +Антон Попов. Q2. В очереди. Простая задача, является небольшим пререквизитом для потенциальной поддержки полуструктурированных данных. ### 1.15. Возможность иметь разный первичный ключ в разных кусках. {#vozmozhnost-imet-raznyi-pervichnyi-kliuch-v-raznykh-kuskakh} @@ -146,6 +148,7 @@ Upd. Олег будет делать только часть про HDFS. Требует 1.3 и 1.6. Полная замена hard links на sym links, что будет лучше для 1.12. + ## 2. Крупные рефакторинги. {#krupnye-refaktoringi} Для обоснования необходимости смотрите ссылки в описании других задач. @@ -161,6 +164,8 @@ Upd. Включили по-умолчанию. Удаление старого Upd. Уже есть первый релиз, в котором это включено по-умолчанию. +Upd. Всё ещё ждём удаление старого кода, которое должно случиться после релиза 20.4. + ### 2.2. Инфраструктура событий/метрик/ограничений/квот/трассировки. {#infrastruktura-sobytiimetrikogranicheniikvottrassirovki} В очереди. https://gist.github.com/alexey-milovidov/d62d73222d83b9319dc519cbb13aeff6 @@ -193,6 +198,8 @@ Upd. Каталог БД вынесен из Context. Средний приоритет. Нужно для YQL. +Upd. В очереди. Иван Лежанкин. + ### 2.9. Логгировние в format-стиле. {#loggirovnie-v-format-stile} Делает [Иван Лежанкин](https://github.com/abyss7). Низкий приоритет. @@ -212,10 +219,14 @@ Upd. Каталог БД вынесен из Context. Задачу делает Алексей Миловидов. Прогресс 50% и разработка временно приостановлена. +Upd. Разработка всё ещё приостановлена. + ### 2.13. Каждая функция в отдельном файле. {#kazhdaia-funktsiia-v-otdelnom-faile} Задачу делает Алексей Миловидов. Прогресс 80%. Потребуется помощь других разработчиков. +Upd. Поползновения наблюдаются. + ### 2.14. Все функции с состоянием переделать на FunctionBuilder. {#vse-funktsii-s-sostoianiem-peredelat-na-functionbuilder} Долг [Николай Кочетов](https://github.com/KochetovNicolai). Сейчас код находится в переходном состоянии, что неприемлемо. @@ -224,13 +235,14 @@ Upd. Каталог БД вынесен из Context. Для нормализации работы materialized views поверх Merge, Distributed, Kafka. + ## 3. Документация. {#dokumentatsiia} Здесь задачи только по инфраструктуре документации. ### 3.1. Перенос документации по функциям в код. {#perenos-dokumentatsii-po-funktsiiam-v-kod} -Требует 2.12 и 2.13. Хотим в Q1/Q2, средний приоритет. +Требует 2.12 и 2.13. Хотим в Q2, средний приоритет. ### 3.2. Перенос однородных частей документации в код. {#perenos-odnorodnykh-chastei-dokumentatsii-v-kod} @@ -246,11 +258,12 @@ Upd. Иван Блинков сделал эту задачу путём зам Эту задачу сделает [Иван Блинков](https://github.com/blinkov/), до конца декабря 2019. Сделано. + ## 4. Сетевое взаимодействие. {#setevoe-vzaimodeistvie} ### 4.1. Уменьшение числа потоков при распределённых запросах. {#umenshenie-chisla-potokov-pri-raspredelionnykh-zaprosakh} -[Никита Лапков](https://github.com/laplab), весна 2020. Upd. Есть прототип. Upd. Он не работает. +Весна 2020. Upd. Есть прототип. Upd. Он не работает. Upd. Человек отказался от задачи, теперь сроки не определены. ### 4.2. Спекулятивное выполнение запросов на нескольких репликах. {#spekuliativnoe-vypolnenie-zaprosov-na-neskolkikh-replikakh} @@ -262,6 +275,8 @@ Upd. Иван Блинков сделал эту задачу путём зам Сейчас для распределённых запросов используется по потоку на соединение. Это позволяет хорошо распараллелить вычисления над полученными данными и утилизировать сеть, но становится сильно избыточным для больших кластеров. Для примера, создание 1000 потоков для чтения данных из 1000 серверов кластера - лишь расходует ресурсы и увеличивает время выполнения запроса. Вместо этого необходимо использовать количество потоков не большее количества процессорных ядер, и мультиплексировать в одном потоке общение с серверами. Реализация нетривиальна, так как мультиплексировать необходимо каждую стадию общения по сети, включая установку соединения и обмен handshake. +Upd. Сейчас обсуждается, как сделать другую задачу вместо этой. + ### 4.3. Ограничение числа одновременных скачиваний с реплик. {#ogranichenie-chisla-odnovremennykh-skachivanii-s-replik} Дмитрий Григорьев, ВШЭ. @@ -284,14 +299,16 @@ Upd. Иван Блинков сделал эту задачу путём зам Дмитрий Григорьев, ВШЭ. В очереди. Исправить проблему, что восстанавливающаяся реплика перестаёт мержить. Частично компенсируется 4.3. + ## 5. Операции. {#operatsii} -### 5.1. Разделение задач на более мелкие куски в clickhouse-copier. {#razdelenie-zadach-na-bolee-melkie-kuski-v-clickhouse-copier} +### 5.1. + Разделение задач на более мелкие куски в clickhouse-copier. {#razdelenie-zadach-na-bolee-melkie-kuski-v-clickhouse-copier} [\#9075](https://github.com/ClickHouse/ClickHouse/pull/9075) Q1. Нужно для Метрики, в очереди. Никита Михайлов. Upd. Задача на финальной стадии разработки. +Upd. Сделано. Эффективность работы под вопросом. Есть варианты, как сделать лучше. ### 5.2. Автонастройка лимита на оперативку и размера кэшей. {#avtonastroika-limita-na-operativku-i-razmera-keshei} @@ -305,6 +322,8 @@ Upd. Задача на финальной стадии разработки. Требует 7.5. Задачу хочет Метрика, Облако, БК, Маркет и Altinity. Первой LTS версией уже стала версия 19.14. Метрика, БК, Маркет, Altinity уже используют более свежие версии чем LTS. +Upd. Появилась вторая версия LTS - 20.3. + ## 6. Инструментирование. {#instrumentirovanie} @@ -321,7 +340,7 @@ Upd. Задача на финальной стадии разработки. ### 6.3. Учёт оперативки total расширить не только на запросы. {#uchiot-operativki-total-rasshirit-ne-tolko-na-zaprosy} -Исправление долгоживущей проблемы с дрифтом учёта оперативки. Нужна для Метрики и БК. Иван Лежанкин. Q1. +Исправление долгоживущей проблемы с дрифтом учёта оперативки. Нужна для Метрики и БК. Иван Лежанкин. Q1. Странно, как будто не сделано. ### 6.4. Поддержка perf events как метрик запроса. {#podderzhka-perf-events-kak-metrik-zaprosa} @@ -339,7 +358,7 @@ Upd. Задача на финальной стадии разработки. Сейчас есть стек трейс для почти всех, но не всех исключений. Требует 7.4. -### 6.7. + Таблица system.stack\_trace. {#tablitsa-system-stack-trace} +### 6.7. + Таблица system.stack_trace. {#tablitsa-system-stack-trace} Сравнительно простая задача, но только для опытных разработчиков. @@ -351,6 +370,7 @@ Upd. Задача на финальной стадии разработки. ### 6.10. Сбор общих системных метрик. {#sbor-obshchikh-sistemnykh-metrik} + ## 7. Сопровождение разработки. {#soprovozhdenie-razrabotki} ### 7.1. + ICU в submodules. {#icu-v-submodules} @@ -361,7 +381,7 @@ Upd. Задача на финальной стадии разработки. Сделал Алексей Миловидов. -### 7.3. Обновление Poco. {#obnovlenie-poco} +### 7.3. + Обновление Poco. {#obnovlenie-poco} Алексанр Кузьменков. @@ -383,13 +403,18 @@ Upd. Задача на финальной стадии разработки. Уже есть ASan, TSan, UBSan. Не хватает тестов под MSan. Они уже добавлены в CI, но не проходят. [Александр Кузьменков](https://github.com/akuzm) и [Александр Токмаков](https://github.com/tavplubix). -### 7.8. Добавить clang-tidy. {#dobavit-clang-tidy} +Upd. Задача всё ещё медленно тащится. + +### 7.8. + Добавить clang-tidy. {#dobavit-clang-tidy} Уже есть PVS-Studio. Мы очень довольны, но этого недостаточно. Upd. Алексей Миловидов. Добавлено некоторое множество проверок, но нужно рассмотреть все проверки подряд и добавить всё, что можно. +Upd. Рассмотрели все проверки подряд. -### 7.9. Проверки на стиль имён с помощью clang-tidy. {#proverki-na-stil-imion-s-pomoshchiu-clang-tidy} +### 7.9. + Проверки на стиль имён с помощью clang-tidy. {#proverki-na-stil-imion-s-pomoshchiu-clang-tidy} + +Сделано. Только в .cpp файлах и только для имён локальных переменных. Остальное слишком сложно. ### 7.10. Включение UBSan и MSan в интеграционных тестах. {#vkliuchenie-ubsan-i-msan-v-integratsionnykh-testakh} @@ -399,6 +424,8 @@ UBSan включен в функциональных тестах, но не в У нас мало unit тестов по сравнению с функциональными тестами и их использование не обязательно. Но они всё-равно важны и нет причин не запускать их под всеми видами sanitizers. +Илья Яцишин. + ### 7.12. Показывать тестовое покрытие нового кода в PR. {#pokazyvat-testovoe-pokrytie-novogo-koda-v-pr} Пока есть просто показ тестового покрытия всего кода. @@ -413,6 +440,8 @@ UBSan включен в функциональных тестах, но не в Подключение replxx вместо readline сделал Иван Лежанкин. +Есть технический долг с лицензиями файлов консорциума Unicode. + ### 7.14.1. Улучшение возможностей интерактивного режима clickhouse-client. {#uluchshenie-vozmozhnostei-interaktivnogo-rezhima-clickhouse-client} Тагир Кускаров, ВШЭ. @@ -476,7 +505,7 @@ https://github.com/ClickHouse/ClickHouse/issues/8027\#issuecomment-566670282 Проверили на настоящем сервере Huawei, а также в специальном Docker контейнере, который содержит внутри qemu-user-static. Также можно проверить на Cavium, на Raspberry Pi а также на твоём Android телефоне. -### 7.20. Автосборка для FreeBSD x86\_64. {#avtosborka-dlia-freebsd-x86-64} +### 7.20. Автосборка для FreeBSD x86_64. {#avtosborka-dlia-freebsd-x86-64} [Иван Лежанкин](https://github.com/abyss7). @@ -535,6 +564,8 @@ Fuzzing тестирование - это тестирование случай Также можно сделать функции с детерминированным генератором случайных чисел (аргументом передаётся seed) для воспроизводимости тестовых кейсов. Upd. Сергей Штыков сделал функцию `randomPrintableASCII`. +Upd. Илья Яцишин сделал табличную функцию `generateRandom`. +Upd. Эльдар Заитов добавляет OSS Fuzz. ### 7.24. Fuzzing лексера и парсера запросов; кодеков и форматов. {#fuzzing-leksera-i-parsera-zaprosov-kodekov-i-formatov} @@ -557,10 +588,12 @@ Upd. Сергей Штыков сделал функцию `randomPrintableASCII Нужно для CHYT и YQL. -UPD: Все патчи Максима отправлены в master. Задача взята в работу. +Upd: Все патчи Максима отправлены в master. Задача взята в работу. Upd: Задача в процессе реализации. Синхронизироваться будет master. Делает [Иван Лежанкин](https://github.com/abyss7) +Upd: Есть собирающийся прототип, но сборка как будто ещё не в trunk Аркадии. + ### 7.26. Побайтовая идентичность репозитория с Аркадией. {#pobaitovaia-identichnost-repozitoriia-s-arkadiei} Команда DevTools. Прогресс по задаче под вопросом. @@ -617,6 +650,7 @@ Upd: Задача в процессе реализации. Синхронизи Upd. Иван Блинков настроил CDN repo.clickhouse.tech, что решает проблему с доступностью зарубежом. Вопрос с operations, visibility пока актуален. + ## 8. Интеграция с внешними системами. {#integratsiia-s-vneshnimi-sistemami} ### 8.1. Поддержка ALTER MODIFY SETTING для Kafka. {#podderzhka-alter-modify-setting-dlia-kafka} @@ -629,11 +663,11 @@ Altinity. Никто не делает эту задачу. [Александр Кузьменков](https://github.com/akuzm). -### 8.3. Доработки globs (правильная поддержка диапазонов, уменьшение числа одновременных stream-ов). {#dorabotki-globs-pravilnaia-podderzhka-diapazonov-umenshenie-chisla-odnovremennykh-stream-ov} +### 8.3. + Доработки globs (правильная поддержка диапазонов, уменьшение числа одновременных stream-ов). {#dorabotki-globs-pravilnaia-podderzhka-diapazonov-umenshenie-chisla-odnovremennykh-stream-ov} [Ольга Хвостикова](https://github.com/stavrolia). -Уменьшение числа stream-ов сделано, а вот правильная поддержка диапазонов - нет. Будем надеяться на Q1/Q2. +Уменьшение числа stream-ов сделано, а вот правильная поддержка диапазонов - нет. Будем надеяться на Q1/Q2. Сделано. ### 8.4. Унификация File, HDFS, S3 под URL. {#unifikatsiia-file-hdfs-s3-pod-url} @@ -690,19 +724,21 @@ Andrew Onyshchuk. Есть pull request. Q1. Сделано. Павел Круглов, ВШЭ и Яндекс. Есть pull request. -### 8.16.2. Поддержка формата Thrift. {#podderzhka-formata-thrift} +### 8.16.2. - Поддержка формата Thrift. {#podderzhka-formata-thrift} -Павел Круглов, ВШЭ и Яндекс. +Павел Круглов, ВШЭ и Яндекс. Задача отменена. ### 8.16.3. Поддержка формата MsgPack. {#podderzhka-formata-msgpack} Павел Круглов, ВШЭ и Яндекс. Задача взята в работу. -### 8.16.4. Формат Regexp. {#format-regexp} +Upd. Почти готово - есть лишь небольшой технический долг. + +### 8.16.4. + Формат Regexp. {#format-regexp} Павел Круглов, ВШЭ и Яндекс. -Есть pull request. +Есть pull request. Готово. ### 8.17. ClickHouse как MySQL реплика. {#clickhouse-kak-mysql-replika} @@ -735,6 +771,7 @@ Maxim Fedotov, Wargaming + Yuri Baranov, Яндекс. Нужно для БК. Декабрь 2019. В декабре для БК сделан минимальный вариант этой задачи. Максимальный вариант, вроде, никому не нужен. +Upd. Всё ещё кажется, что задача не нужна. ### 8.22. Поддержка синтаксиса для переменных в стиле MySQL. {#podderzhka-sintaksisa-dlia-peremennykh-v-stile-mysql} @@ -746,6 +783,7 @@ Upd. Юрий Баранов работает в Google, там запрещен Желательно 2.15. + ## 9. Безопасность. {#bezopasnost} ### 9.1. + Ограничение на хосты в запросах ко внешним системам. {#ogranichenie-na-khosty-v-zaprosakh-ko-vneshnim-sistemam} @@ -761,7 +799,12 @@ ClickHouse предоставляет возможность обратитьс Вместо этого предлагается описывать необходимые данные в конфигурационном файле сервера или в отдельном сервисе и ссылаться на них по именам. ### 9.3. Поддержка TLS для ZooKeeper. {#podderzhka-tls-dlia-zookeeper} + [#10174](https://github.com/ClickHouse/ClickHouse/issues/10174) + +Есть pull request. + + ## 10. Внешние словари. {#vneshnie-slovari} ### 10.1. + Исправление зависания в библиотеке доступа к YT. {#ispravlenie-zavisaniia-v-biblioteke-dostupa-k-yt} @@ -777,6 +820,7 @@ ClickHouse предоставляет возможность обратитьс Нужно для БК и Метрики. Поиск причин - [Александр Сапин](https://github.com/alesapin). Дальшейшее исправление возможно на стороне YT. Upd. Одну причину устранили, но ещё что-то неизвестное осталось. +Upd. Нас заставляют переписать эту библиотеку с одного API на другое, так как старое внезапно устарело. Кажется, что переписывание случайно исправит все проблемы. ### 10.3. Возможность чтения данных из статических таблиц в YT словарях. {#vozmozhnost-chteniia-dannykh-iz-staticheskikh-tablits-v-yt-slovariakh} @@ -802,7 +846,7 @@ Upd. Одну причину устранили, но ещё что-то неи Артём Стрельцов, Николай Дегтеринский, Наталия Михненко, ВШЭ. -### 10.9. Уменьшение блокировок для cache словарей за счёт одновременных запросов одного и того же. {#umenshenie-blokirovok-dlia-cache-slovarei-za-schiot-odnovremennykh-zaprosov-odnogo-i-togo-zhe} +### 10.9. - Уменьшение блокировок для cache словарей за счёт одновременных запросов одного и того же. {#umenshenie-blokirovok-dlia-cache-slovarei-za-schiot-odnovremennykh-zaprosov-odnogo-i-togo-zhe} Заменено в пользу 10.10, 10.11. @@ -825,7 +869,7 @@ Upd. Одну причину устранили, но ещё что-то неи ### 10.14. Поддержка всех типов в функции transform. {#podderzhka-vsekh-tipov-v-funktsii-transform} -Задачу взяла Ольга Хвостикова. +Задачу взяла Ольга Хвостикова. Upd. Статус неизвестен. ### 10.15. Использование словарей как специализированного layout для Join. {#ispolzovanie-slovarei-kak-spetsializirovannogo-layout-dlia-join} @@ -843,6 +887,7 @@ Upd. Одну причину устранили, но ещё что-то неи ### 10.19. Возможность зарегистрировать некоторые функции, использующие словари, под пользовательскими именами. {#vozmozhnost-zaregistrirovat-nekotorye-funktsii-ispolzuiushchie-slovari-pod-polzovatelskimi-imenami} + ## 11. Интерфейсы. {#interfeisy} ### 11.1. Вставка состояний агрегатных функций в виде кортежа аргументов или массива кортежей аргументов. {#vstavka-sostoianii-agregatnykh-funktsii-v-vide-kortezha-argumentov-ili-massiva-kortezhei-argumentov} @@ -851,6 +896,8 @@ Upd. Одну причину устранили, но ещё что-то неи Нужно разобраться, как упаковывать Java в статический бинарник, возможно AppImage. Или предоставить максимально простую инструкцию по установке jdbc-bridge. Может быть будет заинтересован Александр Крашенинников, Badoo, так как он разработал jdbc-bridge. +Upd. Александр Крашенинников перешёл в другую компанию и больше не занимается этим. + ### 11.3. + Интеграционные тесты ODBC драйвера путём подключения ClickHouse к самому себе через ODBC. {#integratsionnye-testy-odbc-draivera-putiom-podkliucheniia-clickhouse-k-samomu-sebe-cherez-odbc} Михаил Филимонов, Altinity. Готово. @@ -881,12 +928,13 @@ zhang2014, есть pull request. Возможность описать в конфигурационном файле handler (путь в URL) для HTTP запросов к серверу, которому соответствует некоторый параметризованный запрос. Пользователь может вызвать этот обработчик и не должен передавать SQL запрос. + ## 12. Управление пользователями и доступом. {#upravlenie-polzovateliami-i-dostupom} -### 12.1. Role Based Access Control. {#role-based-access-control} +### 12.1. + Role Based Access Control. {#role-based-access-control} -[Виталий Баранов](https://github.com/vitlibar). Финальная стадия разработки, рабочая версия в начале февраля 2019. -Q1. Сейчас сделаны все интерфейсы в коде и запросы, но не сделаны варианты хранения прав кроме прототипа. +[Виталий Баранов](https://github.com/vitlibar). Финальная стадия разработки, рабочая версия в начале апреля 2019. +Q2. Сейчас сделаны все интерфейсы в коде и запросы, но не сделаны варианты хранения прав кроме прототипа. Upd. Сделано хранение прав. До готового к использованию состояния осталось несколько доработок. ### 12.2. + Управление пользователями и правами доступа с помощью SQL запросов. {#upravlenie-polzovateliami-i-pravami-dostupa-s-pomoshchiu-sql-zaprosov} @@ -897,7 +945,7 @@ Q1. Сделано управление правами полностью, но ### 12.3. Подключение справочника пользователей и прав доступа из LDAP. {#podkliuchenie-spravochnika-polzovatelei-i-prav-dostupa-iz-ldap} [Виталий Баранов](https://github.com/vitlibar). Требует 12.1. -Q1/Q2. +Q2. ### 12.4. Подключение IDM системы Яндекса как справочника пользователей и прав доступа. {#podkliuchenie-idm-sistemy-iandeksa-kak-spravochnika-polzovatelei-i-prav-dostupa} @@ -911,6 +959,7 @@ Q1/Q2. [Виталий Баранов](https://github.com/vitlibar). Требует 12.1. + ## 13. Разделение ресурсов, multi-tenancy. {#razdelenie-resursov-multi-tenancy} ### 13.1. Overcommit запросов по памяти и вытеснение. {#overcommit-zaprosov-po-pamiati-i-vytesnenie} @@ -926,6 +975,8 @@ Q1/Q2. Требует 13.2 или сможем сделать более неудобную реализацию раньше. Обсуждается вариант неудобной реализации. Пока средний приоритет, целимся на Q1/Q2. Вариант реализации выбрал Александр Казаков. +Upd. Не уследили, и задачу стали обсуждать менеджеры. + ## 14. Диалект SQL. {#dialekt-sql} @@ -936,8 +987,6 @@ Q1/Q2. ### 14.2. Поддержка WITH для подзапросов. {#podderzhka-with-dlia-podzaprosov} -Михаил Коротов. - ### 14.3. Поддержка подстановок для множеств в правой части IN. {#podderzhka-podstanovok-dlia-mnozhestv-v-pravoi-chasti-in} ### 14.4. Поддержка подстановок для идентификаторов (имён) в SQL запросе. {#podderzhka-podstanovok-dlia-identifikatorov-imion-v-sql-zaprose} @@ -993,7 +1042,7 @@ zhang2014 ### 14.16. Синонимы для функций из MySQL. {#sinonimy-dlia-funktsii-iz-mysql} -### 14.17. Ввести понятие stateful функций. {#vvesti-poniatie-stateful-funktsii} +### 14.17. + Ввести понятие stateful функций. {#vvesti-poniatie-stateful-funktsii} zhang2014. Для runningDifference, neighbour - их учёт в оптимизаторе запросов. @@ -1018,13 +1067,15 @@ zhang2014. Павел Потёмкин, ВШЭ. + ## 15. Улучшение поддержки JOIN. {#uluchshenie-podderzhki-join} -### 15.1. Доведение merge JOIN до продакшена. {#dovedenie-merge-join-do-prodakshena} +### 15.1. + Доведение merge JOIN до продакшена. {#dovedenie-merge-join-do-prodakshena} Артём Зуйков. Сейчас merge JOIN включается вручную опцией и всегда замедляет запросы. Хотим, чтобы он замедлял запросы только когда это неизбежно. Кстати, смысл merge JOIN появляется только совместно с 15.2 и 15.3. Q1. Сделали адаптивный вариант, но вроде он что-то всё-ещё замедляет. +Задача сделана, но всё работает слишком медленно. ### 15.1.1. Алгоритм two-level merge JOIN. {#algoritm-two-level-merge-join} @@ -1052,6 +1103,7 @@ Q1. Сделали адаптивный вариант, но вроде он ч Артём Зуйков. + ## 16. Типы данных и функции. {#tipy-dannykh-i-funktsii} ### 16.1. + DateTime64. {#datetime64} @@ -1073,6 +1125,7 @@ Upd. Секретного изменения в работе не будет, з ### 16.6. Функции нормализации и хэширования SQL запросов. {#funktsii-normalizatsii-i-kheshirovaniia-sql-zaprosov} + ## 17. Работа с географическими данными. {#rabota-s-geograficheskimi-dannymi} ### 17.1. Гео-словари для определения региона по координатам. {#geo-slovari-dlia-opredeleniia-regiona-po-koordinatam} @@ -1105,6 +1158,7 @@ Upd. Андрей сделал прототип более оптимально Сейчас функция тихо не работает в случае полигонов с самопересечениями, надо кидать исключение. + ## 18. Машинное обучение и статистика. {#mashinnoe-obuchenie-i-statistika} ### 18.1. Инкрементальная кластеризация данных. {#inkrementalnaia-klasterizatsiia-dannykh} @@ -1123,6 +1177,7 @@ Upd. Андрей сделал прототип более оптимально В очереди. Возможно, Александр Кожихов. У него сначала идёт задача 24.26. + ## 19. Улучшение работы кластера. {#uluchshenie-raboty-klastera} ### 19.1. Параллельные кворумные вставки без линеаризуемости. {#parallelnye-kvorumnye-vstavki-bez-linearizuemosti} @@ -1153,7 +1208,7 @@ Upd. Алексей сделал какой-то вариант, но борет Hold. Полезно для заказчиков внутри Яндекса, но есть риски. Эту задачу никто не будет делать. -### 19.4. internal\_replication = ‘auto’. {#internal-replication-auto} +### 19.4. internal_replication = ‘auto’. {#internal-replication-auto} ### 19.5. Реплицируемые базы данных. {#replitsiruemye-bazy-dannykh} @@ -1177,18 +1232,20 @@ Hold. Полезно для заказчиков внутри Яндекса, н Требует 1.6, 19.1, 19.6, 19.7, 19.8, 19.9. + ## 20. Мутации данных. {#mutatsii-dannykh} Пока все задачи по точечным UPDATE/DELETE имеют низкий приоритет, но ожидаем взять в работу в середине 2020. ### 20.1. Поддержка DELETE путём запоминания множества затронутых кусков и ключей. {#podderzhka-delete-putiom-zapominaniia-mnozhestva-zatronutykh-kuskov-i-kliuchei} -### 20.2. Поддержка DELETE путём преобразования множества ключей в множество row\_numbers на реплике, столбца флагов и индекса по диапазонам. {#podderzhka-delete-putiom-preobrazovaniia-mnozhestva-kliuchei-v-mnozhestvo-row-numbers-na-replike-stolbtsa-flagov-i-indeksa-po-diapazonam} +### 20.2. Поддержка DELETE путём преобразования множества ключей в множество row_numbers на реплике, столбца флагов и индекса по диапазонам. {#podderzhka-delete-putiom-preobrazovaniia-mnozhestva-kliuchei-v-mnozhestvo-row-numbers-na-replike-stolbtsa-flagov-i-indeksa-po-diapazonam} ### 20.3. Поддержка ленивых DELETE путём запоминания выражений и преобразования к множеству ключей в фоне. {#podderzhka-lenivykh-delete-putiom-zapominaniia-vyrazhenii-i-preobrazovaniia-k-mnozhestvu-kliuchei-v-fone} ### 20.4. Поддержка UPDATE с помощью преобразования в DELETE и вставок. {#podderzhka-update-s-pomoshchiu-preobrazovaniia-v-delete-i-vstavok} + ## 21. Оптимизации производительности. {#optimizatsii-proizvoditelnosti} ### 21.1. + Параллельный парсинг форматов. {#parallelnyi-parsing-formatov} @@ -1201,7 +1258,7 @@ Hold. Полезно для заказчиков внутри Яндекса, н После 21.1, предположительно Никита Михайлов. Задача сильно проще чем 21.1. -### 21.3. Исправление низкой производительности анализа индекса в случае большого множества в секции IN. {#ispravlenie-nizkoi-proizvoditelnosti-analiza-indeksa-v-sluchae-bolshogo-mnozhestva-v-sektsii-in} +### 21.3. + Исправление низкой производительности анализа индекса в случае большого множества в секции IN. {#ispravlenie-nizkoi-proizvoditelnosti-analiza-indeksa-v-sluchae-bolshogo-mnozhestva-v-sektsii-in} Нужно всем (Zen, БК, DataLens, TestEnv…). Антон Попов, Q1/Q2. @@ -1309,23 +1366,23 @@ Constraints позволяют задать выражение, истиннос В ClickHouse используется неоптимальный вариант top sort. Суть его в том, что из каждого блока достаётся top N записей, а затем, все блоки мержатся. Но доставание top N записей у каждого следующего блока бессмысленно, если мы знаем, что из них в глобальный top N войдёт меньше. Конечно нужно реализовать вариацию на тему priority queue (heap) с быстрым пропуском целых блоков, если ни одна строка не попадёт в накопленный top. -1. Рекурсивный вариант сортировки по кортежам. +2. Рекурсивный вариант сортировки по кортежам. Для сортировки по кортежам используется обычная сортировка с компаратором, который в цикле по элементам кортежа делает виртуальные вызовы `IColumn::compareAt`. Это неоптимально - как из-за короткого цикла по неизвестному в compile-time количеству элементов, так и из-за виртуальных вызовов. Чтобы обойтись без виртуальных вызовов, есть метод `IColumn::getPermutation`. Он используется в случае сортировки по одному столбцу. Есть вариант, что в случае сортировки по кортежу, что-то похожее тоже можно применить… например, сделать метод `updatePermutation`, принимающий аргументы offset и limit, и допереставляющий перестановку в диапазоне значений, в которых предыдущий столбец имел равные значения. -1. RadixSort для сортировки. +3. RadixSort для сортировки. Один наш знакомый начал делать задачу по попытке использования RadixSort для сортировки столбцов. Был сделан вариант indirect сортировки (для `getPermutation`), но не оптимизирован до конца - есть лишние ненужные перекладывания элементов. Для того, чтобы его оптимизировать, придётся добавить немного шаблонной магии (на последнем шаге что-то не копировать, вместо перекладывания индексов - складывать их в готовое место). Также этот человек добавил метод MSD Radix Sort для реализации radix partial sort. Но даже не проверил производительность. Наиболее содержательная часть задачи может состоять в применении Radix Sort для сортировки кортежей, расположенных в оперативке в виде Structure Of Arrays неизвестного в compile-time размера. Это может работать хуже, чем то, что описано в пункте 2… Но попробовать не помешает. -1. Three-way comparison sort. +4. Three-way comparison sort. Виртуальный метод `compareAt` возвращает -1, 0, 1. Но алгоритмы сортировки сравнениями обычно рассчитаны на `operator<` и не могут получить преимущества от three-way comparison. А можно ли написать так, чтобы преимущество было? -1. pdq partial sort +5. pdq partial sort -Хороший алгоритм сортировки сравнениями `pdqsort` не имеет варианта partial sort. Заметим, что на практике, почти все сортировки в запросах ClickHouse являются partial\_sort, так как `ORDER BY` почти всегда идёт с `LIMIT`. Кстати, Данила Кутенин уже попробовал это и показал, что в тривиальном случае преимущества нет. Но не очевидно, что нельзя сделать лучше. +Хороший алгоритм сортировки сравнениями `pdqsort` не имеет варианта partial sort. Заметим, что на практике, почти все сортировки в запросах ClickHouse являются partial_sort, так как `ORDER BY` почти всегда идёт с `LIMIT`. Кстати, Данила Кутенин уже попробовал это и показал, что в тривиальном случае преимущества нет. Но не очевидно, что нельзя сделать лучше. ### 21.20. Использование материализованных представлений для оптимизации запросов. {#ispolzovanie-materializovannykh-predstavlenii-dlia-optimizatsii-zaprosov} @@ -1344,6 +1401,7 @@ Constraints позволяют задать выражение, истиннос zhang2014. Есть pull request. + ## 22. Долги и недоделанные возможности. {#dolgi-i-nedodelannye-vozmozhnosti} ### 22.1. + Исправление неработающих таймаутов, если используется TLS. {#ispravlenie-nerabotaiushchikh-taimautov-esli-ispolzuetsia-tls} @@ -1362,6 +1420,7 @@ N.Vartolomei. Александр Казаков. Нужно для Яндекс.Метрики и Datalens. Задача постепенно тащится и исправлениями в соседних местах стала менее актуальна. В Q1 будет сделана или отменена с учётом 1.2. и 1.3. +Upd. Добавили таймауты. ### 22.5. + Исправление редких срабатываний TSan в stress тестах в CI. {#ispravlenie-redkikh-srabatyvanii-tsan-v-stress-testakh-v-ci} @@ -1470,18 +1529,19 @@ Altinity. [Александр Сапин](https://github.com/alesapin) + ## 23. Default Festival. {#default-festival} -### 23.1. + Включение minimalistic\_part\_header в ZooKeeper. {#vkliuchenie-minimalistic-part-header-v-zookeeper} +### 23.1. + Включение minimalistic_part_header в ZooKeeper. {#vkliuchenie-minimalistic-part-header-v-zookeeper} Сильно уменьшает объём данных в ZooKeeper. Уже год в продакшене в Яндекс.Метрике. Алексей Миловидов, ноябрь 2019. -### 23.2. Включение distributed\_aggregation\_memory\_efficient. {#vkliuchenie-distributed-aggregation-memory-efficient} +### 23.2. Включение distributed_aggregation_memory_efficient. {#vkliuchenie-distributed-aggregation-memory-efficient} Есть риски меньшей производительности лёгких запросов, хотя производительность тяжёлых запросов всегда увеличивается. -### 23.3. Включение min\_bytes\_to\_external\_sort и min\_bytes\_to\_external\_group\_by. {#vkliuchenie-min-bytes-to-external-sort-i-min-bytes-to-external-group-by} +### 23.3. Включение min_bytes_to_external_sort и min_bytes_to_external_group_by. {#vkliuchenie-min-bytes-to-external-sort-i-min-bytes-to-external-group-by} Желательно 5.2. и 13.1. @@ -1489,7 +1549,7 @@ Altinity. Есть гипотеза, что плохо работает на очень больших кластерах. -### 23.5. Включение compile\_expressions. {#vkliuchenie-compile-expressions} +### 23.5. Включение compile_expressions. {#vkliuchenie-compile-expressions} Требует 7.2. Задачу изначально на 99% сделал Денис Скоробогатов, ВШЭ и Яндекс. Остальной процент доделывал Алексей Миловидов, а затем [Александр Сапин](https://github.com/alesapin). @@ -1514,6 +1574,7 @@ Q1. [Николай Кочетов](https://github.com/KochetovNicolai). Возможность mlock бинарника сделал Олег Алексеенков [\#3553](https://github.com/ClickHouse/ClickHouse/pull/3553) . Поможет, когда на серверах кроме ClickHouse работает много посторонних программ (мы иногда называем их в шутку «треш-программами»). + ## 24. Экспериментальные задачи. {#eksperimentalnye-zadachi} ### 24.1. Веб-интерфейс для просмотра состояния кластера и профилирования запросов. {#veb-interfeis-dlia-prosmotra-sostoianiia-klastera-i-profilirovaniia-zaprosov} @@ -1553,7 +1614,7 @@ ClickHouse поддерживает LZ4 и ZSTD для сжатия данных Смотрите также 24.5. -1. Шифрование отдельных значений. +2. Шифрование отдельных значений. Для этого требуется реализовать функции шифрования и расшифрования, доступные из SQL. Для шифрования реализовать возможность добавления нужного количества случайных бит для исключения одинаковых зашифрованных значений на одинаковых данных. Это позволит реализовать возможность «забывания» данных без удаления строк таблицы: можно шифровать данные разных клиентов разными ключами, и для того, чтобы забыть данные одного клиента, потребуется всего лишь удалить ключ. ### 24.6. Userspace RAID. {#userspace-raid} @@ -1586,7 +1647,7 @@ RAID позволяет одновременно увеличить надёжн Дмитрий Ковальков, ВШЭ и Яндекс. -Подавляющее большинство кода ClickHouse написана для x86\_64 с набором инструкций до SSE 4.2 включительно. Лишь отдельные редкие функции поддерживают AVX/AVX2/AVX512 с динамической диспетчеризацией. +Подавляющее большинство кода ClickHouse написана для x86_64 с набором инструкций до SSE 4.2 включительно. Лишь отдельные редкие функции поддерживают AVX/AVX2/AVX512 с динамической диспетчеризацией. В первой части задачи, следует добавить в ClickHouse реализации некоторых примитивов, оптимизированные под более новый набор инструкций. Например, AVX2 реализацию генератора случайных чисел pcg: https://github.com/lemire/simdpcg @@ -1598,6 +1659,8 @@ RAID позволяет одновременно увеличить надёжн Продолжение 24.8. +Upd. Есть pull request. + ### 24.10. Поддержка типов half/bfloat16/unum. {#podderzhka-tipov-halfbfloat16unum} [\#7657](https://github.com/ClickHouse/ClickHouse/issues/7657) @@ -1633,6 +1696,7 @@ ClickHouse предоставляет достаточно богатый наб В компании nVidia сделали прототип offloading вычисления GROUP BY с некоторыми из агрегатных функций в ClickHouse и обещат предоставить исходники в публичный доступ для дальнейшего развития. Предлагается изучить этот прототип и расширить его применимость для более широкого сценария использования. В качестве альтернативы, предлагается изучить исходные коды системы `OmniSci` или `Alenka` или библиотеку `CUB` https://nvlabs.github.io/cub/ и применить некоторые из алгоритмов в ClickHouse. Upd. В компании nVidia выложили прототип, теперь нужна интеграция в систему сборки. +Upd. Интеграция в систему сборки - Иван Лежанкин. ### 24.13. Stream запросы. {#stream-zaprosy} @@ -1791,7 +1855,7 @@ Amos Bird, но его решение слишком громоздкое и п ### 25.10. Митапы в России и Беларуси: Москва x2 + митап для разработчиков или хакатон, Санкт-Петербург, Минск, Нижний Новгород, Екатеринбург, Новосибирск и/или Академгородок, Иннополис или Казань. {#mitapy-v-rossii-i-belarusi-moskva-x2-mitap-dlia-razrabotchikov-ili-khakaton-sankt-peterburg-minsk-nizhnii-novgorod-ekaterinburg-novosibirsk-iili-akademgorodok-innopolis-ili-kazan} -Екатерина - организация +Екатерина - организация. Upd. Проведено два онлайн митапа на русском. ### 25.11. Митапы зарубежные: восток США (Нью Йорк, возможно Raleigh), возможно северо-запад (Сиэтл), Китай (Пекин снова, возможно митап для разработчиков или хакатон), Лондон. {#mitapy-zarubezhnye-vostok-ssha-niu-iork-vozmozhno-raleigh-vozmozhno-severo-zapad-sietl-kitai-pekin-snova-vozmozhno-mitap-dlia-razrabotchikov-ili-khakaton-london} @@ -1807,7 +1871,8 @@ Amos Bird, но его решение слишком громоздкое и п ### 25.14. Конференции в России: все HighLoad, возможно CodeFest, DUMP или UWDC, возможно C++ Russia. {#konferentsii-v-rossii-vse-highload-vozmozhno-codefest-dump-ili-uwdc-vozmozhno-c-russia} -Алексей Миловидов и все подготовленные докладчики +Алексей Миловидов и все подготовленные докладчики. +Upd. Есть Saint HighLoad online. ### 25.15. Конференции зарубежные: Percona, DataOps, попытка попасть на более крупные. {#konferentsii-zarubezhnye-percona-dataops-popytka-popast-na-bolee-krupnye} @@ -1848,7 +1913,7 @@ Amos Bird, но его решение слишком громоздкое и п ### 25.22. On-site помощь с ClickHouse компаниям в дни рядом с мероприятиями. {#on-site-pomoshch-s-clickhouse-kompaniiam-v-dni-riadom-s-meropriiatiiami} -[Иван Блинков](https://github.com/blinkov/) - организация +[Иван Блинков](https://github.com/blinkov/) - организация. Проверил мероприятие для турецкой компании. ### 25.23. Новый мерч для ClickHouse. {#novyi-merch-dlia-clickhouse} From 9210a50c5c95f26203377f5b3327b4f735fe2709 Mon Sep 17 00:00:00 2001 From: Alexander Kuzmenkov Date: Tue, 14 Apr 2020 03:00:48 +0300 Subject: [PATCH 177/208] simple backport script --- utils/simple-backport/backport.sh | 4 ++-- utils/simple-backport/changelog.sh | 4 ++-- utils/simple-backport/format-changelog.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/utils/simple-backport/backport.sh b/utils/simple-backport/backport.sh index ade0b54f24d..7d05f6902d0 100755 --- a/utils/simple-backport/backport.sh +++ b/utils/simple-backport/backport.sh @@ -15,8 +15,8 @@ git log "$merge_base..origin/$branch" --first-parent > "$branch-log.txt" # variant is squashed. Next are some backport message variants. find_prs=(sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p; s/^.*(#\([[:digit:]]\+\))$/\1/p; - s/^.*back[- ]*port[ of]*#\([[:digit:]]\+\).*$/\1/Ip; - s/^.*cherry[- ]*pick[ of]*#\([[:digit:]]\+\).*$/\1/Ip") + s/^.*back[- ]*port[ed of]*#\([[:digit:]]\+\).*$/\1/Ip; + s/^.*cherry[- ]*pick[ed of]*#\([[:digit:]]\+\).*$/\1/Ip") "${find_prs[@]}" master-log.txt | sort -rn > master-prs.txt "${find_prs[@]}" "$branch-log.txt" | sort -rn > "$branch-prs.txt" diff --git a/utils/simple-backport/changelog.sh b/utils/simple-backport/changelog.sh index 43a0b2d46da..b2f95f22533 100755 --- a/utils/simple-backport/changelog.sh +++ b/utils/simple-backport/changelog.sh @@ -11,8 +11,8 @@ git log "$from..$to" --first-parent > "changelog-log.txt" # variant is squashed. Next are some backport message variants. find_prs=(sed -n "s/^.*Merge pull request #\([[:digit:]]\+\).*$/\1/p; s/^.*(#\([[:digit:]]\+\))$/\1/p; - s/^.*back[- ]*port[ ]*#\([[:digit:]]\+\).*$/\1/Ip; - s/^.*cherry[- ]*pick[ ]*#\([[:digit:]]\+\).*$/\1/Ip") + s/^.*back[- ]*port[ed of]*#\([[:digit:]]\+\).*$/\1/Ip; + s/^.*cherry[- ]*pick[ed of]*#\([[:digit:]]\+\).*$/\1/Ip") "${find_prs[@]}" "changelog-log.txt" | sort -rn > "changelog-prs.txt" diff --git a/utils/simple-backport/format-changelog.py b/utils/simple-backport/format-changelog.py index 0f379d5529f..d6f97b358ed 100755 --- a/utils/simple-backport/format-changelog.py +++ b/utils/simple-backport/format-changelog.py @@ -9,7 +9,7 @@ import collections import re parser = argparse.ArgumentParser(description='Format changelog for given PRs.') -parser.add_argument('file', metavar='FILE', type=argparse.FileType('r', encoding='utf-8'), nargs=1, default=sys.stdin, help='File with PR numbers, one per line.') +parser.add_argument('file', metavar='FILE', type=argparse.FileType('r', encoding='utf-8'), nargs='?', default=[sys.stdin], help='File with PR numbers, one per line.') args = parser.parse_args() # This function mirrors the PR description checks in ClickhousePullRequestTrigger. From b4499ca607c9d195ddd6e35846ca79438a2b614a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Tue, 14 Apr 2020 05:08:14 +0300 Subject: [PATCH 178/208] Fix ugly typo --- website/templates/index/scalable.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/templates/index/scalable.html b/website/templates/index/scalable.html index fb86091ff06..672a02f202b 100644 --- a/website/templates/index/scalable.html +++ b/website/templates/index/scalable.html @@ -2,7 +2,7 @@
-

Linerarly scalable

+

Linearly scalable

ClickHouse scales well both vertically and horizontally. ClickHouse is easily adaptable to perform either on a cluster with hundreds or thousands of nodes or on a single server or even on a tiny virtual machine. Currently, there are installations with more multiple trillion rows or hundreds of terabytes of data per single node.

There are many ClickHouse clusters consisting of multiple hundred nodes, including few clusters of Yandex Metrica, while the largest known ClickHouse cluster is well over a thousand nodes. From 8e10a5504a5a98df1f8b4870619183e6e2905a56 Mon Sep 17 00:00:00 2001 From: zvrr Date: Tue, 14 Apr 2020 12:21:46 +0800 Subject: [PATCH 179/208] Update settings.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update "动物管理员" to zookeeper --- .../operations/server_configuration_parameters/settings.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/zh/operations/server_configuration_parameters/settings.md b/docs/zh/operations/server_configuration_parameters/settings.md index b78f8173741..fefeac9fc57 100644 --- a/docs/zh/operations/server_configuration_parameters/settings.md +++ b/docs/zh/operations/server_configuration_parameters/settings.md @@ -774,11 +774,11 @@ TCP端口,用于与客户端进行安全通信。 使用它与 [OpenSSL](#serv users.xml ``` -## 动物园管理员 {#server-settings_zookeeper} +## zookeeper {#server-settings_zookeeper} -包含允许ClickHouse与 [动物园管理员](http://zookeeper.apache.org/) 集群。 +包含允许ClickHouse与 [zookpeer](http://zookeeper.apache.org/) 集群。 -ClickHouse使用ZooKeeper在使用复制表时存储副本的元数据。 如果未使用复制的表,则可以省略此部分参数。 +ClickHouse使用ZooKeeper存储复制表副本的元数据。 如果未使用复制的表,则可以省略此部分参数。 本节包含以下参数: From b50d622e73e89fd16b4bb8da5f9d2587499ed147 Mon Sep 17 00:00:00 2001 From: zvrr Date: Tue, 14 Apr 2020 12:30:04 +0800 Subject: [PATCH 180/208] Update settings.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update some setting to 配置 --- .../server_configuration_parameters/settings.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/zh/operations/server_configuration_parameters/settings.md b/docs/zh/operations/server_configuration_parameters/settings.md index b78f8173741..2cffc7e5d2c 100644 --- a/docs/zh/operations/server_configuration_parameters/settings.md +++ b/docs/zh/operations/server_configuration_parameters/settings.md @@ -5,13 +5,13 @@ toc_priority: 57 toc_title: "\u670D\u52A1\u5668\u8BBE\u7F6E" --- -# 服务器设置 {#server-settings} +# 服务器配置 {#server-settings} ## builtin\_dictionaries\_reload\_interval {#builtin-dictionaries-reload-interval} -重新加载内置字典之前的时间间隔(以秒为单位)。 +重新加载内置字典的间隔时间(以秒为单位)。 -ClickHouse每x秒重新加载内置字典。 这使得编辑字典成为可能 “on the fly” 无需重新启动服务器。 +ClickHouse每x秒重新加载内置字典。 这使得编辑字典 “on the fly”,而无需重新启动服务器。 默认值:3600. @@ -23,7 +23,7 @@ ClickHouse每x秒重新加载内置字典。 这使得编辑字典成为可能 ## 压缩 {#server-settings-compression} -数据压缩设置 [MergeTree](../../engines/table_engines/mergetree_family/mergetree.md)-发动机表。 +数据压缩配置 [MergeTree](../../engines/table_engines/mergetree_family/mergetree.md)-引擎表。 !!! warning "警告" 如果您刚开始使用ClickHouse,请不要使用它。 @@ -41,7 +41,7 @@ ClickHouse每x秒重新加载内置字典。 这使得编辑字典成为可能 ``` -`` 字段: +`` 参数: - `min_part_size` – The minimum size of a data part. - `min_part_size_ratio` – The ratio of the data part size to the table size. @@ -82,9 +82,9 @@ ClickHouse每x秒重新加载内置字典。 这使得编辑字典成为可能 ## default\_profile {#default-profile} -默认设置配置文件。 +默认配置文件。 -设置配置文件位于参数中指定的文件中 `user_config`. +配置文件位于`user_config`参数指定的文件中 . **示例** From c5c424b4470ee3f0d03f6780729876ed31f97f22 Mon Sep 17 00:00:00 2001 From: Yatsishin Ilya <2159081+qoega@users.noreply.github.com> Date: Fri, 10 Apr 2020 17:26:31 +0300 Subject: [PATCH 181/208] add junit_to_html_util --- utils/junit_to_html/junit-noframes.xsl | 398 +++++++++++++++++++++++++ utils/junit_to_html/junit_to_html | 25 ++ 2 files changed, 423 insertions(+) create mode 100644 utils/junit_to_html/junit-noframes.xsl create mode 100755 utils/junit_to_html/junit_to_html diff --git a/utils/junit_to_html/junit-noframes.xsl b/utils/junit_to_html/junit-noframes.xsl new file mode 100644 index 00000000000..a8df085f719 --- /dev/null +++ b/utils/junit_to_html/junit-noframes.xsl @@ -0,0 +1,398 @@ + + + + + + + + + + Test Results + + + + + + + + +


+ + + + + + + + + + + + + + + + + +

+
+
+ + + + + + + + +
+

+ Back to top + + +

Summary

+ + + + + + + + + + + + + + + + + Failure + Error + + + + + + + + +
TestsFailuresErrorsSuccess rateTime
+ + + + + + + +
+ + + + +
+ Note: failures are anticipated and checked for with assertions while errors are unanticipated. +
+ + + + + +

Test Results

+
+
+ + + Name + Tests + Errors + Failures + Time(s) + + + + + + Name + Tests + Errors + Failures + Time(s) + Time Stamp + Host + + + + + + Name + Status + Type + Time(s) + + + + + + + + + Failure + Error + + + + + + + + + + + + + + + + + + + + + Error + Failure + TableRowColor + + + + + + Failure + + + + Error + + + + Success + + + + + + + + + + + + +

+ + + + + +
+ + + +

+ + + + + +
+ + + + N/A + + + + + + +

+ at line + + + , column + + +
+
+
+ + + + + + + + + + 32 + + + + + + + + + + + + +
+ + + +
+ + +
+ + + +
+ + + +
+
+ + + + + + + + + diff --git a/utils/junit_to_html/junit_to_html b/utils/junit_to_html/junit_to_html new file mode 100755 index 00000000000..440541c3db6 --- /dev/null +++ b/utils/junit_to_html/junit_to_html @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import os +import sys +import lxml.etree as etree + +def _convert_junit_to_html(junit_path, html_path): + with open(os.path.join(os.path.dirname(__file__), "junit-noframes.xsl")) as xslt_file: + junit_to_html_xslt = etree.parse(xslt_file) + with open(junit_path) as junit_file: + junit_xml = etree.parse(junit_file) + transform = etree.XSLT(junit_to_html_xslt) + print transform(junit_xml) + html = etree.tostring(transform(junit_xml), encoding="utf-8") + html_dir = os.path.dirname(html_path) + if not os.path.exists(html_dir): + os.makedirs(html_dir) + with open(html_path, "w") as html_file: + html_file.write(html) + +if __name__ == "__main__": + if len(sys.argv) < 3: + raise "Insufficient arguments: junit.xml result.html", level + junit_path, html_path = sys.argv[1] , sys.argv[2] + _convert_junit_to_html(junit_path, html_path) From 26a1b3163a3c14f4fc4aead4215716a3d12a0420 Mon Sep 17 00:00:00 2001 From: Yatsishin Ilya <2159081+qoega@users.noreply.github.com> Date: Tue, 14 Apr 2020 10:11:05 +0300 Subject: [PATCH 182/208] better colors --- utils/junit_to_html/junit-noframes.xsl | 11 ++++++----- utils/junit_to_html/junit_to_html | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/utils/junit_to_html/junit-noframes.xsl b/utils/junit_to_html/junit-noframes.xsl index a8df085f719..4532ca87c60 100644 --- a/utils/junit_to_html/junit-noframes.xsl +++ b/utils/junit_to_html/junit-noframes.xsl @@ -34,6 +34,7 @@ under the License. Test Results