diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3dffbd7ecfc..db923369296 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -24,3 +24,6 @@ Detailed description / Documentation draft: By adding documentation, you'll allow users to try your new feature immediately, not when someone else will have time to document it later. Documentation is necessary for all features that affect user experience in any way. You can add brief documentation draft above, or add documentation right into your patch as Markdown files in [docs](https://github.com/ClickHouse/ClickHouse/tree/master/docs) folder. If you are doing this for the first time, it's recommended to read the lightweight [Contributing to ClickHouse Documentation](https://github.com/ClickHouse/ClickHouse/tree/master/docs/README.md) guide first. + + +Information about CI checks: https://clickhouse.tech/docs/en/development/continuous-integration/ diff --git a/.gitmodules b/.gitmodules index ba038dd5cc8..19f93ee8270 100644 --- a/.gitmodules +++ b/.gitmodules @@ -180,3 +180,9 @@ [submodule "contrib/stats"] path = contrib/stats url = https://github.com/kthohr/stats.git +[submodule "contrib/krb5"] + path = contrib/krb5 + url = https://github.com/krb5/krb5 +[submodule "contrib/cyrus-sasl"] + path = contrib/cyrus-sasl + url = https://github.com/cyrusimap/cyrus-sasl diff --git a/CMakeLists.txt b/CMakeLists.txt index c0889383b1d..ec168723b83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,9 +202,16 @@ if (ARCH_NATIVE) set (COMPILER_FLAGS "${COMPILER_FLAGS} -march=native") endif () -# cmake < 3.12 doesn't supoprt 20. We'll set CMAKE_CXX_FLAGS for now +if (UNBUNDLED AND (COMPILER_GCC OR COMPILER_CLANG)) + # to make numeric_limits<__int128> works for unbundled build + set (_CXX_STANDARD "-std=gnu++2a") +else() + set (_CXX_STANDARD "-std=c++2a") +endif() +# cmake < 3.12 doesn't support 20. We'll set CMAKE_CXX_FLAGS for now # set (CMAKE_CXX_STANDARD 20) -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++2a") +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${_CXX_STANDARD}") + set (CMAKE_CXX_EXTENSIONS 0) # https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html#prop_tgt:CXX_EXTENSIONS set (CMAKE_CXX_STANDARD_REQUIRED ON) @@ -371,7 +378,9 @@ include (cmake/find/ltdl.cmake) # for odbc # openssl, zlib before poco include (cmake/find/sparsehash.cmake) include (cmake/find/re2.cmake) +include (cmake/find/krb5.cmake) include (cmake/find/libgsasl.cmake) +include (cmake/find/cyrus-sasl.cmake) include (cmake/find/rdkafka.cmake) include (cmake/find/amqpcpp.cmake) include (cmake/find/capnp.cmake) diff --git a/README.md b/README.md index e895e10c458..6e2282204e7 100644 --- a/README.md +++ b/README.md @@ -17,4 +17,4 @@ ClickHouse is an open-source column-oriented database management system that all ## Upcoming Events -* [ClickHouse at ByteDance (in Chinese)](https://mp.weixin.qq.com/s/Em-HjPylO8D7WPui4RREAQ) on August 14, 2020. +* [ClickHouse at ByteDance (in Chinese)](https://mp.weixin.qq.com/s/Em-HjPylO8D7WPui4RREAQ) on August 28, 2020. diff --git a/base/common/ReadlineLineReader.cpp b/base/common/ReadlineLineReader.cpp index d52ac0e9769..095df319acc 100644 --- a/base/common/ReadlineLineReader.cpp +++ b/base/common/ReadlineLineReader.cpp @@ -6,6 +6,8 @@ #include #include +#include + namespace { @@ -107,6 +109,8 @@ ReadlineLineReader::ReadlineLineReader( throw std::runtime_error(std::string("Cannot set signal handler for readline: ") + strerror(errno)); rl_variable_bind("completion-ignore-case", "on"); + // TODO: it doesn't work + // history_write_timestamps = 1; } ReadlineLineReader::~ReadlineLineReader() @@ -129,6 +133,11 @@ LineReader::InputStatus ReadlineLineReader::readOneLine(const String & prompt) void ReadlineLineReader::addToHistory(const String & line) { add_history(line.c_str()); + + // Flush changes to the disk + // NOTE readline builds a buffer of all the lines to write, and write them in one syscall. + // Thus there is no need to lock the history file here. + write_history(history_file_path.c_str()); } #if RL_VERSION_MAJOR >= 7 diff --git a/base/common/StringRef.h b/base/common/StringRef.h index 2247f0de2ed..410e13ba7d8 100644 --- a/base/common/StringRef.h +++ b/base/common/StringRef.h @@ -21,21 +21,26 @@ #endif -/// The thing to avoid creating strings to find substrings in the hash table. +/** + * The std::string_view-like container to avoid creating strings to find substrings in the hash table. + */ struct StringRef { const char * data = nullptr; size_t size = 0; + /// Non-constexpr due to reinterpret_cast. template > - constexpr StringRef(const CharT * data_, size_t size_) : data(reinterpret_cast(data_)), size(size_) + StringRef(const CharT * data_, size_t size_) : data(reinterpret_cast(data_)), size(size_) { /// Sanity check for overflowed values. assert(size < 0x8000000000000000ULL); } + constexpr StringRef(const char * data_, size_t size_) : data(data_), size(size_) {} + StringRef(const std::string & s) : data(s.data()), size(s.size()) {} - constexpr explicit StringRef(const std::string_view & s) : data(s.data()), size(s.size()) {} + constexpr explicit StringRef(std::string_view s) : data(s.data()), size(s.size()) {} constexpr StringRef(const char * data_) : StringRef(std::string_view{data_}) {} constexpr StringRef() = default; @@ -45,6 +50,12 @@ struct StringRef constexpr explicit operator std::string_view() const { return {data, size}; } }; +/// Here constexpr doesn't implicate inline, see https://www.viva64.com/en/w/v1043/ +/// nullptr can't be used because the StringRef values are used in SipHash's pointer arithmetics +/// and the UBSan thinks that something like nullptr + 8 is UB. +constexpr const inline char empty_string_ref_addr{}; +constexpr const inline StringRef EMPTY_STRING_REF{&empty_string_ref_addr, 0}; + using StringRefs = std::vector; diff --git a/base/common/arithmeticOverflow.h b/base/common/arithmeticOverflow.h index 38e47ccda57..3dfbdbc1346 100644 --- a/base/common/arithmeticOverflow.h +++ b/base/common/arithmeticOverflow.h @@ -1,5 +1,7 @@ #pragma once +#include + namespace common { template @@ -35,6 +37,21 @@ namespace common return (y > 0 && x > max_int128 - y) || (y < 0 && x < min_int128 - y); } + template <> + inline bool addOverflow(bInt256 x, bInt256 y, bInt256 & res) + { + res = x + y; + return (y > 0 && x > std::numeric_limits::max() - y) || + (y < 0 && x < std::numeric_limits::min() - y); + } + + template <> + inline bool addOverflow(bUInt256 x, bUInt256 y, bUInt256 & res) + { + res = x + y; + return x > std::numeric_limits::max() - y; + } + template inline bool subOverflow(T x, T y, T & res) { @@ -68,6 +85,21 @@ namespace common return (y < 0 && x > max_int128 + y) || (y > 0 && x < min_int128 + y); } + template <> + inline bool subOverflow(bInt256 x, bInt256 y, bInt256 & res) + { + res = x - y; + return (y < 0 && x > std::numeric_limits::max() + y) || + (y > 0 && x < std::numeric_limits::min() + y); + } + + template <> + inline bool subOverflow(bUInt256 x, bUInt256 y, bUInt256 & res) + { + res = x - y; + return x < y; + } + template inline bool mulOverflow(T x, T y, T & res) { @@ -103,4 +135,25 @@ namespace common unsigned __int128 b = (y > 0) ? y : -y; return (a * b) / b != a; } + + template <> + inline bool mulOverflow(bInt256 x, bInt256 y, bInt256 & res) + { + res = x * y; + if (!x || !y) + return false; + + bInt256 a = (x > 0) ? x : -x; + bInt256 b = (y > 0) ? y : -y; + return (a * b) / b != a; + } + + template <> + inline bool mulOverflow(bUInt256 x, bUInt256 y, bUInt256 & res) + { + res = x * y; + if (!x || !y) + return false; + return (x * y) / y != x; + } } diff --git a/base/common/getResource.cpp b/base/common/getResource.cpp index be7f205e7d1..5d5f18047b3 100644 --- a/base/common/getResource.cpp +++ b/base/common/getResource.cpp @@ -2,6 +2,7 @@ #include "unaligned.h" #include #include +#include std::string_view getResource(std::string_view name) @@ -10,6 +11,7 @@ std::string_view getResource(std::string_view name) std::replace(name_replaced.begin(), name_replaced.end(), '/', '_'); std::replace(name_replaced.begin(), name_replaced.end(), '-', '_'); std::replace(name_replaced.begin(), name_replaced.end(), '.', '_'); + boost::replace_all(name_replaced, "+", "_PLUS_"); /// These are the names that are generated by "ld -r -b binary" std::string symbol_name_data = "_binary_" + name_replaced + "_start"; diff --git a/base/common/tests/CMakeLists.txt b/base/common/tests/CMakeLists.txt index 486914e4ca7..b7082ee9900 100644 --- a/base/common/tests/CMakeLists.txt +++ b/base/common/tests/CMakeLists.txt @@ -1,19 +1,15 @@ include (${ClickHouse_SOURCE_DIR}/cmake/add_check.cmake) -add_executable (date_lut_init date_lut_init.cpp) add_executable (date_lut2 date_lut2.cpp) add_executable (date_lut3 date_lut3.cpp) -add_executable (date_lut4 date_lut4.cpp) add_executable (date_lut_default_timezone date_lut_default_timezone.cpp) add_executable (local_date_time_comparison local_date_time_comparison.cpp) add_executable (realloc-perf allocator.cpp) set(PLATFORM_LIBS ${CMAKE_DL_LIBS}) -target_link_libraries (date_lut_init PRIVATE common ${PLATFORM_LIBS}) target_link_libraries (date_lut2 PRIVATE common ${PLATFORM_LIBS}) target_link_libraries (date_lut3 PRIVATE common ${PLATFORM_LIBS}) -target_link_libraries (date_lut4 PRIVATE common ${PLATFORM_LIBS}) target_link_libraries (date_lut_default_timezone PRIVATE common ${PLATFORM_LIBS}) target_link_libraries (local_date_time_comparison PRIVATE common) target_link_libraries (realloc-perf PRIVATE common) diff --git a/base/common/tests/date_lut4.cpp b/base/common/tests/date_lut4.cpp deleted file mode 100644 index 86a4708dc79..00000000000 --- a/base/common/tests/date_lut4.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include -#include - - -int main(int, char **) -{ - /** В DateLUT был глюк - для времён из дня 1970-01-01, возвращался номер часа больше 23. */ - static const time_t time = 66130; - - const auto & date_lut = DateLUT::instance(); - - std::cerr << date_lut.toHour(time) << std::endl; - std::cerr << date_lut.toDayNum(time) << std::endl; - - const auto * values = reinterpret_cast(&date_lut); - - std::cerr << values[0].date << ", " << time_t(values[1].date - values[0].date) << std::endl; - - return 0; -} diff --git a/base/common/tests/date_lut_init.cpp b/base/common/tests/date_lut_init.cpp deleted file mode 100644 index 48f0d6063c7..00000000000 --- a/base/common/tests/date_lut_init.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#include - -/// Позволяет проверить время инициализации DateLUT. -int main(int, char **) -{ - DateLUT::instance(); - return 0; -} diff --git a/base/common/types.h b/base/common/types.h index 238e4e3956b..c49e9334bf5 100644 --- a/base/common/types.h +++ b/base/common/types.h @@ -6,6 +6,8 @@ #include #include +#include + using Int8 = int8_t; using Int16 = int16_t; using Int32 = int32_t; @@ -15,11 +17,21 @@ using Int64 = int64_t; using char8_t = unsigned char; #endif +/// This is needed for more strict aliasing. https://godbolt.org/z/xpJBSb https://stackoverflow.com/a/57453713 using UInt8 = char8_t; using UInt16 = uint16_t; using UInt32 = uint32_t; using UInt64 = uint64_t; +using Int128 = __int128; + +/// We have to use 127 and 255 bit integers to safe a bit for a sign serialization +//using bInt256 = boost::multiprecision::int256_t; +using bInt256 = boost::multiprecision::number >; +using bUInt256 = boost::multiprecision::uint256_t; + + using String = std::string; /// The standard library type traits, such as std::is_arithmetic, with one exception @@ -31,6 +43,9 @@ struct is_signed static constexpr bool value = std::is_signed_v; }; +template <> struct is_signed { static constexpr bool value = true; }; +template <> struct is_signed { static constexpr bool value = true; }; + template inline constexpr bool is_signed_v = is_signed::value; @@ -40,17 +55,26 @@ struct is_unsigned static constexpr bool value = std::is_unsigned_v; }; +template <> struct is_unsigned { static constexpr bool value = true; }; + template inline constexpr bool is_unsigned_v = is_unsigned::value; + +/// TODO: is_integral includes char, char8_t and wchar_t. template -struct is_integral +struct is_integer { static constexpr bool value = std::is_integral_v; }; +template <> struct is_integer { static constexpr bool value = true; }; +template <> struct is_integer { static constexpr bool value = true; }; +template <> struct is_integer { static constexpr bool value = true; }; + template -inline constexpr bool is_integral_v = is_integral::value; +inline constexpr bool is_integer_v = is_integer::value; + template struct is_arithmetic @@ -58,5 +82,42 @@ struct is_arithmetic static constexpr bool value = std::is_arithmetic_v; }; +template <> struct is_arithmetic<__int128> { static constexpr bool value = true; }; + template inline constexpr bool is_arithmetic_v = is_arithmetic::value; + +template +struct make_unsigned +{ + typedef std::make_unsigned_t type; +}; + +template <> struct make_unsigned<__int128> { using type = unsigned __int128; }; +template <> struct make_unsigned { using type = bUInt256; }; +template <> struct make_unsigned { using type = bUInt256; }; + +template using make_unsigned_t = typename make_unsigned::type; + +template +struct make_signed +{ + typedef std::make_signed_t type; +}; + +template <> struct make_signed { typedef bInt256 type; }; +template <> struct make_signed { typedef bInt256 type; }; + +template using make_signed_t = typename make_signed::type; + +template +struct is_big_int +{ + static constexpr bool value = false; +}; + +template <> struct is_big_int { static constexpr bool value = true; }; +template <> struct is_big_int { static constexpr bool value = true; }; + +template +inline constexpr bool is_big_int_v = is_big_int::value; diff --git a/base/common/ya.make b/base/common/ya.make index fc5de5efab3..7cac8f2c9a5 100644 --- a/base/common/ya.make +++ b/base/common/ya.make @@ -25,8 +25,8 @@ PEERDIR( contrib/libs/cctz/src contrib/libs/cxxsupp/libcxx-filesystem contrib/libs/poco/Net - contrib/libs/poco/NetSSL_OpenSSL contrib/libs/poco/Util + contrib/libs/poco/NetSSL_OpenSSL contrib/libs/fmt contrib/restricted/boost contrib/restricted/cityhash-1.0.2 @@ -52,6 +52,7 @@ SRCS( shift10.cpp sleep.cpp terminalColors.cpp + ) END() diff --git a/base/common/ya.make.in b/base/common/ya.make.in index 957ae4d68b7..e841648692c 100644 --- a/base/common/ya.make.in +++ b/base/common/ya.make.in @@ -10,6 +10,7 @@ CFLAGS (GLOBAL -DARCADIA_BUILD) CFLAGS (GLOBAL -DUSE_CPUID=1) CFLAGS (GLOBAL -DUSE_JEMALLOC=0) CFLAGS (GLOBAL -DUSE_RAPIDJSON=1) +CFLAGS (GLOBAL -DUSE_SSL=1) IF (OS_DARWIN) CFLAGS (GLOBAL -DOS_DARWIN) @@ -24,6 +25,7 @@ PEERDIR( contrib/libs/cxxsupp/libcxx-filesystem contrib/libs/poco/Net contrib/libs/poco/Util + contrib/libs/poco/NetSSL_OpenSSL contrib/libs/fmt contrib/restricted/boost contrib/restricted/cityhash-1.0.2 diff --git a/benchmark/monetdb/usability.md b/benchmark/monetdb/usability.md index 20eaf37f9e8..741079b5663 100644 --- a/benchmark/monetdb/usability.md +++ b/benchmark/monetdb/usability.md @@ -2,7 +2,7 @@ Go to https://www.monetdb.org/ The graphical design of the website is a bit old-fashioned but I do not afraid. -Dowload now. +Download now. Latest binary releases. Ubuntu & Debian. @@ -1103,7 +1103,7 @@ Ok, it's doing something at least for twenty minues... clk: 28:02 min ``` -Finally it has loaded data successfuly in 28 minutes. It's not fast - just below 60 000 rows per second. +Finally it has loaded data successfully in 28 minutes. It's not fast - just below 60 000 rows per second. But the second query from the test does not work: diff --git a/cmake/find/cyrus-sasl.cmake b/cmake/find/cyrus-sasl.cmake new file mode 100644 index 00000000000..974b8148fdc --- /dev/null +++ b/cmake/find/cyrus-sasl.cmake @@ -0,0 +1,23 @@ +if (${ENABLE_LIBRARIES} AND ${ENABLE_KRB5}) + set (DEFAULT_ENABLE_CYRUS_SASL 1) +else() + set (DEFAULT_ENABLE_CYRUS_SASL 0) +endif() + +OPTION(ENABLE_CYRUS_SASL "Enable cyrus-sasl" ${DEFAULT_ENABLE_CYRUS_SASL}) +if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/cyrus-sasl/README") + message (WARNING "submodule contrib/cyrus-sasl is missing. to fix try run: \n git submodule update --init --recursive") + set (ENABLE_CYRUS_SASL 0) +endif () + +if (ENABLE_CYRUS_SASL) + + set (USE_CYRUS_SASL 1) + set (CYRUS_SASL_LIBRARY sasl2) + + set (CYRUS_SASL_INCLUDE_DIR "${ClickHouse_SOURCE_DIR}/contrib/cyrus-sasl/include") + + +endif () + +message (STATUS "Using cyrus-sasl: krb5=${USE_KRB5}: ${CYRUS_SASL_INCLUDE_DIR} : ${CYRUS_SASL_LIBRARY}") diff --git a/cmake/find/krb5.cmake b/cmake/find/krb5.cmake new file mode 100644 index 00000000000..bd9c8e239cd --- /dev/null +++ b/cmake/find/krb5.cmake @@ -0,0 +1,25 @@ +OPTION(ENABLE_KRB5 "Enable krb5" ${ENABLE_LIBRARIES}) + +if (NOT EXISTS "${ClickHouse_SOURCE_DIR}/contrib/krb5/README") + message (WARNING "submodule contrib/krb5 is missing. to fix try run: \n git submodule update --init --recursive") + set (ENABLE_KRB5 0) +endif () + +if (NOT CMAKE_SYSTEM_NAME MATCHES "Linux") + message (WARNING "krb5 disabled in non-Linux environments") + set (ENABLE_KRB5 0) +endif () + +if (ENABLE_KRB5) + + set (USE_KRB5 1) + set (KRB5_LIBRARY krb5) + + set (KRB5_INCLUDE_DIR + "${ClickHouse_SOURCE_DIR}/contrib/krb5/src/include" + "${ClickHouse_BINARY_DIR}/contrib/krb5-cmake/include" + ) + +endif () + +message (STATUS "Using krb5=${USE_KRB5}: ${KRB5_INCLUDE_DIR} : ${KRB5_LIBRARY}") diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt index b4ac383004b..130e4b13c91 100644 --- a/contrib/CMakeLists.txt +++ b/contrib/CMakeLists.txt @@ -311,3 +311,10 @@ if (USE_STATS) add_subdirectory (stats-cmake) add_subdirectory (gcem) endif() + +if (USE_KRB5) + add_subdirectory (krb5-cmake) + if (USE_CYRUS_SASL) + add_subdirectory (cyrus-sasl-cmake) + endif() +endif() diff --git a/contrib/cctz-cmake/CMakeLists.txt b/contrib/cctz-cmake/CMakeLists.txt index ee87b3233ad..eab3210d556 100644 --- a/contrib/cctz-cmake/CMakeLists.txt +++ b/contrib/cctz-cmake/CMakeLists.txt @@ -27,584 +27,29 @@ if (USE_INTERNAL_CCTZ) # Build a libray with embedded tzdata if (OS_LINUX) - - set (TIMEZONES - Africa/Abidjan - Africa/Accra - Africa/Addis_Ababa - Africa/Algiers - Africa/Asmara - Africa/Asmera - Africa/Bamako - Africa/Bangui - Africa/Banjul - Africa/Bissau - Africa/Blantyre - Africa/Brazzaville - Africa/Bujumbura - Africa/Cairo - Africa/Casablanca - Africa/Ceuta - Africa/Conakry - Africa/Dakar - Africa/Dar_es_Salaam - Africa/Djibouti - Africa/Douala - Africa/El_Aaiun - Africa/Freetown - Africa/Gaborone - Africa/Harare - Africa/Johannesburg - Africa/Juba - Africa/Kampala - Africa/Khartoum - Africa/Kigali - Africa/Kinshasa - Africa/Lagos - Africa/Libreville - Africa/Lome - Africa/Luanda - Africa/Lubumbashi - Africa/Lusaka - Africa/Malabo - Africa/Maputo - Africa/Maseru - Africa/Mbabane - Africa/Mogadishu - Africa/Monrovia - Africa/Nairobi - Africa/Ndjamena - Africa/Niamey - Africa/Nouakchott - Africa/Ouagadougou - Africa/Porto-Novo - Africa/Sao_Tome - Africa/Timbuktu - Africa/Tripoli - Africa/Tunis - Africa/Windhoek - America/Adak - America/Anchorage - America/Anguilla - America/Antigua - America/Araguaina - America/Argentina/Buenos_Aires - America/Argentina/Catamarca - America/Argentina/ComodRivadavia - America/Argentina/Cordoba - America/Argentina/Jujuy - America/Argentina/La_Rioja - America/Argentina/Mendoza - America/Argentina/Rio_Gallegos - America/Argentina/Salta - America/Argentina/San_Juan - America/Argentina/San_Luis - America/Argentina/Tucuman - America/Argentina/Ushuaia - America/Aruba - America/Asuncion - America/Atikokan - America/Atka - America/Bahia - America/Bahia_Banderas - America/Barbados - America/Belem - America/Belize - America/Blanc-Sablon - America/Boa_Vista - America/Bogota - America/Boise - America/Buenos_Aires - America/Cambridge_Bay - America/Campo_Grande - America/Cancun - America/Caracas - America/Catamarca - America/Cayenne - America/Cayman - America/Chicago - America/Chihuahua - America/Coral_Harbour - America/Cordoba - America/Costa_Rica - America/Creston - America/Cuiaba - America/Curacao - America/Danmarkshavn - America/Dawson - America/Dawson_Creek - America/Denver - America/Detroit - America/Dominica - America/Edmonton - America/Eirunepe - America/El_Salvador - America/Ensenada - America/Fortaleza - America/Fort_Nelson - America/Fort_Wayne - America/Glace_Bay - America/Godthab - America/Goose_Bay - America/Grand_Turk - America/Grenada - America/Guadeloupe - America/Guatemala - America/Guayaquil - America/Guyana - America/Halifax - America/Havana - America/Hermosillo - America/Indiana/Indianapolis - America/Indiana/Knox - America/Indiana/Marengo - America/Indiana/Petersburg - America/Indianapolis - America/Indiana/Tell_City - America/Indiana/Vevay - America/Indiana/Vincennes - America/Indiana/Winamac - America/Inuvik - America/Iqaluit - America/Jamaica - America/Jujuy - America/Juneau - America/Kentucky/Louisville - America/Kentucky/Monticello - America/Knox_IN - America/Kralendijk - America/La_Paz - America/Lima - America/Los_Angeles - America/Louisville - America/Lower_Princes - America/Maceio - America/Managua - America/Manaus - America/Marigot - America/Martinique - America/Matamoros - America/Mazatlan - America/Mendoza - America/Menominee - America/Merida - America/Metlakatla - America/Mexico_City - America/Miquelon - America/Moncton - America/Monterrey - America/Montevideo - America/Montreal - America/Montserrat - America/Nassau - America/New_York - America/Nipigon - America/Nome - America/Noronha - America/North_Dakota/Beulah - America/North_Dakota/Center - America/North_Dakota/New_Salem - America/Ojinaga - America/Panama - America/Pangnirtung - America/Paramaribo - America/Phoenix - America/Port-au-Prince - America/Porto_Acre - America/Port_of_Spain - America/Porto_Velho - America/Puerto_Rico - America/Punta_Arenas - America/Rainy_River - America/Rankin_Inlet - America/Recife - America/Regina - America/Resolute - America/Rio_Branco - America/Rosario - America/Santa_Isabel - America/Santarem - America/Santiago - America/Santo_Domingo - America/Sao_Paulo - America/Scoresbysund - America/Shiprock - America/Sitka - America/St_Barthelemy - America/St_Johns - America/St_Kitts - America/St_Lucia - America/St_Thomas - America/St_Vincent - America/Swift_Current - America/Tegucigalpa - America/Thule - America/Thunder_Bay - America/Tijuana - America/Toronto - America/Tortola - America/Vancouver - America/Virgin - America/Whitehorse - America/Winnipeg - America/Yakutat - America/Yellowknife - Antarctica/Casey - Antarctica/Davis - Antarctica/DumontDUrville - Antarctica/Macquarie - Antarctica/Mawson - Antarctica/McMurdo - Antarctica/Palmer - Antarctica/Rothera - Antarctica/South_Pole - Antarctica/Syowa - Antarctica/Troll - Antarctica/Vostok - Arctic/Longyearbyen - Asia/Aden - Asia/Almaty - Asia/Amman - Asia/Anadyr - Asia/Aqtau - Asia/Aqtobe - Asia/Ashgabat - Asia/Ashkhabad - Asia/Atyrau - Asia/Baghdad - Asia/Bahrain - Asia/Baku - Asia/Bangkok - Asia/Barnaul - Asia/Beirut - Asia/Bishkek - Asia/Brunei - Asia/Calcutta - Asia/Chita - Asia/Choibalsan - Asia/Chongqing - Asia/Chungking - Asia/Colombo - Asia/Dacca - Asia/Damascus - Asia/Dhaka - Asia/Dili - Asia/Dubai - Asia/Dushanbe - Asia/Famagusta - Asia/Gaza - Asia/Harbin - Asia/Hebron - Asia/Ho_Chi_Minh - Asia/Hong_Kong - Asia/Hovd - Asia/Irkutsk - Asia/Istanbul - Asia/Jakarta - Asia/Jayapura - Asia/Jerusalem - Asia/Kabul - Asia/Kamchatka - Asia/Karachi - Asia/Kashgar - Asia/Kathmandu - Asia/Katmandu - Asia/Khandyga - Asia/Kolkata - Asia/Krasnoyarsk - Asia/Kuala_Lumpur - Asia/Kuching - Asia/Kuwait - Asia/Macao - Asia/Macau - Asia/Magadan - Asia/Makassar - Asia/Manila - Asia/Muscat - Asia/Nicosia - Asia/Novokuznetsk - Asia/Novosibirsk - Asia/Omsk - Asia/Oral - Asia/Phnom_Penh - Asia/Pontianak - Asia/Pyongyang - Asia/Qatar - Asia/Qostanay - Asia/Qyzylorda - Asia/Rangoon - Asia/Riyadh - Asia/Saigon - Asia/Sakhalin - Asia/Samarkand - Asia/Seoul - Asia/Shanghai - Asia/Singapore - Asia/Srednekolymsk - Asia/Taipei - Asia/Tashkent - Asia/Tbilisi - Asia/Tehran - Asia/Tel_Aviv - Asia/Thimbu - Asia/Thimphu - Asia/Tokyo - Asia/Tomsk - Asia/Ujung_Pandang - Asia/Ulaanbaatar - Asia/Ulan_Bator - Asia/Urumqi - Asia/Ust-Nera - Asia/Vientiane - Asia/Vladivostok - Asia/Yakutsk - Asia/Yangon - Asia/Yekaterinburg - Asia/Yerevan - Atlantic/Azores - Atlantic/Bermuda - Atlantic/Canary - Atlantic/Cape_Verde - Atlantic/Faeroe - Atlantic/Faroe - Atlantic/Jan_Mayen - Atlantic/Madeira - Atlantic/Reykjavik - Atlantic/South_Georgia - Atlantic/Stanley - Atlantic/St_Helena - Australia/ACT - Australia/Adelaide - Australia/Brisbane - Australia/Broken_Hill - Australia/Canberra - Australia/Currie - Australia/Darwin - Australia/Eucla - Australia/Hobart - Australia/LHI - Australia/Lindeman - Australia/Lord_Howe - Australia/Melbourne - Australia/North - Australia/NSW - Australia/Perth - Australia/Queensland - Australia/South - Australia/Sydney - Australia/Tasmania - Australia/Victoria - Australia/West - Australia/Yancowinna - Brazil/Acre - Brazil/DeNoronha - Brazil/East - Brazil/West - Canada/Atlantic - Canada/Central - Canada/Eastern - Canada/Mountain - Canada/Newfoundland - Canada/Pacific - Canada/Saskatchewan - Canada/Yukon - CET - Chile/Continental - Chile/EasterIsland - CST6CDT - Cuba - EET - Egypt - Eire - EST - EST5EDT - Etc/GMT - Etc/Greenwich - Etc/UCT - Etc/Universal - Etc/UTC - Etc/Zulu - Europe/Amsterdam - Europe/Andorra - Europe/Astrakhan - Europe/Athens - Europe/Belfast - Europe/Belgrade - Europe/Berlin - Europe/Bratislava - Europe/Brussels - Europe/Bucharest - Europe/Budapest - Europe/Busingen - Europe/Chisinau - Europe/Copenhagen - Europe/Dublin - Europe/Gibraltar - Europe/Guernsey - Europe/Helsinki - Europe/Isle_of_Man - Europe/Istanbul - Europe/Jersey - Europe/Kaliningrad - Europe/Kiev - Europe/Kirov - Europe/Lisbon - Europe/Ljubljana - Europe/London - Europe/Luxembourg - Europe/Madrid - Europe/Malta - Europe/Mariehamn - Europe/Minsk - Europe/Monaco - Europe/Moscow - Europe/Nicosia - Europe/Oslo - Europe/Paris - Europe/Podgorica - Europe/Prague - Europe/Riga - Europe/Rome - Europe/Samara - Europe/San_Marino - Europe/Sarajevo - Europe/Saratov - Europe/Simferopol - Europe/Skopje - Europe/Sofia - Europe/Stockholm - Europe/Tallinn - Europe/Tirane - Europe/Tiraspol - Europe/Ulyanovsk - Europe/Uzhgorod - Europe/Vaduz - Europe/Vatican - Europe/Vienna - Europe/Vilnius - Europe/Volgograd - Europe/Warsaw - Europe/Zagreb - Europe/Zaporozhye - Europe/Zurich - Factory - GB - GB-Eire - GMT - GMT0 - Greenwich - Hongkong - HST - Iceland - Indian/Antananarivo - Indian/Chagos - Indian/Christmas - Indian/Cocos - Indian/Comoro - Indian/Kerguelen - Indian/Mahe - Indian/Maldives - Indian/Mauritius - Indian/Mayotte - Indian/Reunion - Iran - Israel - Jamaica - Japan - Kwajalein - Libya - MET - Mexico/BajaNorte - Mexico/BajaSur - Mexico/General - MST - MST7MDT - Navajo - NZ - NZ-CHAT - Pacific/Apia - Pacific/Auckland - Pacific/Bougainville - Pacific/Chatham - Pacific/Chuuk - Pacific/Easter - Pacific/Efate - Pacific/Enderbury - Pacific/Fakaofo - Pacific/Fiji - Pacific/Funafuti - Pacific/Galapagos - Pacific/Gambier - Pacific/Guadalcanal - Pacific/Guam - Pacific/Honolulu - Pacific/Johnston - Pacific/Kiritimati - Pacific/Kosrae - Pacific/Kwajalein - Pacific/Majuro - Pacific/Marquesas - Pacific/Midway - Pacific/Nauru - Pacific/Niue - Pacific/Norfolk - Pacific/Noumea - Pacific/Pago_Pago - Pacific/Palau - Pacific/Pitcairn - Pacific/Pohnpei - Pacific/Ponape - Pacific/Port_Moresby - Pacific/Rarotonga - Pacific/Saipan - Pacific/Samoa - Pacific/Tahiti - Pacific/Tarawa - Pacific/Tongatapu - Pacific/Truk - Pacific/Wake - Pacific/Wallis - Pacific/Yap - Poland - Portugal - PRC - PST8PDT - ROC - ROK - Singapore - Turkey - UCT - Universal - US/Alaska - US/Aleutian - US/Arizona - US/Central - US/Eastern - US/East-Indiana - US/Hawaii - US/Indiana-Starke - US/Michigan - US/Mountain - US/Pacific - US/Samoa - UTC - WET - W-SU - Zulu) - + # get the list of timezones from tzdata shipped with cctz set(TZDIR ${LIBRARY_DIR}/testdata/zoneinfo) + file(STRINGS ${LIBRARY_DIR}/testdata/version TZDATA_VERSION) + set_property(GLOBAL PROPERTY TZDATA_VERSION_PROP "${TZDATA_VERSION}") + message(STATUS "Packaging with tzdata version: ${TZDATA_VERSION}") + set(TZ_OBJS) + # each file/symlink in that dir (except of tab and localtime) store the info about timezone + execute_process(COMMAND bash -c "cd ${TZDIR} && find * -type f,l -and ! -name '*.tab' -and ! -name 'localtime' | sort | paste -sd ';'" OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE TIMEZONES ) + foreach(TIMEZONE ${TIMEZONES}) string(REPLACE "/" "_" TIMEZONE_ID ${TIMEZONE}) + string(REPLACE "+" "_PLUS_" TIMEZONE_ID ${TIMEZONE_ID}) set(TZ_OBJ ${TIMEZONE_ID}.o) set(TZ_OBJS ${TZ_OBJS} ${TZ_OBJ}) # https://stackoverflow.com/questions/14776463/compile-and-add-an-object-file-from-a-binary-with-cmake add_custom_command(OUTPUT ${TZ_OBJ} - COMMAND cd ${TZDIR} && ${OBJCOPY_PATH} -I binary ${OBJCOPY_ARCH_OPTIONS} ${TIMEZONE} ${CMAKE_CURRENT_BINARY_DIR}/${TZ_OBJ} - COMMAND ${OBJCOPY_PATH} --rename-section .data=.rodata,alloc,load,readonly,data,contents - ${CMAKE_CURRENT_BINARY_DIR}/${TZ_OBJ} ${CMAKE_CURRENT_BINARY_DIR}/${TZ_OBJ}) + COMMAND cp ${TZDIR}/${TIMEZONE} ${CMAKE_CURRENT_BINARY_DIR}/${TIMEZONE_ID} + COMMAND cd ${CMAKE_CURRENT_BINARY_DIR} && ${OBJCOPY_PATH} -I binary ${OBJCOPY_ARCH_OPTIONS} + --rename-section .data=.rodata,alloc,load,readonly,data,contents ${TIMEZONE_ID} ${TZ_OBJ} + COMMAND rm ${CMAKE_CURRENT_BINARY_DIR}/${TIMEZONE_ID}) set_source_files_properties(${TZ_OBJ} PROPERTIES EXTERNAL_OBJECT true GENERATED true) endforeach(TIMEZONE) diff --git a/contrib/cyrus-sasl b/contrib/cyrus-sasl new file mode 160000 index 00000000000..6054630889f --- /dev/null +++ b/contrib/cyrus-sasl @@ -0,0 +1 @@ +Subproject commit 6054630889fd1cd8d0659573d69badcee1e23a00 diff --git a/contrib/cyrus-sasl-cmake/CMakeLists.txt b/contrib/cyrus-sasl-cmake/CMakeLists.txt new file mode 100644 index 00000000000..5003c9a21db --- /dev/null +++ b/contrib/cyrus-sasl-cmake/CMakeLists.txt @@ -0,0 +1,69 @@ +set(CYRUS_SASL_SOURCE_DIR ${ClickHouse_SOURCE_DIR}/contrib/cyrus-sasl) + +add_library(${CYRUS_SASL_LIBRARY}) + +target_sources(${CYRUS_SASL_LIBRARY} PRIVATE + ${CYRUS_SASL_SOURCE_DIR}/plugins/gssapi.c + # ${CYRUS_SASL_SOURCE_DIR}/plugins/gssapiv2_init.c + ${CYRUS_SASL_SOURCE_DIR}/common/plugin_common.c + ${CYRUS_SASL_SOURCE_DIR}/lib/common.c + ${CYRUS_SASL_SOURCE_DIR}/lib/canonusr.c + ${CYRUS_SASL_SOURCE_DIR}/lib/server.c + ${CYRUS_SASL_SOURCE_DIR}/lib/config.c + ${CYRUS_SASL_SOURCE_DIR}/lib/auxprop.c + ${CYRUS_SASL_SOURCE_DIR}/lib/saslutil.c + ${CYRUS_SASL_SOURCE_DIR}/lib/external.c + ${CYRUS_SASL_SOURCE_DIR}/lib/seterror.c + ${CYRUS_SASL_SOURCE_DIR}/lib/md5.c + ${CYRUS_SASL_SOURCE_DIR}/lib/dlopen.c + ${CYRUS_SASL_SOURCE_DIR}/lib/client.c + ${CYRUS_SASL_SOURCE_DIR}/lib/checkpw.c +) + +target_include_directories(${CYRUS_SASL_LIBRARY} PUBLIC + ${CMAKE_CURRENT_BINARY_DIR} +) + +target_include_directories(${CYRUS_SASL_LIBRARY} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} # for config.h + ${CYRUS_SASL_SOURCE_DIR}/plugins + ${CYRUS_SASL_SOURCE_DIR} + ${CYRUS_SASL_SOURCE_DIR}/include + ${CYRUS_SASL_SOURCE_DIR}/lib + ${CYRUS_SASL_SOURCE_DIR}/sasldb + ${CYRUS_SASL_SOURCE_DIR}/common + ${CYRUS_SASL_SOURCE_DIR}/saslauthd + ${CYRUS_SASL_SOURCE_DIR}/sample + ${CYRUS_SASL_SOURCE_DIR}/utils + ${CYRUS_SASL_SOURCE_DIR}/tests +) + +target_compile_definitions(${CYRUS_SASL_LIBRARY} PUBLIC + HAVE_CONFIG_H + # PLUGINDIR="/usr/local/lib/sasl2" + PLUGINDIR="" + # PIC + OBSOLETE_CRAM_ATTR=1 + # SASLAUTHD_CONF_FILE_DEFAULT="/usr/local/etc/saslauthd.conf" + SASLAUTHD_CONF_FILE_DEFAULT="" + # CONFIGDIR="/usr/local/lib/sasl2:/usr/local/etc/sasl2" + CONFIGDIR="" + OBSOLETE_DIGEST_ATTR=1 + LIBSASL_EXPORTS=1 +) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/sasl) + +file(COPY + ${CYRUS_SASL_SOURCE_DIR}/include/sasl.h + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/sasl +) + +file(COPY + ${CYRUS_SASL_SOURCE_DIR}/include/prop.h + DESTINATION ${CMAKE_CURRENT_BINARY_DIR} +) + +target_link_libraries(${CYRUS_SASL_LIBRARY} + PUBLIC ${KRB5_LIBRARY} +) diff --git a/contrib/cyrus-sasl-cmake/config.h b/contrib/cyrus-sasl-cmake/config.h new file mode 100644 index 00000000000..b74275c62c6 --- /dev/null +++ b/contrib/cyrus-sasl-cmake/config.h @@ -0,0 +1,722 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + + +/* acconfig.h - autoheader configuration input */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef CONFIG_H +#define CONFIG_H + + +/* Include SASLdb Support */ +/* #undef AUTH_SASLDB */ + +/* Do we need a leading _ for dlsym? */ +/* #undef DLSYM_NEEDS_UNDERSCORE */ + +/* Should we build a shared plugin (via dlopen) library? */ +#define DO_DLOPEN /**/ + +/* should we support sasl_checkapop? */ +#define DO_SASL_CHECKAPOP /**/ + +/* should we support setpass() for SRP? */ +/* #undef DO_SRP_SETPASS */ + +/* Define if your getpwnam_r()/getspnam_r() functions take 5 arguments */ +#define GETXXNAM_R_5ARG 1 + +/* should we mutex-wrap calls into the GSS library? */ +#define GSS_USE_MUTEXES /**/ + +/* Enable 'alwaystrue' password verifier? */ +/* #undef HAVE_ALWAYSTRUE */ + +/* Define to 1 if you have the `asprintf' function. */ +#define HAVE_ASPRINTF 1 + +/* Include support for Courier's authdaemond? */ +#define HAVE_AUTHDAEMON /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_CRYPT_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DES_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dns_lookup' function. */ +/* #undef HAVE_DNS_LOOKUP */ + +/* Define to 1 if you have the `dn_expand' function. */ +/* #undef HAVE_DN_EXPAND */ + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Do we have a getaddrinfo? */ +#define HAVE_GETADDRINFO /**/ + +/* Define to 1 if you have the `getdomainname' function. */ +#define HAVE_GETDOMAINNAME 1 + +/* Define to 1 if you have the `gethostname' function. */ +#define HAVE_GETHOSTNAME 1 + +/* Do we have a getnameinfo() function? */ +#define HAVE_GETNAMEINFO /**/ + +/* Define to 1 if you have the `getpassphrase' function. */ +/* #undef HAVE_GETPASSPHRASE */ + +/* Define to 1 if you have the `getpwnam' function. */ +#define HAVE_GETPWNAM 1 + +/* Define to 1 if you have the `getspnam' function. */ +#define HAVE_GETSPNAM 1 + +/* do we have getsubopt()? */ +#define HAVE_GETSUBOPT /**/ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Include GSSAPI/Kerberos 5 Support */ +#define HAVE_GSSAPI /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_GSSAPI_GSSAPI_EXT_H 1 + +/* Define if you have the gssapi/gssapi.h header file */ +/* #undef HAVE_GSSAPI_GSSAPI_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_GSSAPI_GSSAPI_KRB5_H 1 + +/* Define if you have the gssapi.h header file */ +#define HAVE_GSSAPI_H /**/ + +/* Define if your GSSAPI implementation defines + gsskrb5_register_acceptor_identity */ +#define HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY 1 + +/* Define if your GSSAPI implementation defines GSS_C_NT_HOSTBASED_SERVICE */ +#define HAVE_GSS_C_NT_HOSTBASED_SERVICE /**/ + +/* Define if your GSSAPI implementation defines GSS_C_NT_USER_NAME */ +#define HAVE_GSS_C_NT_USER_NAME /**/ + +/* Define if your GSSAPI implementation defines GSS_C_SEC_CONTEXT_SASL_SSF */ +#define HAVE_GSS_C_SEC_CONTEXT_SASL_SSF /**/ + +/* Define to 1 if you have the `gss_decapsulate_token' function. */ +#define HAVE_GSS_DECAPSULATE_TOKEN 1 + +/* Define to 1 if you have the `gss_encapsulate_token' function. */ +#define HAVE_GSS_ENCAPSULATE_TOKEN 1 + +/* Define to 1 if you have the `gss_get_name_attribute' function. */ +#define HAVE_GSS_GET_NAME_ATTRIBUTE 1 + +/* Define if your GSSAPI implementation defines gss_inquire_sec_context_by_oid + */ +#define HAVE_GSS_INQUIRE_SEC_CONTEXT_BY_OID 1 + +/* Define to 1 if you have the `gss_oid_equal' function. */ +#define HAVE_GSS_OID_EQUAL 1 + +/* Define if your GSSAPI implementation supports SPNEGO */ +#define HAVE_GSS_SPNEGO /**/ + +/* Include HTTP form Support */ +/* #undef HAVE_HTTPFORM */ + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `jrand48' function. */ +#define HAVE_JRAND48 1 + +/* Do we have Kerberos 4 Support? */ +/* #undef HAVE_KRB */ + +/* Define to 1 if you have the header file. */ +#define HAVE_KRB5_H 1 + +/* Define to 1 if you have the `krb_get_err_text' function. */ +/* #undef HAVE_KRB_GET_ERR_TEXT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LBER_H */ + +/* Support for LDAP? */ +/* #undef HAVE_LDAP */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LDAP_H */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#define HAVE_LIBRESOLV 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the `memmem' function. */ +#define HAVE_MEMMEM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mkdir' function. */ +#define HAVE_MKDIR 1 + +/* Do we have mysql support? */ +/* #undef HAVE_MYSQL */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Do we have OpenSSL? */ +#define HAVE_OPENSSL /**/ + +/* Use OPIE for server-side OTP? */ +/* #undef HAVE_OPIE */ + +/* Support for PAM? */ +/* #undef HAVE_PAM */ + +/* Define to 1 if you have the header file. */ +#define HAVE_PATHS_H 1 + +/* Do we have Postgres support? */ +/* #undef HAVE_PGSQL */ + +/* Include Support for pwcheck daemon? */ +/* #undef HAVE_PWCHECK */ + +/* Include support for saslauthd? */ +#define HAVE_SASLAUTHD /**/ + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Do we have SHA512? */ +#define HAVE_SHA512 /**/ + +/* Include SIA Support */ +/* #undef HAVE_SIA */ + +/* Does the system have snprintf()? */ +#define HAVE_SNPRINTF /**/ + +/* Does sockaddr have an sa_len? */ +/* #undef HAVE_SOCKADDR_SA_LEN */ + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Do we have a socklen_t? */ +#define HAVE_SOCKLEN_T /**/ + +/* Do we have SQLite support? */ +/* #undef HAVE_SQLITE */ + +/* Do we have SQLite3 support? */ +/* #undef HAVE_SQLITE3 */ + +/* Is there an ss_family in sockaddr_storage? */ +#define HAVE_SS_FAMILY /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +/* #undef HAVE_STRLCAT */ + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strspn' function. */ +#define HAVE_STRSPN 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Do we have struct sockaddr_stroage? */ +#define HAVE_STRUCT_SOCKADDR_STORAGE /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSEXITS_H 1 + +/* Define to 1 if you have the `syslog' function. */ +#define HAVE_SYSLOG 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VARARGS_H */ + +/* Does the system have vsnprintf()? */ +#define HAVE_VSNPRINTF /**/ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WS2TCPIP_H */ + +/* Should we keep handle to DB open in SASLDB plugin? */ +/* #undef KEEP_DB_OPEN */ + +/* Ignore IP Address in Kerberos 4 tickets? */ +/* #undef KRB4_IGNORE_IP_ADDRESS */ + +/* Using Heimdal */ +/* #undef KRB5_HEIMDAL */ + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "cyrus-sasl" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://github.com/cyrusimap/cyrus-sasl/issues" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "cyrus-sasl" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "cyrus-sasl 2.1.27" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "cyrus-sasl" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "http://www.cyrusimap.org" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.1.27" + +/* Where do we look for Courier authdaemond's socket? */ +#define PATH_AUTHDAEMON_SOCKET "/dev/null" + +/* Where do we look for saslauthd's socket? */ +#define PATH_SASLAUTHD_RUNDIR "/var/state/saslauthd" + +/* Force a preferred mechanism */ +/* #undef PREFER_MECH */ + +/* Location of pwcheck socket */ +/* #undef PWCHECKDIR */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Use BerkeleyDB for SASLdb */ +/* #undef SASL_BERKELEYDB */ + +/* Path to default SASLdb database */ +#define SASL_DB_PATH "/etc/sasldb2" + +/* File to use for source of randomness */ +#define SASL_DEV_RANDOM "/dev/urandom" + +/* Use GDBM for SASLdb */ +/* #undef SASL_GDBM */ + +/* Use LMDB for SASLdb */ +/* #undef SASL_LMDB */ + +/* Use NDBM for SASLdb */ +/* #undef SASL_NDBM */ + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* Link ANONYMOUS Statically */ +// #define STATIC_ANONYMOUS /**/ + +/* Link CRAM-MD5 Statically */ +// #define STATIC_CRAMMD5 /**/ + +/* Link DIGEST-MD5 Statically */ +// #define STATIC_DIGESTMD5 /**/ + +/* Link GSSAPI Statically */ +#define STATIC_GSSAPIV2 /**/ + +/* User KERBEROS_V4 Staticly */ +/* #undef STATIC_KERBEROS4 */ + +/* Link ldapdb plugin Statically */ +/* #undef STATIC_LDAPDB */ + +/* Link LOGIN Statically */ +/* #undef STATIC_LOGIN */ + +/* Link NTLM Statically */ +/* #undef STATIC_NTLM */ + +/* Link OTP Statically */ +// #define STATIC_OTP /**/ + +/* Link PASSDSS Statically */ +/* #undef STATIC_PASSDSS */ + +/* Link PLAIN Staticly */ +// #define STATIC_PLAIN /**/ + +/* Link SASLdb Staticly */ +// #define STATIC_SASLDB /**/ + +/* Link SCRAM Statically */ +// #define STATIC_SCRAM /**/ + +/* Link SQL plugin statically */ +/* #undef STATIC_SQL */ + +/* Link SRP Statically */ +/* #undef STATIC_SRP */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Should we try to dlopen() plugins while statically compiled? */ +/* #undef TRY_DLOPEN_WHEN_STATIC */ + +/* use the doors IPC API for saslauthd? */ +/* #undef USE_DOORS */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Version number of package */ +#define VERSION "2.1.27" + +/* Use DES */ +#define WITH_DES /**/ + +/* Linking against dmalloc? */ +/* #undef WITH_DMALLOC */ + +/* Use RC4 */ +#define WITH_RC4 /**/ + +/* Use OpenSSL DES Implementation */ +#define WITH_SSL_DES /**/ + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `int' if does not define. */ +/* #undef mode_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + + + + +/* Create a struct iovec if we need one */ +#if !defined(_WIN32) +#if !defined(HAVE_SYS_UIO_H) +/* (win32 is handled in sasl.h) */ +struct iovec { + char *iov_base; + long iov_len; +}; +#else +#include +#include +#endif +#endif + +/* location of the random number generator */ +#ifdef DEV_RANDOM +/* #undef DEV_RANDOM */ +#endif +#define DEV_RANDOM SASL_DEV_RANDOM + +/* if we've got krb_get_err_txt, we might as well use it; + especially since krb_err_txt isn't in some newer distributions + (MIT Kerb for Mac 4 being a notable example). If we don't have + it, we fall back to the krb_err_txt array */ +#ifdef HAVE_KRB_GET_ERR_TEXT +#define get_krb_err_txt krb_get_err_text +#else +#define get_krb_err_txt(X) (krb_err_txt[(X)]) +#endif + +/* Make Solaris happy... */ +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ 1 +#endif + +/* Make Linux happy... */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#define SASL_PATH_ENV_VAR "SASL_PATH" +#define SASL_CONF_PATH_ENV_VAR "SASL_CONF_PATH" + +#include +#include +#ifndef WIN32 +# include +# include +# include +# ifdef HAVE_SYS_PARAM_H +# include +# endif +#else /* WIN32 */ +# include +#endif /* WIN32 */ +#include + +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +#endif /* HAVE_SOCKLEN_T */ + +#if !defined(HAVE_STRUCT_SOCKADDR_STORAGE) && !defined(WIN32) +#define _SS_MAXSIZE 128 /* Implementation specific max size */ +#define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) + +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#ifndef HAVE_GETADDRINFO +#define getaddrinfo sasl_getaddrinfo +#define freeaddrinfo sasl_freeaddrinfo +#define gai_strerror sasl_gai_strerror +#endif + +#ifndef HAVE_GETNAMEINFO +#define getnameinfo sasl_getnameinfo +#endif + +#if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO) +#include "gai.h" +#endif + +#ifndef AI_NUMERICHOST /* support glibc 2.0.x */ +#define AI_NUMERICHOST 4 +#define NI_NUMERICHOST 2 +#define NI_NAMEREQD 4 +#define NI_NUMERICSERV 8 +#endif + +#ifndef HAVE_SYSEXITS_H +#include "exits.h" +#else +#include "sysexits.h" +#endif + +/* Get the correct time.h */ +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifndef HIER_DELIMITER +#define HIER_DELIMITER '/' +#endif + +#ifdef WIN32 +#define SASL_ROOT_KEY "SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library" +#define SASL_PLUGIN_PATH_ATTR "SearchPath" +#define SASL_CONF_PATH_ATTR "ConfFile" + +#include +inline static unsigned int sleep(unsigned int seconds) { + Sleep(seconds * 1000); + return 0; +} +#endif + +/* handy string manipulation functions */ +#ifndef HAVE_STRLCPY +extern size_t saslauthd_strlcpy(char *dst, const char *src, size_t len); +#define strlcpy(x,y,z) saslauthd_strlcpy((x),(y),(z)) +#endif +#ifndef HAVE_STRLCAT +extern size_t saslauthd_strlcat(char *dst, const char *src, size_t len); +#define strlcat(x,y,z) saslauthd_strlcat((x),(y),(z)) +#endif +#ifndef HAVE_ASPRINTF +extern int asprintf(char **str, const char *fmt, ...); +#endif + +#endif /* CONFIG_H */ + + +#if defined __GNUC__ && __GNUC__ > 6 + #define GCC_FALLTHROUGH __attribute__((fallthrough)); +#else + #define GCC_FALLTHROUGH /* fall through */ +#endif diff --git a/contrib/krb5 b/contrib/krb5 new file mode 160000 index 00000000000..99f7ad2831a --- /dev/null +++ b/contrib/krb5 @@ -0,0 +1 @@ +Subproject commit 99f7ad2831a01f264c07eed42a0a3a9336b86184 diff --git a/contrib/krb5-cmake/CMakeLists.txt b/contrib/krb5-cmake/CMakeLists.txt new file mode 100644 index 00000000000..059e2b4a46a --- /dev/null +++ b/contrib/krb5-cmake/CMakeLists.txt @@ -0,0 +1,670 @@ +find_program(AWK_PROGRAM awk) +if(NOT AWK_PROGRAM) + message(FATAL_ERROR "You need the awk program to build ClickHouse with krb5 enabled.") +endif() + +set(KRB5_SOURCE_DIR ${ClickHouse_SOURCE_DIR}/contrib/krb5/src) + +set(ALL_SRCS + ${KRB5_SOURCE_DIR}/util/et/et_name.c + ${KRB5_SOURCE_DIR}/util/et/com_err.c + ${KRB5_SOURCE_DIR}/util/et/error_message.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_inq_names.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_rel_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_unwrap_aead.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_set_name_attr.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_glue.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_imp_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/gssd_pname_to_uid.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_authorize_localname.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_prf.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_acquire_cred_with_pw.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_set_cred_option.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_map_name_to_any.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_inq_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_rel_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_seal.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_delete_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_context_time.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_get_name_attr.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_mech_invoke.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_unwrap_iov.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_exp_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_init_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_accept_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_verify.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_sign.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_mechname.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_mechattr.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_complete_auth_token.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_wrap_aead.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_inq_cred_oid.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_rel_buffer.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_initialize.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_export_name_comp.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_set_context_option.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_acquire_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_acquire_cred_imp_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_imp_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_inq_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_set_neg_mechs.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_inq_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_export_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_oid_ops.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_inq_context_oid.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_del_name_attr.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_decapsulate_token.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_compare_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_rel_name_mapping.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_imp_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_dup_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_export_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_wrap_iov.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_rel_oid_set.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_unseal.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_store_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_buffer_set.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_canon_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_dsp_status.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_dsp_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_dsp_name_ext.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_saslname.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_process_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_encapsulate_token.c + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue/g_negoex.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/delete_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/lucid_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/duplicate_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/get_tkt_flags.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/set_allowable_enctypes.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/k5sealiov.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/gssapi_err_krb5.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/canon_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/inq_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/export_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/inq_names.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/prf.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/k5sealv3iov.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/store_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/import_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/export_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/naming_exts.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/s4u_gss_glue.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/rel_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/k5unsealiov.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/gssapi_krb5.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/disp_status.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/import_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/k5seal.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/accept_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/import_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/process_context_token.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/disp_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/wrap_size_limit.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/krb5_gss_glue.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/util_crypt.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/set_ccache.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/export_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/rel_oid.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/val_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/context_time.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/cred_store.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/iakerb.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/copy_ccache.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/init_sec_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/indicate_mechs.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/inq_context.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/util_seed.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/util_seqnum.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/compare_name.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/ser_sctx.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/k5sealv3.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/acquire_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/k5unseal.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/rel_cred.c + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/util_cksum.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/disp_com_err_status.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/gssapi_generic.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/rel_oid_set.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/oid_ops.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/util_buffer.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/util_buffer_set.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/util_set.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/util_token.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/gssapi_err_generic.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/disp_major_status.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/util_seqstate.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/util_errmap.c + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/rel_buffer.c + + ${KRB5_SOURCE_DIR}/lib/gssapi/spnego/spnego_mech.c + ${KRB5_SOURCE_DIR}/lib/gssapi/spnego/negoex_util.c + ${KRB5_SOURCE_DIR}/lib/gssapi/spnego/negoex_ctx.c + + # ${KRB5_SOURCE_DIR}/lib/gssapi/spnego/negoex_trace.c + + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prng.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/enc_dk_cmac.c + # ${KRB5_SOURCE_DIR}/lib/crypto/krb/crc32.c + # ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_cbc.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/enctype_util.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/enc_etm.c + # ${KRB5_SOURCE_DIR}/lib/crypto/krb/combine_keys.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/default_state.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/decrypt_iov.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_dk_cmac.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/etypes.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/old_api_glue.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/cksumtypes.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prf_cmac.c + # ${KRB5_SOURCE_DIR}/lib/crypto/krb/enc_old.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/decrypt.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prf_dk.c + # ${KRB5_SOURCE_DIR}/lib/crypto/krb/s2k_des.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_unkeyed.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/crypto_length.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/block_size.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/string_to_key.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/verify_checksum.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/crypto_libinit.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/derive.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/random_to_key.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/verify_checksum_iov.c + # ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_confounder.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_length.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/enc_dk_hmac.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/make_checksum.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prf_des.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prf.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/coll_proof_cksum.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/enc_rc4.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/cf2.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/aead.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/encrypt_iov.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/cksumtype_to_string.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/key.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/enc_raw.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/keylengths.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_hmac_md5.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/keyed_cksum.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/keyed_checksum_types.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prf_aes2.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/state.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_dk_hmac.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/encrypt.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/checksum_etm.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/make_random_key.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/string_to_cksumtype.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/mandatory_sumtype.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/make_checksum_iov.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/s2k_rc4.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/valid_cksumtype.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/nfold.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prng_fortuna.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/encrypt_length.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/cmac.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/keyblocks.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/prf_rc4.c + ${KRB5_SOURCE_DIR}/lib/crypto/krb/s2k_pbkdf2.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/enc_provider/aes.c + # ${KRB5_SOURCE_DIR}/lib/crypto/openssl/enc_provider/des.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/enc_provider/rc4.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/enc_provider/des3.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/enc_provider/camellia.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/sha256.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/hmac.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/pbkdf2.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/init.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/stubs.c + # ${KRB5_SOURCE_DIR}/lib/crypto/openssl/hash_provider/hash_crc32.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/hash_provider/hash_evp.c + ${KRB5_SOURCE_DIR}/lib/crypto/openssl/des/des_keys.c + ${KRB5_SOURCE_DIR}/util/support/fake-addrinfo.c + ${KRB5_SOURCE_DIR}/util/support/k5buf.c + ${KRB5_SOURCE_DIR}/util/support/hex.c + ${KRB5_SOURCE_DIR}/util/support/threads.c + ${KRB5_SOURCE_DIR}/util/support/utf8.c + ${KRB5_SOURCE_DIR}/util/support/hashtab.c + ${KRB5_SOURCE_DIR}/util/support/dir_filenames.c + ${KRB5_SOURCE_DIR}/util/support/base64.c + ${KRB5_SOURCE_DIR}/util/support/strerror_r.c + ${KRB5_SOURCE_DIR}/util/support/plugins.c + ${KRB5_SOURCE_DIR}/util/support/path.c + ${KRB5_SOURCE_DIR}/util/support/init-addrinfo.c + ${KRB5_SOURCE_DIR}/util/support/json.c + ${KRB5_SOURCE_DIR}/util/support/errors.c + ${KRB5_SOURCE_DIR}/util/support/utf8_conv.c + ${KRB5_SOURCE_DIR}/util/support/strlcpy.c + ${KRB5_SOURCE_DIR}/util/support/gmt_mktime.c + ${KRB5_SOURCE_DIR}/util/support/zap.c + ${KRB5_SOURCE_DIR}/util/support/bcmp.c + ${KRB5_SOURCE_DIR}/util/support/secure_getenv.c + ${KRB5_SOURCE_DIR}/util/profile/prof_tree.c + ${KRB5_SOURCE_DIR}/util/profile/prof_file.c + ${KRB5_SOURCE_DIR}/util/profile/prof_parse.c + ${KRB5_SOURCE_DIR}/util/profile/prof_get.c + ${KRB5_SOURCE_DIR}/util/profile/prof_set.c + ${KRB5_SOURCE_DIR}/util/profile/prof_err.c + ${KRB5_SOURCE_DIR}/util/profile/prof_init.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/fwd_tgt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/conv_creds.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/fast.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_adata.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_tick.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/enc_keyhelper.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_actx.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/init_ctx.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/preauth2.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_princ.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/parse_host_string.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/pr_to_salt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_req.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/pac_sign.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_addrs.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/conv_princ.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_rep.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/str_conv.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gic_opt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/recvauth.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_cksum.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ai_authdata.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_ctx.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/appdefault.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/bld_princ.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/in_tkt_sky.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_creds.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/auth_con.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_key.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/kdc_rep_dc.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_cred.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gic_keytab.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_req_dec.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/set_realm.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/preauth_sam2.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/libdef_parse.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/privsafe.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_auth.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/val_renew.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/addr_order.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/authdata_dec.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/walk_rtree.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gen_subkey.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_auth.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/chpw.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_req.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/allow_weak.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_rep.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_priv.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/s4u_authdata.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/preauth_otp.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/init_keyblock.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_addr.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/encrypt_tk.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/s4u_creds.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/srv_dec_tkt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_priv.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/authdata_enc.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/authdata_exp.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/decode_kdc.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/decrypt_tk.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/enc_helper.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_req_ext.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_key.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/preauth_encts.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/send_tgs.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_cksum.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/tgtname.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/encode_kdc.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_cred.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_safe.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/preauth_pkinit.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/srv_rcache.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/chk_trans.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/etype_list.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/get_creds.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/ser_princ.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gic_pwd.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/authdata.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gen_save_subkey.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/vfy_increds.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/addr_comp.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/kfree.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/response_items.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/serialize.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/cammac_util.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gc_via_tkt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_ctx.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/sendauth.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/addr_srch.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_safe.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/preauth_ec.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/bld_pr_ext.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/random_str.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/sname_match.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/princ_comp.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/get_in_tkt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/gen_seqnum.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/cp_key_cnt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/mk_error.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_athctr.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/deltat.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/get_etype_info.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/plugin.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/kerrs.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/vic_opt.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/unparse.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/parse.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/rd_error.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/pac.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/valid_times.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/copy_data.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb/padata.c + + + ${KRB5_SOURCE_DIR}/lib/krb5/os/hostrealm.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/thread_safe.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/krbfileio.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/toffset.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/hostaddr.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/ustime.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/timeofday.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/ccdefname.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/full_ipadr.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/read_pwd.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/trace.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/localauth_k5login.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/localauth_rule.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/localaddr.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/hostrealm_dns.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/hostrealm_domain.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/sn2princ.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/net_write.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/gen_rname.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/net_read.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/accessor.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/hostrealm_profile.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/c_ustime.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/expand_path.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/port2ip.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/changepw.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/unlck_file.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/gen_port.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/localauth_an2ln.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/genaddrs.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/init_os_ctx.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/localauth.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/locate_kdc.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/prompter.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/ktdefname.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/realm_dom.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/dnssrv.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/mk_faddr.c + # ${KRB5_SOURCE_DIR}/lib/krb5/os/dnsglue.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/sendto_kdc.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/hostrealm_registry.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/write_msg.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/localauth_names.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/read_msg.c + ${KRB5_SOURCE_DIR}/lib/krb5/os/lock_file.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccselect.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccselect_realm.c + # ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ser_cc.c + + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccdefops.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cc_retr.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccselect_k5identity.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cccopy.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccfns.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cc_file.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccbase.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cccursor.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccdefault.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cc_memory.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccmarshal.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccselect_hostname.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cc_dir.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cc_keyring.c + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/cc_kcm.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/ktadd.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/ktbase.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/ktdefault.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/kt_memory.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/ktfns.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/ktremove.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/read_servi.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/kt_file.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/read_servi.c + ${KRB5_SOURCE_DIR}/lib/krb5/keytab/ktfr_entry.c + + + + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/k5e1_err.c + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/kdb5_err.c + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/asn1_err.c + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/krb5_err.c + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/krb524_err.c + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/kv5m_err.c + + + + ${KRB5_SOURCE_DIR}/lib/krb5/rcache/rc_base.c + ${KRB5_SOURCE_DIR}/lib/krb5/rcache/rc_dfl.c + ${KRB5_SOURCE_DIR}/lib/krb5/rcache/rc_file2.c + ${KRB5_SOURCE_DIR}/lib/krb5/rcache/rc_none.c + ${KRB5_SOURCE_DIR}/lib/krb5/rcache/memrcache.c + ${KRB5_SOURCE_DIR}/lib/krb5/unicode/ucdata/ucdata.c + ${KRB5_SOURCE_DIR}/lib/krb5/unicode/ucstr.c + ${KRB5_SOURCE_DIR}/lib/krb5/asn.1/asn1_encode.c + ${KRB5_SOURCE_DIR}/lib/krb5/asn.1/asn1_k_encode.c + ${KRB5_SOURCE_DIR}/lib/krb5/asn.1/ldap_key_seq.c + ${KRB5_SOURCE_DIR}/lib/krb5/krb5_libinit.c +) + +add_custom_command( + OUTPUT ${KRB5_SOURCE_DIR}/util/et/compile_et + COMMAND /bin/sh + ./config_script + ./compile_et.sh + "/usr/local/share/et" + ${AWK_PROGRAM} + sed + > + compile_et + DEPENDS ${KRB5_SOURCE_DIR}/util/et/compile_et.sh ${KRB5_SOURCE_DIR}/util/et/config_script + WORKING_DIRECTORY "${KRB5_SOURCE_DIR}/util/et" +) + +add_custom_target( + CREATE_COMPILE_ET ALL + DEPENDS ${KRB5_SOURCE_DIR}/util/et/compile_et + COMMENT "creating compile_et" + VERBATIM +) + +file(GLOB_RECURSE ET_FILES + "${KRB5_SOURCE_DIR}/*.et" +) + +function(preprocess_et out_var) + set(result) + foreach(in_f ${ARGN}) + string(REPLACE + .et + .c + F_C + ${in_f} + ) + string(REPLACE + .et + .h + F_H + ${in_f} + ) + + get_filename_component(ET_PATH ${in_f} DIRECTORY) + + add_custom_command(OUTPUT ${F_C} ${F_H} + COMMAND perl ${KRB5_SOURCE_DIR}/util/et/compile_et -d "${KRB5_SOURCE_DIR}/util/et" ${in_f} + DEPENDS ${in_f} ${KRB5_SOURCE_DIR}/util/et/compile_et + WORKING_DIRECTORY ${ET_PATH} + COMMENT "Creating preprocessed file ${F_C}" + VERBATIM + ) + list(APPEND result ${F_C}) + endforeach() + set(${out_var} "${result}" PARENT_SCOPE) +endfunction() + +add_custom_command( + OUTPUT ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/error_map.h + COMMAND perl + -I../../../util + ../../../util/gen-map.pl + -oerror_map.h + NAME=gsserrmap + KEY=OM_uint32 + VALUE=char* + COMPARE=compare_OM_uint32 + FREEVALUE=free_string + WORKING_DIRECTORY "${KRB5_SOURCE_DIR}/lib/gssapi/krb5" +) + + +add_custom_target( + ERROR_MAP_H ALL + DEPENDS ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/error_map.h + COMMENT "generating error_map.h" + VERBATIM +) + +add_custom_command( + OUTPUT ${KRB5_SOURCE_DIR}/lib/gssapi/generic/errmap.h + COMMAND perl -w -I../../../util ../../../util/gen.pl bimap errmap.h NAME=mecherrmap LEFT=OM_uint32 RIGHT=struct\ mecherror LEFTPRINT=print_OM_uint32 RIGHTPRINT=mecherror_print LEFTCMP=cmp_OM_uint32 RIGHTCMP=mecherror_cmp + WORKING_DIRECTORY "${KRB5_SOURCE_DIR}/lib/gssapi/generic" +) + +add_custom_target( + ERRMAP_H ALL + DEPENDS ${KRB5_SOURCE_DIR}/lib/gssapi/generic/errmap.h + COMMENT "generating errmap.h" + VERBATIM +) + +add_custom_target( + KRB_5_H ALL + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/include/krb5/krb5.h + COMMENT "generating krb5.h" + VERBATIM +) + +add_library(${KRB5_LIBRARY}) + +add_dependencies( + ${KRB5_LIBRARY} + ERRMAP_H + ERROR_MAP_H + KRB_5_H + ) + +preprocess_et(processed_et_files ${ET_FILES}) + +add_custom_command( + OUTPUT ${KRB5_SOURCE_DIR}/lib/gssapi/generic/errmap.h + COMMAND perl -w -I../../../util ../../../util/gen.pl bimap errmap.h NAME=mecherrmap LEFT=OM_uint32 RIGHT=struct\ mecherror LEFTPRINT=print_OM_uint32 RIGHTPRINT=mecherror_print LEFTCMP=cmp_OM_uint32 RIGHTCMP=mecherror_cmp + WORKING_DIRECTORY "${KRB5_SOURCE_DIR}/lib/gssapi/generic" +) + +target_sources(${KRB5_LIBRARY} PRIVATE + ${ALL_SRCS} +) + +file(MAKE_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR}/include/gssapi +) + +file(GLOB GSSAPI_GENERIC_HEADERS + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/*.h + ${KRB5_SOURCE_DIR}/lib/gssapi/generic/gssapi.hin +) + +file(COPY ${GSSAPI_GENERIC_HEADERS} + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/gssapi/ +) + +file(RENAME + ${CMAKE_CURRENT_BINARY_DIR}/include/gssapi/gssapi.hin + ${CMAKE_CURRENT_BINARY_DIR}/include/gssapi/gssapi.h +) + +file(COPY ${KRB5_SOURCE_DIR}/lib/gssapi/krb5/gssapi_krb5.h + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/gssapi/ +) + +file(COPY ${KRB5_SOURCE_DIR}/util/et/com_err.h + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/include/ +) + +file(MAKE_DIRECTORY + ${CMAKE_CURRENT_BINARY_DIR}/include/krb5 +) + +SET(KRBHDEP + ${KRB5_SOURCE_DIR}/include/krb5/krb5.hin + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/krb5_err.h + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/k5e1_err.h + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/kdb5_err.h + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/kv5m_err.h + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/krb524_err.h + ${KRB5_SOURCE_DIR}/lib/krb5/error_tables/asn1_err.h +) + +# cmake < 3.18 does not have 'cat' command +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/krb5/krb5.h + COMMAND cat ${KRBHDEP} > ${CMAKE_CURRENT_BINARY_DIR}/include/krb5/krb5.h + DEPENDS ${KRBHDEP} +) + + + +target_include_directories(${KRB5_LIBRARY} PUBLIC + ${KRB5_SOURCE_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include +) + +target_include_directories(${KRB5_LIBRARY} PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} #for autoconf.h + ${KRB5_SOURCE_DIR} + ${KRB5_SOURCE_DIR}/include + ${KRB5_SOURCE_DIR}/lib/gssapi/mechglue + ${KRB5_SOURCE_DIR}/lib/ + ${KRB5_SOURCE_DIR}/lib/gssapi + ${KRB5_SOURCE_DIR}/lib/gssapi/generic + ${KRB5_SOURCE_DIR}/lib/gssapi/krb5 + ${KRB5_SOURCE_DIR}/lib/gssapi/spnego + ${KRB5_SOURCE_DIR}/util/et + ${KRB5_SOURCE_DIR}/lib/crypto/openssl + ${KRB5_SOURCE_DIR}/lib/crypto/krb + ${KRB5_SOURCE_DIR}/util/profile + ${KRB5_SOURCE_DIR}/lib/krb5/ccache/ccapi + ${KRB5_SOURCE_DIR}/lib/krb5/ccache + ${KRB5_SOURCE_DIR}/lib/krb5/keytab + ${KRB5_SOURCE_DIR}/lib/krb5/rcache + ${KRB5_SOURCE_DIR}/lib/krb5/unicode + ${KRB5_SOURCE_DIR}/lib/krb5/os + # ${OPENSSL_INCLUDE_DIR} +) + +target_compile_definitions(${KRB5_LIBRARY} PRIVATE + KRB5_PRIVATE + _GSS_STATIC_LINK=1 + KRB5_DEPRECATED=1 + LOCALEDIR="/usr/local/share/locale" + BINDIR="/usr/local/bin" + SBINDIR="/usr/local/sbin" + LIBDIR="/usr/local/lib" +) + +target_link_libraries(${KRB5_LIBRARY} + PRIVATE ${OPENSSL_CRYPTO_LIBRARY} +) diff --git a/contrib/krb5-cmake/autoconf.h b/contrib/krb5-cmake/autoconf.h new file mode 100644 index 00000000000..7b71d962d9a --- /dev/null +++ b/contrib/krb5-cmake/autoconf.h @@ -0,0 +1,764 @@ +/* include/autoconf.h. Generated from autoconf.h.in by configure. */ +/* include/autoconf.h.in. Generated from configure.in by autoheader. */ + + +#ifndef KRB5_AUTOCONF_H +#define KRB5_AUTOCONF_H + + +/* Define if AES-NI support is enabled */ +/* #undef AESNI */ + +/* Define if socket can't be bound to 0.0.0.0 */ +/* #undef BROKEN_STREAMS_SOCKETS */ + +/* Define if va_list objects can be simply copied by assignment. */ +/* #undef CAN_COPY_VA_LIST */ + +/* Define to reduce code size even if it means more cpu usage */ +/* #undef CONFIG_SMALL */ + +/* Define if __attribute__((constructor)) works */ +#define CONSTRUCTOR_ATTR_WORKS 1 + +/* Define to default ccache name */ +#define DEFCCNAME "FILE:/tmp/krb5cc_%{uid}" + +/* Define to default client keytab name */ +#define DEFCKTNAME "FILE:/etc/krb5/user/%{euid}/client.keytab" + +/* Define to default keytab name */ +#define DEFKTNAME "FILE:/etc/krb5.keytab" + +/* Define if library initialization should be delayed until first use */ +#define DELAY_INITIALIZER 1 + +/* Define if __attribute__((destructor)) works */ +#define DESTRUCTOR_ATTR_WORKS 1 + +/* Define to disable PKINIT plugin support */ +/* #undef DISABLE_PKINIT */ + +/* Define if LDAP KDB support within the Kerberos library (mainly ASN.1 code) + should be enabled. */ +/* #undef ENABLE_LDAP */ + +/* Define if translation functions should be used. */ +#define ENABLE_NLS 1 + +/* Define if thread support enabled */ +#define ENABLE_THREADS 1 + +/* Define as return type of endrpcent */ +#define ENDRPCENT_TYPE void + +/* Define if Fortuna PRNG is selected */ +#define FORTUNA 1 + +/* Define to the type of elements in the array set by `getgroups'. Usually + this is either `int' or `gid_t'. */ +#define GETGROUPS_T gid_t + +/* Define if gethostbyname_r returns int rather than struct hostent * */ +#define GETHOSTBYNAME_R_RETURNS_INT 1 + +/* Type of getpeername second argument. */ +#define GETPEERNAME_ARG3_TYPE GETSOCKNAME_ARG3_TYPE + +/* Define if getpwnam_r exists but takes only 4 arguments (e.g., POSIX draft 6 + implementations like some Solaris releases). */ +/* #undef GETPWNAM_R_4_ARGS */ + +/* Define if getpwnam_r returns an int */ +#define GETPWNAM_R_RETURNS_INT 1 + +/* Define if getpwuid_r exists but takes only 4 arguments (e.g., POSIX draft 6 + implementations like some Solaris releases). */ +/* #undef GETPWUID_R_4_ARGS */ + +/* Define if getservbyname_r returns int rather than struct servent * */ +#define GETSERVBYNAME_R_RETURNS_INT 1 + +/* Type of pointer target for argument 3 to getsockname */ +#define GETSOCKNAME_ARG3_TYPE socklen_t + +/* Define if gmtime_r returns int instead of struct tm pointer, as on old + HP-UX systems. */ +/* #undef GMTIME_R_RETURNS_INT */ + +/* Define if va_copy macro or function is available. */ +#define HAS_VA_COPY 1 + +/* Define to 1 if you have the `access' function. */ +#define HAVE_ACCESS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the `bswap16' function. */ +/* #undef HAVE_BSWAP16 */ + +/* Define to 1 if you have the `bswap64' function. */ +/* #undef HAVE_BSWAP64 */ + +/* Define to 1 if bswap_16 is available via byteswap.h */ +#define HAVE_BSWAP_16 1 + +/* Define to 1 if bswap_64 is available via byteswap.h */ +#define HAVE_BSWAP_64 1 + +/* Define if bt_rseq is available, for recursive btree traversal. */ +#define HAVE_BT_RSEQ 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_BYTESWAP_H 1 + +/* Define to 1 if you have the `chmod' function. */ +#define HAVE_CHMOD 1 + +/* Define if cmocka library is available. */ +/* #undef HAVE_CMOCKA */ + +/* Define to 1 if you have the `compile' function. */ +/* #undef HAVE_COMPILE */ + +/* Define if com_err has compatible gettext support */ +#define HAVE_COM_ERR_INTL 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_CPUID_H */ + +/* Define to 1 if you have the `daemon' function. */ +#define HAVE_DAEMON 1 + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#define HAVE_DECL_STRERROR_R 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dn_skipname' function. */ +#define HAVE_DN_SKIPNAME 0 + +/* Define to 1 if you have the header file. */ +#define HAVE_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `fchmod' function. */ +#define HAVE_FCHMOD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `flock' function. */ +#define HAVE_FLOCK 1 + +/* Define to 1 if you have the `fnmatch' function. */ +#define HAVE_FNMATCH 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FNMATCH_H 1 + +/* Define if you have the getaddrinfo function */ +#define HAVE_GETADDRINFO 1 + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `getenv' function. */ +#define HAVE_GETENV 1 + +/* Define to 1 if you have the `geteuid' function. */ +#define HAVE_GETEUID 1 + +/* Define if gethostbyname_r exists and its return type is known */ +#define HAVE_GETHOSTBYNAME_R 1 + +/* Define to 1 if you have the `getnameinfo' function. */ +#define HAVE_GETNAMEINFO 1 + +/* Define if system getopt should be used. */ +#define HAVE_GETOPT 1 + +/* Define if system getopt_long should be used. */ +#define HAVE_GETOPT_LONG 1 + +/* Define if getpwnam_r is available and useful. */ +#define HAVE_GETPWNAM_R 1 + +/* Define if getpwuid_r is available and useful. */ +#define HAVE_GETPWUID_R 1 + +/* Define if getservbyname_r exists and its return type is known */ +#define HAVE_GETSERVBYNAME_R 1 + +/* Have the gettimeofday function */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `getusershell' function. */ +#define HAVE_GETUSERSHELL 1 + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the `inet_ntop' function. */ +#define HAVE_INET_NTOP 1 + +/* Define to 1 if you have the `inet_pton' function. */ +#define HAVE_INET_PTON 1 + +/* Define to 1 if the system has the type `int16_t'. */ +#define HAVE_INT16_T 1 + +/* Define to 1 if the system has the type `int32_t'. */ +#define HAVE_INT32_T 1 + +/* Define to 1 if the system has the type `int8_t'. */ +#define HAVE_INT8_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_KEYUTILS_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LBER_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LDAP_H */ + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#define HAVE_LIBCRYPTO 1 + +/* Define if building with libedit. */ +/* #undef HAVE_LIBEDIT */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#define HAVE_LIBRESOLV 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define if the util library is available */ +#define HAVE_LIBUTIL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACHINE_BYTE_ORDER_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACHINE_ENDIAN_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mkstemp' function. */ +#define HAVE_MKSTEMP 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_NETDB_H 1 + +/* Define if netdb.h declares h_errno */ +#define HAVE_NETDB_H_H_ERRNO 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the `ns_initparse' function. */ +#define HAVE_NS_INITPARSE 0 + +/* Define to 1 if you have the `ns_name_uncompress' function. */ +#define HAVE_NS_NAME_UNCOMPRESS 0 + +/* Define if OpenSSL supports cms. */ +#define HAVE_OPENSSL_CMS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PATHS_H 1 + +/* Define if persistent keyrings are supported */ +/* #undef HAVE_PERSISTENT_KEYRING */ + +/* Define to 1 if you have the header file. */ +#define HAVE_POLL_H 1 + +/* Define if #pragma weak references work */ +#define HAVE_PRAGMA_WEAK_REF 1 + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the `pthread_once' function. */ +/* #undef HAVE_PTHREAD_ONCE */ + +/* Have PTHREAD_PRIO_INHERIT. */ +#define HAVE_PTHREAD_PRIO_INHERIT 1 + +/* Define to 1 if you have the `pthread_rwlock_init' function. */ +/* #undef HAVE_PTHREAD_RWLOCK_INIT */ + +/* Define if pthread_rwlock_init is provided in the thread library. */ +#define HAVE_PTHREAD_RWLOCK_INIT_IN_THREAD_LIB 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* Define if building with GNU Readline. */ +/* #undef HAVE_READLINE */ + +/* Define if regcomp exists and functions */ +#define HAVE_REGCOMP 1 + +/* Define to 1 if you have the `regexec' function. */ +#define HAVE_REGEXEC 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_REGEXPR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_REGEX_H 1 + +/* Define to 1 if you have the `res_nclose' function. */ +#define HAVE_RES_NCLOSE 1 + +/* Define to 1 if you have the `res_ndestroy' function. */ +/* #undef HAVE_RES_NDESTROY */ + +/* Define to 1 if you have the `res_ninit' function. */ +#define HAVE_RES_NINIT 1 + +/* Define to 1 if you have the `res_nsearch' function. */ +#define HAVE_RES_NSEARCH 0 + +/* Define to 1 if you have the `res_search' function */ +#define HAVE_RES_SEARCH 1 + +/* Define to 1 if you have the `re_comp' function. */ +#define HAVE_RE_COMP 1 + +/* Define to 1 if you have the `re_exec' function. */ +#define HAVE_RE_EXEC 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SASL_SASL_H */ + +/* Define if struct sockaddr contains sa_len */ +/* #undef HAVE_SA_LEN */ + +/* Define to 1 if you have the `setegid' function. */ +#define HAVE_SETEGID 1 + +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the `seteuid' function. */ +#define HAVE_SETEUID 1 + +/* Define if setluid provided in OSF/1 security library */ +/* #undef HAVE_SETLUID */ + +/* Define to 1 if you have the `setregid' function. */ +#define HAVE_SETREGID 1 + +/* Define to 1 if you have the `setresgid' function. */ +#define HAVE_SETRESGID 1 + +/* Define to 1 if you have the `setresuid' function. */ +#define HAVE_SETRESUID 1 + +/* Define to 1 if you have the `setreuid' function. */ +#define HAVE_SETREUID 1 + +/* Define to 1 if you have the `setsid' function. */ +#define HAVE_SETSID 1 + +/* Define to 1 if you have the `setvbuf' function. */ +#define HAVE_SETVBUF 1 + +/* Define if there is a socklen_t type. If not, probably use size_t */ +#define HAVE_SOCKLEN_T 1 + +/* Define to 1 if you have the `srand' function. */ +#define HAVE_SRAND 1 + +/* Define to 1 if you have the `srand48' function. */ +#define HAVE_SRAND48 1 + +/* Define to 1 if you have the `srandom' function. */ +#define HAVE_SRANDOM 1 + +/* Define to 1 if the system has the type `ssize_t'. */ +#define HAVE_SSIZE_T 1 + +/* Define to 1 if you have the `stat' function. */ +#define HAVE_STAT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `step' function. */ +/* #undef HAVE_STEP */ + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcpy' function. */ +/* #undef HAVE_STRLCPY */ + +/* Define to 1 if you have the `strptime' function. */ +#define HAVE_STRPTIME 1 + +/* Define to 1 if the system has the type `struct cmsghdr'. */ +#define HAVE_STRUCT_CMSGHDR 1 + +/* Define if there is a struct if_laddrconf. */ +/* #undef HAVE_STRUCT_IF_LADDRCONF */ + +/* Define to 1 if the system has the type `struct in6_pktinfo'. */ +#define HAVE_STRUCT_IN6_PKTINFO 1 + +/* Define to 1 if the system has the type `struct in_pktinfo'. */ +#define HAVE_STRUCT_IN_PKTINFO 1 + +/* Define if there is a struct lifconf. */ +/* #undef HAVE_STRUCT_LIFCONF */ + +/* Define to 1 if the system has the type `struct rt_msghdr'. */ +/* #undef HAVE_STRUCT_RT_MSGHDR */ + +/* Define to 1 if the system has the type `struct sockaddr_storage'. */ +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 + +/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_MTIMENSEC */ + +/* Define to 1 if `st_mtimespec.tv_nsec' is a member of `struct stat'. */ +/* #undef HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC */ + +/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BSWAP_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define if sys_errlist in libc */ +#define HAVE_SYS_ERRLIST 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_FILIO_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SELECT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_SOCKIO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if tcl.h found */ +/* #undef HAVE_TCL_H */ + +/* Define if tcl/tcl.h found */ +/* #undef HAVE_TCL_TCL_H */ + +/* Define to 1 if you have the `timegm' function. */ +#define HAVE_TIMEGM 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `unsetenv' function. */ +#define HAVE_UNSETENV 1 + +/* Define to 1 if the system has the type `u_char'. */ +#define HAVE_U_CHAR 1 + +/* Define to 1 if the system has the type `u_int'. */ +#define HAVE_U_INT 1 + +/* Define to 1 if the system has the type `u_int16_t'. */ +#define HAVE_U_INT16_T 1 + +/* Define to 1 if the system has the type `u_int32_t'. */ +#define HAVE_U_INT32_T 1 + +/* Define to 1 if the system has the type `u_int8_t'. */ +#define HAVE_U_INT8_T 1 + +/* Define to 1 if the system has the type `u_long'. */ +#define HAVE_U_LONG 1 + +/* Define to 1 if you have the `vasprintf' function. */ +#define HAVE_VASPRINTF 1 + +/* Define to 1 if you have the `vsnprintf' function. */ +#define HAVE_VSNPRINTF 1 + +/* Define to 1 if you have the `vsprintf' function. */ +#define HAVE_VSPRINTF 1 + +/* Define to 1 if the system has the type `__int128_t'. */ +#define HAVE___INT128_T 1 + +/* Define to 1 if the system has the type `__uint128_t'. */ +#define HAVE___UINT128_T 1 + +/* Define if errno.h declares perror */ +/* #undef HDR_HAS_PERROR */ + +/* May need to be defined to enable IPv6 support, for example on IRIX */ +/* #undef INET6 */ + +/* Define if MIT Project Athena default configuration should be used */ +/* #undef KRB5_ATHENA_COMPAT */ + +/* Define for DNS support of locating realms and KDCs */ +#undef KRB5_DNS_LOOKUP + +/* Define to enable DNS lookups of Kerberos realm names */ +/* #undef KRB5_DNS_LOOKUP_REALM */ + +/* Define if the KDC should return only vague error codes to clients */ +/* #undef KRBCONF_VAGUE_ERRORS */ + +/* define if the system header files are missing prototype for daemon() */ +/* #undef NEED_DAEMON_PROTO */ + +/* Define if in6addr_any is not defined in libc */ +/* #undef NEED_INSIXADDR_ANY */ + +/* define if the system header files are missing prototype for + ss_execute_command() */ +/* #undef NEED_SS_EXECUTE_COMMAND_PROTO */ + +/* define if the system header files are missing prototype for strptime() */ +/* #undef NEED_STRPTIME_PROTO */ + +/* define if the system header files are missing prototype for swab() */ +/* #undef NEED_SWAB_PROTO */ + +/* Define if need to declare sys_errlist */ +/* #undef NEED_SYS_ERRLIST */ + +/* define if the system header files are missing prototype for vasprintf() */ +/* #undef NEED_VASPRINTF_PROTO */ + +/* Define if the KDC should use no lookaside cache */ +/* #undef NOCACHE */ + +/* Define if references to pthread routines should be non-weak. */ +/* #undef NO_WEAK_PTHREADS */ + +/* Define if lex produes code with yylineno */ +/* #undef NO_YYLINENO */ + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "krb5-bugs@mit.edu" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "Kerberos 5" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "Kerberos 5 1.17.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "krb5" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.17.1" + +/* Define if setjmp indicates POSIX interface */ +/* #undef POSIX_SETJMP */ + +/* Define if POSIX signal handling is used */ +#define POSIX_SIGNALS 1 + +/* Define if POSIX signal handlers are used */ +#define POSIX_SIGTYPE 1 + +/* Define if termios.h exists and tcsetattr exists */ +#define POSIX_TERMIOS 1 + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define as return type of setrpcent */ +#define SETRPCENT_TYPE void + +/* The size of `size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* The size of `time_t', as computed by sizeof. */ +#define SIZEOF_TIME_T 8 + +/* Define to use OpenSSL for SPAKE preauth */ +#define SPAKE_OPENSSL 1 + +/* Define for static plugin linkage */ +/* #undef STATIC_PLUGINS */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if strerror_r returns char *. */ +#define STRERROR_R_CHAR_P 1 + +/* Define if sys_errlist is defined in errno.h */ +#define SYS_ERRLIST_DECLARED 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if no TLS implementation is selected */ +/* #undef TLS_IMPL_NONE */ + +/* Define if TLS implementation is OpenSSL */ +#define TLS_IMPL_OPENSSL 1 + +/* Define if you have dirent.h functionality */ +#define USE_DIRENT_H 1 + +/* Define if dlopen should be used */ +#define USE_DLOPEN 1 + +/* Define if the keyring ccache should be enabled */ +/* #undef USE_KEYRING_CCACHE */ + +/* Define if link-time options for library finalization will be used */ +/* #undef USE_LINKER_FINI_OPTION */ + +/* Define if link-time options for library initialization will be used */ +/* #undef USE_LINKER_INIT_OPTION */ + +/* Define if sigprocmask should be used */ +#define USE_SIGPROCMASK 1 + +/* Define if wait takes int as a argument */ +#define WAIT_USES_INT 1 + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#define YYTEXT_POINTER 1 + +/* Define to enable extensions in glibc */ +#define _GNU_SOURCE 1 + +/* Define to enable C11 extensions */ +#define __STDC_WANT_LIB_EXT1__ 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define krb5_sigtype to type of signal handler */ +#define krb5_sigtype void + +/* Define to `int' if does not define. */ +/* #undef mode_t */ + +/* Define to `long int' if does not define. */ +/* #undef off_t */ + +/* Define to `long' if does not define. */ +/* #undef time_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + + +#if defined(__GNUC__) && !defined(inline) +/* Silence gcc pedantic warnings about ANSI C. */ +# define inline __inline__ +#endif +#endif /* KRB5_AUTOCONF_H */ diff --git a/contrib/krb5-cmake/osconf.h b/contrib/krb5-cmake/osconf.h new file mode 100644 index 00000000000..f534b4bb9c1 --- /dev/null +++ b/contrib/krb5-cmake/osconf.h @@ -0,0 +1,141 @@ +/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + * Copyright 1990,1991,2008 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + */ + +/* Site- and OS- dependent configuration */ + +#ifndef KRB5_OSCONF__ +#define KRB5_OSCONF__ + +#if !defined(_WIN32) +/* Don't try to pull in autoconf.h for Windows, since it's not used */ +#ifndef KRB5_AUTOCONF__ +#define KRB5_AUTOCONF__ +#include "autoconf.h" +#endif +#endif + +#if defined(__MACH__) && defined(__APPLE__) +# include +#endif + +#if defined(_WIN32) +#define DEFAULT_PROFILE_FILENAME "krb5.ini" +#else /* !_WINDOWS */ +#if TARGET_OS_MAC +#define DEFAULT_SECURE_PROFILE_PATH "/Library/Preferences/edu.mit.Kerberos:/etc/krb5.conf:/usr/local/etc/krb5.conf" +#define DEFAULT_PROFILE_PATH ("~/Library/Preferences/edu.mit.Kerberos" ":" DEFAULT_SECURE_PROFILE_PATH) +#define KRB5_PLUGIN_BUNDLE_DIR "/System/Library/KerberosPlugins/KerberosFrameworkPlugins" +#define KDB5_PLUGIN_BUNDLE_DIR "/System/Library/KerberosPlugins/KerberosDatabasePlugins" +#define KRB5_AUTHDATA_PLUGIN_BUNDLE_DIR "/System/Library/KerberosPlugins/KerberosAuthDataPlugins" +#else +#define DEFAULT_SECURE_PROFILE_PATH "/etc/krb5.conf:/usr/local/etc/krb5.conf" +#define DEFAULT_PROFILE_PATH DEFAULT_SECURE_PROFILE_PATH +#endif +#endif /* _WINDOWS */ + +#ifdef _WIN32 +#define DEFAULT_PLUGIN_BASE_DIR "%{LIBDIR}\\plugins" +#else +#define DEFAULT_PLUGIN_BASE_DIR "/usr/local/lib/krb5/plugins" +#endif + +#if defined(_WIN64) +#define PLUGIN_EXT "64.dll" +#elif defined(_WIN32) +#define PLUGIN_EXT "32.dll" +#else +#define PLUGIN_EXT ".so" +#endif + +#define KDC_DIR "/usr/local/var/krb5kdc" +#define KDC_RUN_DIR "/run/krb5kdc" +#define DEFAULT_KDB_FILE KDC_DIR "/principal" +#define DEFAULT_KEYFILE_STUB KDC_DIR "/.k5." +#define KRB5_DEFAULT_ADMIN_ACL KDC_DIR "/krb5_adm.acl" +/* Used by old admin server */ +#define DEFAULT_ADMIN_ACL KDC_DIR "/kadm_old.acl" + +/* Location of KDC profile */ +#define DEFAULT_KDC_PROFILE KDC_DIR "/kdc.conf" +#define KDC_PROFILE_ENV "KRB5_KDC_PROFILE" + +#if TARGET_OS_MAC +#define DEFAULT_KDB_LIB_PATH { KDB5_PLUGIN_BUNDLE_DIR, "/usr/local/lib/krb5/plugins/kdb", NULL } +#else +#define DEFAULT_KDB_LIB_PATH { "/usr/local/lib/krb5/plugins/kdb", NULL } +#endif + +#define DEFAULT_KDC_ENCTYPE ENCTYPE_AES256_CTS_HMAC_SHA1_96 +#define KDCRCACHE "dfl:krb5kdc_rcache" + +#define KDC_PORTNAME "kerberos" /* for /etc/services or equiv. */ + +#define KRB5_DEFAULT_PORT 88 + +#define DEFAULT_KPASSWD_PORT 464 + +#define DEFAULT_KDC_UDP_PORTLIST "88" +#define DEFAULT_KDC_TCP_PORTLIST "88" +#define DEFAULT_TCP_LISTEN_BACKLOG 5 + +/* + * Defaults for the KADM5 admin system. + */ +#define DEFAULT_KADM5_KEYTAB KDC_DIR "/kadm5.keytab" +#define DEFAULT_KADM5_ACL_FILE KDC_DIR "/kadm5.acl" +#define DEFAULT_KADM5_PORT 749 /* assigned by IANA */ + +#define KRB5_DEFAULT_SUPPORTED_ENCTYPES \ + "aes256-cts-hmac-sha1-96:normal " \ + "aes128-cts-hmac-sha1-96:normal" + +#define MAX_DGRAM_SIZE 65536 + +#define RCTMPDIR "/var/tmp" /* directory to store replay caches */ + +#define KRB5_PATH_TTY "/dev/tty" +#define KRB5_PATH_LOGIN "/usr/local/sbin/login.krb5" +#define KRB5_PATH_RLOGIN "/usr/local/bin/rlogin" + +#define KRB5_ENV_CCNAME "KRB5CCNAME" + +/* + * krb5 replica support follows + */ + +#define KPROP_DEFAULT_FILE KDC_DIR "/replica_datatrans" +#define KPROPD_DEFAULT_FILE KDC_DIR "/from_master" +#define KPROPD_DEFAULT_KDB5_UTIL "/usr/local/sbin/kdb5_util" +#define KPROPD_DEFAULT_KPROP "/usr/local/sbin/kprop" +#define KPROPD_DEFAULT_KRB_DB DEFAULT_KDB_FILE +#define KPROPD_ACL_FILE KDC_DIR "/kpropd.acl" + +/* + * GSS mechglue + */ +#define MECH_CONF "/usr/local/etc/gss/mech" +#define MECH_LIB_PREFIX "/usr/local/lib/gss/" + +#endif /* KRB5_OSCONF__ */ diff --git a/contrib/krb5-cmake/profile.h b/contrib/krb5-cmake/profile.h new file mode 100644 index 00000000000..1a303359565 --- /dev/null +++ b/contrib/krb5-cmake/profile.h @@ -0,0 +1,2 @@ +#include "util/profile/profile.hin" +#include "util/profile/prof_err.h" diff --git a/contrib/librdkafka-cmake/CMakeLists.txt b/contrib/librdkafka-cmake/CMakeLists.txt index b8dcb0a9340..4a67ebadba6 100644 --- a/contrib/librdkafka-cmake/CMakeLists.txt +++ b/contrib/librdkafka-cmake/CMakeLists.txt @@ -49,7 +49,6 @@ set(SRCS ${RDKAFKA_SOURCE_DIR}/rdkafka_request.c ${RDKAFKA_SOURCE_DIR}/rdkafka_roundrobin_assignor.c ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl.c -# ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_cyrus.c # needed to support Kerberos, requires cyrus-sasl ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_oauthbearer.c ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_plain.c ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_scram.c @@ -77,12 +76,34 @@ set(SRCS ${RDKAFKA_SOURCE_DIR}/rdgz.c ) +if(${ENABLE_CYRUS_SASL}) + message (STATUS "librdkafka with SASL support") + set(SRCS + ${SRCS} + ${RDKAFKA_SOURCE_DIR}/rdkafka_sasl_cyrus.c # needed to support Kerberos, requires cyrus-sasl + ) +endif() + add_library(rdkafka ${SRCS}) target_compile_options(rdkafka PRIVATE -fno-sanitize=undefined) -target_include_directories(rdkafka SYSTEM PUBLIC include) +# target_include_directories(rdkafka SYSTEM PUBLIC include) +target_include_directories(rdkafka SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) # for "librdkafka/rdkafka.h" target_include_directories(rdkafka SYSTEM PUBLIC ${RDKAFKA_SOURCE_DIR}) # Because weird logic with "include_next" is used. +target_include_directories(rdkafka SYSTEM PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/auxdir) # for "../config.h" target_include_directories(rdkafka SYSTEM PRIVATE ${ZSTD_INCLUDE_DIR}/common) # Because wrong path to "zstd_errors.h" is used. -target_link_libraries(rdkafka PRIVATE lz4 ${ZLIB_LIBRARIES} ${ZSTD_LIBRARY} ${LIBGSASL_LIBRARY}) +target_link_libraries(rdkafka PRIVATE lz4 ${ZLIB_LIBRARIES} ${ZSTD_LIBRARY}) if(OPENSSL_SSL_LIBRARY AND OPENSSL_CRYPTO_LIBRARY) target_link_libraries(rdkafka PRIVATE ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY}) endif() +if(${ENABLE_CYRUS_SASL}) + target_link_libraries(rdkafka PRIVATE ${CYRUS_SASL_LIBRARY}) + set(WITH_SASL_CYRUS 1) +endif() + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/auxdir) + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h" + IMMEDIATE @ONLY +) diff --git a/contrib/librdkafka-cmake/config.h b/contrib/librdkafka-cmake/config.h.in similarity index 96% rename from contrib/librdkafka-cmake/config.h rename to contrib/librdkafka-cmake/config.h.in index a4c69cd7578..c0f2e41fb9e 100644 --- a/contrib/librdkafka-cmake/config.h +++ b/contrib/librdkafka-cmake/config.h.in @@ -1,4 +1,4 @@ -// Automatically generated by ./configure +// Originally generated by ./configure #ifndef _CONFIG_H_ #define _CONFIG_H_ #define ARCH "x86_64" @@ -65,6 +65,7 @@ #define WITH_SASL_SCRAM 1 // WITH_SASL_OAUTHBEARER #define WITH_SASL_OAUTHBEARER 1 +#cmakedefine WITH_SASL_CYRUS 1 // crc32chw #if !defined(__PPC__) #define WITH_CRC32C_HW 1 diff --git a/debian/clickhouse-server.init b/debian/clickhouse-server.init index 3c5b6edc05d..b82c70bd6e0 100755 --- a/debian/clickhouse-server.init +++ b/debian/clickhouse-server.init @@ -76,7 +76,7 @@ is_supported_command() is_running() { - [ -r "$CLICKHOUSE_PIDFILE" ] && pgrep -s $(cat "$CLICKHOUSE_PIDFILE") 1> /dev/null 2> /dev/null + pgrep --pidfile "$CLICKHOUSE_PIDFILE" $(echo "${PROGRAM}" | cut -c1-15) 1> /dev/null 2> /dev/null } diff --git a/docker/images.json b/docker/images.json index 0ab1688efb0..723d5fc3e7d 100644 --- a/docker/images.json +++ b/docker/images.json @@ -127,5 +127,21 @@ "docker/test/integration/postgresql_java_client": { "name": "yandex/clickhouse-postgresql-java-client", "dependent": [] + }, + "docker/test/base": { + "name": "yandex/clickhouse-test-base", + "dependent": [ + ] + }, + "docker/packager/unbundled": { + "name": "yandex/clickhouse-unbundled-builder", + "dependent": [ + "docker/test/stateless_unbundled" + ] + }, + "docker/test/stateless_unbundled": { + "name": "yandex/clickhouse-stateless-unbundled-test", + "dependent": [ + ] } } diff --git a/docker/packager/binary/build.sh b/docker/packager/binary/build.sh index 07b67d0db9a..72adba5d762 100755 --- a/docker/packager/binary/build.sh +++ b/docker/packager/binary/build.sh @@ -2,9 +2,6 @@ set -x -e -# Update tzdata to the latest version. It is embedded into clickhouse binary. -sudo apt-get update && sudo apt-get install tzdata - mkdir -p build/cmake/toolchain/darwin-x86_64 tar xJf MacOSX10.14.sdk.tar.xz -C build/cmake/toolchain/darwin-x86_64 --strip-components=1 diff --git a/docker/packager/deb/build.sh b/docker/packager/deb/build.sh index 8b26bbb19cb..fbaa0151c6b 100755 --- a/docker/packager/deb/build.sh +++ b/docker/packager/deb/build.sh @@ -2,9 +2,6 @@ set -x -e -# Update tzdata to the latest version. It is embedded into clickhouse binary. -sudo apt-get update && sudo apt-get install tzdata - ccache --show-stats ||: ccache --zero-stats ||: build/release --no-pbuilder $ALIEN_PKGS | ts '%Y-%m-%d %H:%M:%S' diff --git a/docker/packager/unbundled/Dockerfile b/docker/packager/unbundled/Dockerfile new file mode 100644 index 00000000000..b52c1d47dd2 --- /dev/null +++ b/docker/packager/unbundled/Dockerfile @@ -0,0 +1,56 @@ +# docker build -t yandex/clickhouse-unbundled-builder . +FROM yandex/clickhouse-deb-builder + +# Libraries from OS are only needed to test the "unbundled" build (that is not used in production). +RUN apt-get --allow-unauthenticated update -y \ + && env DEBIAN_FRONTEND=noninteractive \ + apt-get --allow-unauthenticated install --yes --no-install-recommends \ + libicu-dev \ + libreadline-dev \ + gperf \ + perl \ + pkg-config \ + devscripts \ + libc++-dev \ + libc++abi-dev \ + libboost-program-options-dev \ + libboost-system-dev \ + libboost-filesystem-dev \ + libboost-thread-dev \ + libboost-iostreams-dev \ + libboost-regex-dev \ + zlib1g-dev \ + liblz4-dev \ + libdouble-conversion-dev \ + librdkafka-dev \ + libpoconetssl62 \ + libpoco-dev \ + libgoogle-perftools-dev \ + libzstd-dev \ + libltdl-dev \ + libre2-dev \ + libjemalloc-dev \ + libmsgpack-dev \ + libcurl4-openssl-dev \ + opencl-headers \ + ocl-icd-libopencl1 \ + intel-opencl-icd \ + unixodbc-dev \ + odbcinst \ + tzdata \ + gperf \ + alien \ + libcapnp-dev \ + cmake \ + gdb \ + pigz \ + moreutils \ + libcctz-dev \ + libldap2-dev \ + libsasl2-dev \ + heimdal-multidev \ + libhyperscan-dev + +COPY build.sh / + +CMD ["/bin/bash", "/build.sh"] \ No newline at end of file diff --git a/docker/packager/unbundled/build.sh b/docker/packager/unbundled/build.sh new file mode 100755 index 00000000000..8b26bbb19cb --- /dev/null +++ b/docker/packager/unbundled/build.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +set -x -e + +# Update tzdata to the latest version. It is embedded into clickhouse binary. +sudo apt-get update && sudo apt-get install tzdata + +ccache --show-stats ||: +ccache --zero-stats ||: +build/release --no-pbuilder $ALIEN_PKGS | ts '%Y-%m-%d %H:%M:%S' +mv /*.deb /output +mv *.changes /output +mv *.buildinfo /output +mv /*.rpm /output ||: # if exists +mv /*.tgz /output ||: # if exists + +if [ -n "$BINARY_OUTPUT" ] && { [ "$BINARY_OUTPUT" = "programs" ] || [ "$BINARY_OUTPUT" = "tests" ] ;} +then + echo Place $BINARY_OUTPUT to output + mkdir /output/binary ||: # if exists + mv /build/obj-*/programs/clickhouse* /output/binary + if [ "$BINARY_OUTPUT" = "tests" ] + then + mv /build/obj-*/src/unit_tests_dbms /output/binary + fi +fi +ccache --show-stats ||: +ln -s /usr/lib/x86_64-linux-gnu/libOpenCL.so.1.0.0 /usr/lib/libOpenCL.so ||: diff --git a/docker/test/base/Dockerfile b/docker/test/base/Dockerfile new file mode 100644 index 00000000000..851ec40a038 --- /dev/null +++ b/docker/test/base/Dockerfile @@ -0,0 +1,51 @@ +# docker build -t yandex/clickhouse-test-base . +FROM ubuntu:19.10 + +RUN apt-get --allow-unauthenticated update -y && apt-get install --yes wget gnupg +RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - +RUN echo "deb [trusted=yes] http://apt.llvm.org/eoan/ llvm-toolchain-eoan-10 main" >> /etc/apt/sources.list + +# initial packages +RUN apt-get --allow-unauthenticated update -y \ + && env DEBIAN_FRONTEND=noninteractive \ + apt-get --allow-unauthenticated install --yes --no-install-recommends \ + apt-transport-https \ + bash \ + ca-certificates \ + curl \ + fakeroot \ + gnupg \ + software-properties-common + +# Special dpkg-deb (https://github.com/ClickHouse-Extras/dpkg) version which is able +# to compress files using pigz (https://zlib.net/pigz/) instead of gzip. +# Significantly increase deb packaging speed and compatible with old systems +RUN curl -O https://clickhouse-builds.s3.yandex.net/utils/1/dpkg-deb +RUN chmod +x dpkg-deb +RUN cp dpkg-deb /usr/bin + +RUN apt-get --allow-unauthenticated update -y \ + && env DEBIAN_FRONTEND=noninteractive \ + apt-get --allow-unauthenticated install --yes --no-install-recommends \ + clang-10 \ + debhelper \ + devscripts \ + gdb \ + git \ + gperf \ + lcov \ + llvm-10 \ + moreutils \ + perl \ + perl \ + pigz \ + pkg-config \ + tzdata + +# Sanitizer options +RUN echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 history_size=7'" >> /etc/environment; \ + echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment; \ + echo "MSAN_OPTIONS='abort_on_error=1'" >> /etc/environment; \ + ln -s /usr/lib/llvm-10/bin/llvm-symbolizer /usr/bin/llvm-symbolizer; + +CMD sleep 1 \ No newline at end of file diff --git a/docker/test/fasttest/Dockerfile b/docker/test/fasttest/Dockerfile index faa7c875275..f8bb3683f60 100644 --- a/docker/test/fasttest/Dockerfile +++ b/docker/test/fasttest/Dockerfile @@ -11,41 +11,42 @@ RUN echo "deb [trusted=yes] http://apt.llvm.org/eoan/ llvm-toolchain-eoan-10 mai RUN apt-get --allow-unauthenticated update -y \ - && env DEBIAN_FRONTEND=noninteractive \ - apt-get --allow-unauthenticated install --yes --no-install-recommends \ - bash \ - fakeroot \ - ccache \ - software-properties-common \ - apt-transport-https \ - ca-certificates \ - wget \ - bash \ - fakeroot \ - cmake \ - ccache \ - llvm-10 \ - clang-10 \ - lld-10 \ - clang-tidy-10 \ - ninja-build \ - gperf \ - git \ - tzdata \ - gperf \ - rename \ - build-essential \ - expect \ - python \ - python-lxml \ - python-termcolor \ - python-requests \ - unixodbc \ - qemu-user-static \ - sudo \ - moreutils \ - curl \ - brotli + && env DEBIAN_FRONTEND=noninteractive \ + apt-get --allow-unauthenticated install --yes --no-install-recommends \ + apt-transport-https \ + bash \ + bash \ + brotli \ + build-essential \ + ca-certificates \ + ccache \ + ccache \ + clang-10 \ + clang-tidy-10 \ + cmake \ + curl \ + expect \ + fakeroot \ + fakeroot \ + git \ + gperf \ + gperf \ + lld-10 \ + llvm-10 \ + moreutils \ + ninja-build \ + psmisc \ + python \ + python-lxml \ + python-requests \ + python-termcolor \ + qemu-user-static \ + rename \ + software-properties-common \ + sudo \ + tzdata \ + unixodbc \ + wget RUN mkdir -p /tmp/clickhouse-odbc-tmp \ && wget --quiet -O - ${odbc_driver_url} | tar --strip-components=1 -xz -C /tmp/clickhouse-odbc-tmp \ diff --git a/docker/test/fasttest/run.sh b/docker/test/fasttest/run.sh index faadfca1210..0152f9c5cfd 100755 --- a/docker/test/fasttest/run.sh +++ b/docker/test/fasttest/run.sh @@ -1,12 +1,65 @@ #!/bin/bash +set -xeu +set -o pipefail +trap "exit" INT TERM +trap 'kill $(jobs -pr) ||:' EXIT -set -x -e +# This script is separated into two stages, cloning and everything else, so +# that we can run the "everything else" stage from the cloned source (we don't +# do this yet). +stage=${stage:-} + +# A variable to pass additional flags to CMake. +# Here we explicitly default it to nothing so that bash doesn't complain about +# it being undefined. Also read it as array so that we can pass an empty list +# of additional variable to cmake properly, and it doesn't generate an extra +# empty parameter. +read -ra FASTTEST_CMAKE_FLAGS <<< "${FASTTEST_CMAKE_FLAGS:-}" ls -la +function kill_clickhouse +{ + for _ in {1..60} + do + if ! pkill -f clickhouse-server ; then break ; fi + sleep 1 + done + + if pgrep -f clickhouse-server + then + pstree -apgT + jobs + echo "Failed to kill the ClickHouse server $(pgrep -f clickhouse-server)" + return 1 + fi +} + +function wait_for_server_start +{ + for _ in {1..60} + do + if clickhouse-client --query "select 1" || ! pgrep -f clickhouse-server + then + break + fi + sleep 1 + done + + if ! clickhouse-client --query "select 1" + then + echo "Failed to wait until ClickHouse server starts." + return 1 + fi + + echo "ClickHouse server pid '$(pgrep -f clickhouse-server)' started and responded" +} + +function clone_root +{ git clone https://github.com/ClickHouse/ClickHouse.git | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/clone_log.txt cd ClickHouse -CLICKHOUSE_DIR=`pwd` +CLICKHOUSE_DIR=$(pwd) if [ "$PULL_REQUEST_NUMBER" != "0" ]; then @@ -15,18 +68,21 @@ if [ "$PULL_REQUEST_NUMBER" != "0" ]; then echo 'Clonned merge head' else git fetch - git checkout $COMMIT_SHA + git checkout "$COMMIT_SHA" echo 'Checked out to commit' fi else if [ "$COMMIT_SHA" != "" ]; then - git checkout $COMMIT_SHA + git checkout "$COMMIT_SHA" fi fi +} -SUBMODULES_TO_UPDATE="contrib/boost contrib/zlib-ng contrib/libxml2 contrib/poco contrib/libunwind contrib/ryu contrib/fmtlib contrib/base64 contrib/cctz contrib/libcpuid contrib/double-conversion contrib/libcxx contrib/libcxxabi contrib/libc-headers contrib/lz4 contrib/zstd contrib/fastops contrib/rapidjson contrib/re2 contrib/sparsehash-c11" +function run +{ +SUBMODULES_TO_UPDATE=(contrib/boost contrib/zlib-ng contrib/libxml2 contrib/poco contrib/libunwind contrib/ryu contrib/fmtlib contrib/base64 contrib/cctz contrib/libcpuid contrib/double-conversion contrib/libcxx contrib/libcxxabi contrib/libc-headers contrib/lz4 contrib/zstd contrib/fastops contrib/rapidjson contrib/re2 contrib/sparsehash-c11) -git submodule update --init --recursive $SUBMODULES_TO_UPDATE | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/submodule_log.txt +git submodule update --init --recursive "${SUBMODULES_TO_UPDATE[@]}" | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/submodule_log.txt export CMAKE_LIBS_CONFIG="-DENABLE_LIBRARIES=0 -DENABLE_TESTS=0 -DENABLE_UTILS=0 -DENABLE_EMBEDDED_COMPILER=0 -DENABLE_THINLTO=0 -DUSE_UNWIND=1" @@ -41,8 +97,7 @@ ccache --zero-stats ||: mkdir build cd build -CLICKHOUSE_BUILD_DIR=`pwd` -cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_C_COMPILER=clang-10 $CMAKE_LIBS_CONFIG | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/cmake_log.txt +cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_CXX_COMPILER=clang++-10 -DCMAKE_C_COMPILER=clang-10 "$CMAKE_LIBS_CONFIG" "${FASTTEST_CMAKE_FLAGS[@]}" | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/cmake_log.txt ninja clickhouse-bundle | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/build_log.txt ninja install | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/install_log.txt @@ -54,8 +109,8 @@ mkdir -p /etc/clickhouse-client mkdir -p /etc/clickhouse-server/config.d mkdir -p /etc/clickhouse-server/users.d ln -s /test_output /var/log/clickhouse-server -cp $CLICKHOUSE_DIR/programs/server/config.xml /etc/clickhouse-server/ -cp $CLICKHOUSE_DIR/programs/server/users.xml /etc/clickhouse-server/ +cp "$CLICKHOUSE_DIR/programs/server/config.xml" /etc/clickhouse-server/ +cp "$CLICKHOUSE_DIR/programs/server/users.xml" /etc/clickhouse-server/ mkdir -p /etc/clickhouse-server/dict_examples ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/dict_examples/ @@ -86,21 +141,12 @@ ln -sf /usr/share/clickhouse-test/config/client_config.xml /etc/clickhouse-clien # Keep original query_masking_rules.xml ln -s --backup=simple --suffix=_original.xml /usr/share/clickhouse-test/config/query_masking_rules.xml /etc/clickhouse-server/config.d/ +# Kill the server in case we are running locally and not in docker +kill_clickhouse clickhouse-server --config /etc/clickhouse-server/config.xml --daemon -counter=0 - -until clickhouse-client --query "SELECT 1" -do - sleep 0.1 - if [ "$counter" -gt 1200 ] - then - break - fi - - counter=$(($counter + 1)) -done +wait_for_server_start TESTS_TO_SKIP=( parquet @@ -160,50 +206,58 @@ TESTS_TO_SKIP=( 01411_bayesian_ab_testing 01238_http_memory_tracking # max_memory_usage_for_user can interfere another queries running concurrently 01281_group_by_limit_memory_tracking # max_memory_usage_for_user can interfere another queries running concurrently + + # Not sure why these two fail even in sequential mode. Disabled for now + # to make some progress. + 00646_url_engine + 00974_query_profiler ) -clickhouse-test -j 4 --no-long --testname --shard --zookeeper --skip ${TESTS_TO_SKIP[*]} 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/test_log.txt +clickhouse-test -j 4 --no-long --testname --shard --zookeeper --skip "${TESTS_TO_SKIP[@]}" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee /test_output/test_log.txt -kill_clickhouse () { - killall clickhouse-server ||: +# substr is to remove semicolon after test name +readarray -t FAILED_TESTS < <(awk '/FAIL|TIMEOUT|ERROR/ { print substr($3, 1, length($3)-1) }' /test_output/test_log.txt | tee /test_output/failed-parallel-tests.txt) - for i in {1..10} - do - if ! killall -0 clickhouse-server; then - echo "No clickhouse process" - break - else - echo "Clickhouse server process" $(pgrep -f clickhouse-server) "still alive" - sleep 10 - fi - done -} - - -FAILED_TESTS=`grep 'FAIL\|TIMEOUT\|ERROR' /test_output/test_log.txt | awk 'BEGIN { ORS=" " }; { print substr($3, 1, length($3)-1) }'` - - -if [[ ! -z "$FAILED_TESTS" ]]; then +# We will rerun sequentially any tests that have failed during parallel run. +# They might have failed because there was some interference from other tests +# running concurrently. If they fail even in seqential mode, we will report them. +# FIXME All tests that require exclusive access to the server must be +# explicitly marked as `sequential`, and `clickhouse-test` must detect them and +# run them in a separate group after all other tests. This is faster and also +# explicit instead of guessing. +if [[ -n "${FAILED_TESTS[*]}" ]] +then kill_clickhouse + # Clean the data so that there is no interference from the previous test run. + rm -rvf /var/lib/clickhouse ||: + mkdir /var/lib/clickhouse + clickhouse-server --config /etc/clickhouse-server/config.xml --daemon - counter=0 - until clickhouse-client --query "SELECT 1" - do - sleep 0.1 - if [ "$counter" -gt 1200 ] - then - break - fi + wait_for_server_start - counter=$(($counter + 1)) - done + echo "Going to run again: ${FAILED_TESTS[*]}" - echo "Going to run again: $FAILED_TESTS" - - clickhouse-test --no-long --testname --shard --zookeeper $FAILED_TESTS 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee -a /test_output/test_log.txt + clickhouse-test --no-long --testname --shard --zookeeper "${FAILED_TESTS[@]}" 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee -a /test_output/test_log.txt else echo "No failed tests" fi +} + +case "$stage" in +"") + ;& +"clone_root") + clone_root + # TODO bootstrap into the cloned script here. Add this on Sep 1 2020 or + # later, so that most of the old branches are updated with this code. + ;& +"run") + run + ;& +esac + +pstree -apgT +jobs diff --git a/docker/test/performance-comparison/compare.sh b/docker/test/performance-comparison/compare.sh index f80fef45a64..d3b9fc2214e 100755 --- a/docker/test/performance-comparison/compare.sh +++ b/docker/test/performance-comparison/compare.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -ex +set -exu set -o pipefail trap "exit" INT TERM trap 'kill $(jobs -pr) ||:' EXIT @@ -7,6 +7,29 @@ trap 'kill $(jobs -pr) ||:' EXIT stage=${stage:-} script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +function wait_for_server # port, pid +{ + for _ in {1..60} + do + if clickhouse-client --port "$1" --query "select 1" || ! kill -0 "$2" + then + break + fi + sleep 1 + done + + if ! clickhouse-client --port "$1" --query "select 1" + then + echo "Cannot connect to ClickHouse server at $1" + return 1 + fi + + if ! kill -0 "$2" + then + echo "Server pid '$2' is not running" + return 1 + fi +} function configure { @@ -27,8 +50,9 @@ function configure kill -0 $left_pid disown $left_pid set +m - while ! clickhouse-client --port 9001 --query "select 1" && kill -0 $left_pid ; do echo . ; sleep 1 ; done - echo server for setup started + + wait_for_server 9001 $left_pid + echo Server for setup started clickhouse-client --port 9001 --query "create database test" ||: clickhouse-client --port 9001 --query "rename table datasets.hits_v1 to test.hits" ||: @@ -67,9 +91,10 @@ function restart set +m - while ! clickhouse-client --port 9001 --query "select 1" && kill -0 $left_pid ; do echo . ; sleep 1 ; done + wait_for_server 9001 $left_pid echo left ok - while ! clickhouse-client --port 9002 --query "select 1" && kill -0 $right_pid ; do echo . ; sleep 1 ; done + + wait_for_server 9002 $right_pid echo right ok clickhouse-client --port 9001 --query "select * from system.tables where database != 'system'" @@ -89,6 +114,8 @@ function run_tests # Just check that the script runs at all "$script_dir/perf.py" --help > /dev/null + changed_test_files="" + # Find the directory with test files. if [ -v CHPC_TEST_PATH ] then @@ -117,6 +144,7 @@ function run_tests if [ -v CHPC_TEST_GREP ] then # Run only explicitly specified tests, if any. + # shellcheck disable=SC2010 test_files=$(ls "$test_prefix" | grep "$CHPC_TEST_GREP" | xargs -I{} -n1 readlink -f "$test_prefix/{}") elif [ "$changed_test_files" != "" ] then @@ -130,7 +158,7 @@ function run_tests # Determine which concurrent benchmarks to run. For now, the only test # we run as a concurrent benchmark is 'website'. Run it as benchmark if we # are also going to run it as a normal test. - for test in $test_files; do echo $test; done | sed -n '/website/p' > benchmarks-to-run.txt + for test in $test_files; do echo "$test"; done | sed -n '/website/p' > benchmarks-to-run.txt # Delete old report files. for x in {test-times,wall-clock-times}.tsv @@ -178,7 +206,7 @@ function run_benchmark mkdir benchmark ||: # The list is built by run_tests. - for file in $(cat benchmarks-to-run.txt) + while IFS= read -r file do name=$(basename "$file" ".xml") @@ -190,7 +218,7 @@ function run_benchmark "${command[@]}" --port 9001 --json "benchmark/$name-left.json" < "benchmark/$name-queries.txt" "${command[@]}" --port 9002 --json "benchmark/$name-right.json" < "benchmark/$name-queries.txt" - done + done < benchmarks-to-run.txt } function get_profiles_watchdog @@ -273,8 +301,7 @@ mkdir analyze analyze/tmp ||: build_log_column_definitions # Split the raw test output into files suitable for analysis. -IFS=$'\n' -for test_file in $(find . -maxdepth 1 -name "*-raw.tsv" -print) +for test_file in *-raw.tsv do test_name=$(basename "$test_file" "-raw.tsv") sed -n "s/^query\t/$test_name\t/p" < "$test_file" >> "analyze/query-runs.tsv" @@ -285,7 +312,6 @@ do sed -n "s/^short\t/$test_name\t/p" < "$test_file" >> "analyze/marked-short-queries.tsv" sed -n "s/^partial\t/$test_name\t/p" < "$test_file" >> "analyze/partial-queries.tsv" done -unset IFS # for each query run, prepare array of metrics from query log clickhouse-local --query " @@ -394,7 +420,7 @@ create table query_run_metric_names engine File(TSV, 'analyze/query-run-metric-n IFS=$'\n' for prefix in $(cut -f1,2 "analyze/query-run-metrics-for-stats.tsv" | sort | uniq) do - file="analyze/tmp/$(echo "$prefix" | sed 's/\t/_/g').tsv" + file="analyze/tmp/${prefix// /_}.tsv" grep "^$prefix " "analyze/query-run-metrics-for-stats.tsv" > "$file" & printf "%s\0\n" \ "clickhouse-local \ @@ -831,15 +857,13 @@ wait unset IFS # Create differential flamegraphs. -IFS=$'\n' -for query_file in $(cat report/query-files.txt) +while IFS= read -r query_file do ~/fg/difffolded.pl "report/tmp/$query_file.stacks.left.tsv" \ "report/tmp/$query_file.stacks.right.tsv" \ | tee "report/tmp/$query_file.stacks.diff.tsv" \ | ~/fg/flamegraph.pl > "$query_file.diff.svg" & -done -unset IFS +done < report/query-files.txt wait # Create per-query files with metrics. Note that the key is different from flamegraphs. @@ -906,8 +930,7 @@ create table changes engine File(TSV, 'metrics/changes.tsv') as ) order by diff desc ; -" -2> >(tee -a metrics/errors.log 1>&2) +" 2> >(tee -a metrics/errors.log 1>&2) IFS=$'\n' for prefix in $(cut -f1 "metrics/metrics.tsv" | sort | uniq) @@ -981,7 +1004,7 @@ case "$stage" in # to collect the logs. Prefer not to restart, because addresses might change # and we won't be able to process trace_log data. Start in a subshell, so that # it doesn't interfere with the watchdog through `wait`. - ( get_profiles || restart && get_profiles ||: ) + ( get_profiles || restart && get_profiles ) ||: # Kill the whole process group, because somehow when the subshell is killed, # the sleep inside remains alive and orphaned. diff --git a/docker/test/performance-comparison/config/users.d/perf-comparison-tweaks-users.xml b/docker/test/performance-comparison/config/users.d/perf-comparison-tweaks-users.xml index 6e3e3df5d39..c6d9f7ea582 100644 --- a/docker/test/performance-comparison/config/users.d/perf-comparison-tweaks-users.xml +++ b/docker/test/performance-comparison/config/users.d/perf-comparison-tweaks-users.xml @@ -6,6 +6,16 @@ 1 1 1 + + 300 diff --git a/docker/test/stateless_unbundled/Dockerfile b/docker/test/stateless_unbundled/Dockerfile new file mode 100644 index 00000000000..7de29fede72 --- /dev/null +++ b/docker/test/stateless_unbundled/Dockerfile @@ -0,0 +1,84 @@ +# docker build -t yandex/clickhouse-stateless-unbundled-test . +FROM yandex/clickhouse-test-base + +ARG odbc_driver_url="https://github.com/ClickHouse/clickhouse-odbc/releases/download/v1.1.4.20200302/clickhouse-odbc-1.1.4-Linux.tar.gz" + +RUN apt-get --allow-unauthenticated update -y \ + && env DEBIAN_FRONTEND=noninteractive \ + apt-get --allow-unauthenticated install --yes --no-install-recommends \ + alien \ + brotli \ + cmake \ + devscripts \ + expect \ + gdb \ + gperf \ + gperf \ + heimdal-multidev \ + intel-opencl-icd \ + libboost-filesystem-dev \ + libboost-iostreams-dev \ + libboost-program-options-dev \ + libboost-regex-dev \ + libboost-system-dev \ + libboost-thread-dev \ + libc++-dev \ + libc++abi-dev \ + libcapnp-dev \ + libcctz-dev \ + libcurl4-openssl-dev \ + libdouble-conversion-dev \ + libgoogle-perftools-dev \ + libhyperscan-dev \ + libicu-dev \ + libjemalloc-dev \ + libldap2-dev \ + libltdl-dev \ + liblz4-dev \ + libmsgpack-dev \ + libpoco-dev \ + libpoconetssl62 \ + librdkafka-dev \ + libre2-dev \ + libreadline-dev \ + libsasl2-dev \ + libzstd-dev \ + lsof \ + moreutils \ + ncdu \ + netcat-openbsd \ + ocl-icd-libopencl1 \ + odbcinst \ + opencl-headers \ + openssl \ + perl \ + pigz \ + pkg-config \ + python \ + python-lxml \ + python-requests \ + python-termcolor \ + qemu-user-static \ + sudo \ + telnet \ + tree \ + tzdata \ + unixodbc \ + unixodbc-dev \ + wget \ + zlib1g-dev \ + zookeeper \ + zookeeperd + +RUN mkdir -p /tmp/clickhouse-odbc-tmp \ + && wget --quiet -O - ${odbc_driver_url} | tar --strip-components=1 -xz -C /tmp/clickhouse-odbc-tmp \ + && cp /tmp/clickhouse-odbc-tmp/lib64/*.so /usr/local/lib/ \ + && odbcinst -i -d -f /tmp/clickhouse-odbc-tmp/share/doc/clickhouse-odbc/config/odbcinst.ini.sample \ + && odbcinst -i -s -l -f /tmp/clickhouse-odbc-tmp/share/doc/clickhouse-odbc/config/odbc.ini.sample \ + && rm -rf /tmp/clickhouse-odbc-tmp + +ENV TZ=Europe/Moscow +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +COPY run.sh / +CMD ["/bin/bash", "/run.sh"] diff --git a/docker/test/stateless_unbundled/clickhouse-statelest-test-runner.Dockerfile b/docker/test/stateless_unbundled/clickhouse-statelest-test-runner.Dockerfile new file mode 100644 index 00000000000..562141ba147 --- /dev/null +++ b/docker/test/stateless_unbundled/clickhouse-statelest-test-runner.Dockerfile @@ -0,0 +1,15 @@ +# Since right now we can't set volumes to the docker during build, we split building container in stages: +# 1. build base container +# 2. run base conatiner with mounted volumes +# 3. commit container as image +FROM ubuntu:18.10 as clickhouse-test-runner-base + +# A volume where directory with clickhouse packages to be mounted, +# for later installing. +VOLUME /packages + +CMD apt-get update ;\ + DEBIAN_FRONTEND=noninteractive \ + apt install -y /packages/clickhouse-common-static_*.deb \ + /packages/clickhouse-client_*.deb \ + /packages/clickhouse-test_*.deb diff --git a/docker/test/stateless_unbundled/run.sh b/docker/test/stateless_unbundled/run.sh new file mode 100755 index 00000000000..2ff15ca9c6a --- /dev/null +++ b/docker/test/stateless_unbundled/run.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -e -x + +dpkg -i package_folder/clickhouse-common-static_*.deb +dpkg -i package_folder/clickhouse-common-static-dbg_*.deb +dpkg -i package_folder/clickhouse-server_*.deb +dpkg -i package_folder/clickhouse-client_*.deb +dpkg -i package_folder/clickhouse-test_*.deb + +mkdir -p /etc/clickhouse-server/dict_examples +ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/dict_examples/ +ln -s /usr/share/clickhouse-test/config/strings_dictionary.xml /etc/clickhouse-server/dict_examples/ +ln -s /usr/share/clickhouse-test/config/decimals_dictionary.xml /etc/clickhouse-server/dict_examples/ +ln -s /usr/share/clickhouse-test/config/zookeeper.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/listen.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/metric_log.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/custom_settings_prefixes.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/ +ln -s /usr/share/clickhouse-test/config/readonly.xml /etc/clickhouse-server/users.d/ +ln -s /usr/share/clickhouse-test/config/access_management.xml /etc/clickhouse-server/users.d/ +ln -s /usr/share/clickhouse-test/config/ints_dictionary.xml /etc/clickhouse-server/ +ln -s /usr/share/clickhouse-test/config/strings_dictionary.xml /etc/clickhouse-server/ +ln -s /usr/share/clickhouse-test/config/decimals_dictionary.xml /etc/clickhouse-server/ +ln -s /usr/share/clickhouse-test/config/macros.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/disks.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/secure_ports.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/clusters.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/graphite.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/server.key /etc/clickhouse-server/ +ln -s /usr/share/clickhouse-test/config/server.crt /etc/clickhouse-server/ +ln -s /usr/share/clickhouse-test/config/dhparam.pem /etc/clickhouse-server/ + +# Retain any pre-existing config and allow ClickHouse to load it if required +ln -s --backup=simple --suffix=_original.xml \ + /usr/share/clickhouse-test/config/query_masking_rules.xml /etc/clickhouse-server/config.d/ + +if [[ -n "$USE_POLYMORPHIC_PARTS" ]] && [[ "$USE_POLYMORPHIC_PARTS" -eq 1 ]]; then + ln -s /usr/share/clickhouse-test/config/polymorphic_parts.xml /etc/clickhouse-server/config.d/ +fi +if [[ -n "$USE_DATABASE_ATOMIC" ]] && [[ "$USE_DATABASE_ATOMIC" -eq 1 ]]; then + ln -s /usr/share/clickhouse-test/config/database_atomic_configd.xml /etc/clickhouse-server/config.d/ + ln -s /usr/share/clickhouse-test/config/database_atomic_usersd.xml /etc/clickhouse-server/users.d/ +fi + +ln -sf /usr/share/clickhouse-test/config/client_config.xml /etc/clickhouse-client/config.xml + +echo "TSAN_OPTIONS='verbosity=1000 halt_on_error=1 history_size=7'" >> /etc/environment +echo "TSAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment +echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment +echo "ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment +echo "UBSAN_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment +echo "LLVM_SYMBOLIZER_PATH=/usr/lib/llvm-10/bin/llvm-symbolizer" >> /etc/environment + +service zookeeper start +sleep 5 +service clickhouse-server start && sleep 5 + +if cat /usr/bin/clickhouse-test | grep -q -- "--use-skip-list"; then + SKIP_LIST_OPT="--use-skip-list" +fi + +clickhouse-test --testname --shard --zookeeper "$SKIP_LIST_OPT" $ADDITIONAL_OPTIONS $SKIP_TESTS_OPTION 2>&1 | ts '%Y-%m-%d %H:%M:%S' | tee test_output/test_result.txt diff --git a/docker/test/stress/run.sh b/docker/test/stress/run.sh index 908bbd60c7a..47c8603babb 100755 --- a/docker/test/stress/run.sh +++ b/docker/test/stress/run.sh @@ -8,15 +8,32 @@ dpkg -i package_folder/clickhouse-server_*.deb dpkg -i package_folder/clickhouse-client_*.deb dpkg -i package_folder/clickhouse-test_*.deb -function wait_server() +function stop() +{ + timeout 120 service clickhouse-server stop + + # Wait for process to disappear from processlist and also try to kill zombies. + while kill -9 $(pidof clickhouse-server) + do + echo "Killed clickhouse-server" + sleep 0.5 + done +} + +function start() { counter=0 until clickhouse-client --query "SELECT 1" do if [ "$counter" -gt 120 ] then + echo "Cannot start clickhouse-server" + cat /var/log/clickhouse-server/stdout.log + tail -n1000 /var/log/clickhouse-server/stderr.log + tail -n1000 /var/log/clickhouse-server/clickhouse-server.log break fi + timeout 120 service clickhouse-server start sleep 0.5 counter=$(($counter + 1)) done @@ -24,24 +41,21 @@ function wait_server() ln -s /usr/share/clickhouse-test/config/log_queries.xml /etc/clickhouse-server/users.d/ ln -s /usr/share/clickhouse-test/config/part_log.xml /etc/clickhouse-server/config.d/ +ln -s /usr/share/clickhouse-test/config/text_log.xml /etc/clickhouse-server/config.d/ echo "TSAN_OPTIONS='halt_on_error=1 history_size=7 ignore_noninstrumented_modules=1 verbosity=1'" >> /etc/environment echo "UBSAN_OPTIONS='print_stacktrace=1'" >> /etc/environment echo "ASAN_OPTIONS='malloc_context_size=10 verbosity=1 allocator_release_to_os_interval_ms=10000'" >> /etc/environment -timeout 120 service clickhouse-server start - -wait_server +start /s3downloader --dataset-names $DATASETS chmod 777 -R /var/lib/clickhouse clickhouse-client --query "ATTACH DATABASE IF NOT EXISTS datasets ENGINE = Ordinary" clickhouse-client --query "CREATE DATABASE IF NOT EXISTS test" -timeout 120 service clickhouse-server stop -timeout 120 service clickhouse-server start - -wait_server +stop +start clickhouse-client --query "SHOW TABLES FROM datasets" clickhouse-client --query "SHOW TABLES FROM test" @@ -51,9 +65,7 @@ clickhouse-client --query "SHOW TABLES FROM test" ./stress --output-folder test_output --skip-func-tests "$SKIP_TESTS_OPTION" -timeout 120 service clickhouse-server stop -timeout 120 service clickhouse-server start - -wait_server +stop +start clickhouse-client --query "SELECT 'Server successfuly started'" > /test_output/alive_check.txt || echo 'Server failed to start' > /test_output/alive_check.txt diff --git a/docker/test/style/Dockerfile b/docker/test/style/Dockerfile index 0f5c8d35fa9..1a4356caced 100644 --- a/docker/test/style/Dockerfile +++ b/docker/test/style/Dockerfile @@ -1,7 +1,7 @@ -# docker build -t yandex/clickhouse-style-test . +# docker build -t yandex/clickhouse-style-test . FROM ubuntu:20.04 -RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install --yes shellcheck libxml2-utils git +RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install --yes shellcheck libxml2-utils git python3-pip && pip3 install codespell CMD cd /ClickHouse/utils/check-style && ./check-style -n | tee /test_output/style_output.txt && \ diff --git a/docs/en/development/build.md b/docs/en/development/build.md index 2e84bcfcc1b..1c84342baf9 100644 --- a/docs/en/development/build.md +++ b/docs/en/development/build.md @@ -146,6 +146,14 @@ $ cd ClickHouse $ ./release ``` +## Faster builds for development + +Normally all tools of the ClickHouse bundle, such as `clickhouse-server`, `clickhouse-client` etc., are linked into a single static executable, `clickhouse`. This executable must be re-linked on every change, which might be slow. Two common ways to improve linking time are to use `lld` linker, and use the 'split' build configuration, which builds a separate binary for every tool, and further splits the code into serveral shared libraries. To enable these tweaks, pass the following flags to `cmake`: + +``` +-DCMAKE_C_FLAGS="-fuse-ld=lld" -DCMAKE_CXX_FLAGS="-fuse-ld=lld" -DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 -DCLICKHOUSE_SPLIT_BINARY=1 +``` + ## You Don’t Have to Build ClickHouse {#you-dont-have-to-build-clickhouse} ClickHouse is available in pre-built binaries and packages. Binaries are portable and can be run on any Linux flavour. @@ -154,4 +162,13 @@ They are built for stable, prestable and testing releases as long as for every c To find the freshest build from `master`, go to [commits page](https://github.com/ClickHouse/ClickHouse/commits/master), click on the first green checkmark or red cross near commit, and click to the “Details” link right after “ClickHouse Build Check”. +## Split build configuration {#split-build} + +Normally ClickHouse is statically linked into a single static `clickhouse` binary with minimal dependencies. This is convenient for distribution, but it means that on every change the entire binary is linked again, which is slow and may be inconvenient for development. There is an alternative configuration which creates dynamically loaded shared libraries instead, allowing faster incremental builds. To use it, add the following flags to your `cmake` invocation: +``` +-DUSE_STATIC_LIBRARIES=0 -DSPLIT_SHARED_LIBRARIES=1 -DCLICKHOUSE_SPLIT_BINARY=1 +``` + +Note that in this configuration there is no single `clickhouse` binary, and you have to run `clickhouse-server`, `clickhouse-client` etc. + [Original article](https://clickhouse.tech/docs/en/development/build/) diff --git a/docs/en/development/continuous-integration.md b/docs/en/development/continuous-integration.md new file mode 100644 index 00000000000..d0109233022 --- /dev/null +++ b/docs/en/development/continuous-integration.md @@ -0,0 +1,215 @@ +--- +toc_priority: 62 +toc_title: Continuous Integration Checks +--- + +# Continuous Integration Checks + +When you submit a pull request, some automated checks are ran for your code by +the ClickHouse [continuous integration (CI) system](tests.md#test-automation). +This happens after a repository maintainer (someone from ClickHouse team) has +screened your code and added the `can be tested` label to your pull request. +The results of the checks are listed on the GitHub pull request page as +described in the [GitHub checks +documentation](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-status-checks). +If a check is failing, you might be required to fix it. This page gives an +overview of checks you may encounter, and what you can do to fix them. + +If it looks like the check failure is not related to your changes, it may be +some transient failure or an infrastructure problem. Push an empty commit to +the pull request to restart the CI checks: +``` +git reset +git commit --allow-empty +git push +``` + +If you are not sure what to do, ask a maintainer for help. + + +## Merge With Master + +Verifies that the PR can be merged to master. If not, it will fail with the +message 'Cannot fetch mergecommit'. To fix this check, resolve the conflict as +described in the [GitHub +documentation](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github), +or merge the `master` branch to your pull request branch using git. + + +## Docs check + +Tries to build the ClickHouse documentation website. It can fail if you changed +something in the documentation. Most probable reason is that some cross-link in +the documentation is wrong. Go to the check report and look for `ERROR` and `WARNING` messages. + +### Report Details + +- [Status page example](https://clickhouse-test-reports.s3.yandex.net/12550/eabcc293eb02214caa6826b7c15f101643f67a6b/docs_check.html) +- `docs_output.txt` contains the building log. [Successful result example](https://clickhouse-test-reports.s3.yandex.net/12550/eabcc293eb02214caa6826b7c15f101643f67a6b/docs_check/docs_output.txt) + + +## Description Check + +Check that the description of your pull request conforms to the template +[PULL_REQUEST_TEMPLATE.md](https://github.com/ClickHouse/ClickHouse/blob/master/.github/PULL_REQUEST_TEMPLATE.md). +You have to specify a changelog category for your change (e.g., Bug Fix), and +write a user-readable message describing the change for [CHANGELOG.md](../whats-new/changelog/index.md) + + +## Push To Dockerhub + +Builds docker images used for build and tests, then pushes them to DockerHub. + + +## Marker Check + +This check means that the CI system started to process the pull request. When it has 'pending' status, it means that not all checks have been started yet. After all checks have been started, it changes status to 'success'. + + +## Style Check + +Performs some simple regex-based checks of code style, using the [`utils/check-style/check-style`](https://github.com/ClickHouse/ClickHouse/blob/master/utils/check-style/check-style) binary (note that it can be run locally). +If it fails, fix the style errors following the [code style guide](style.md). + +### Report Details +- [Status page example](https://clickhouse-test-reports.s3.yandex.net/12550/659c78c7abb56141723af6a81bfae39335aa8cb2/style_check.html) +- `output.txt` contains the check resulting errors (invalid tabulation etc), blank page means no errors. [Successful result example](https://clickhouse-test-reports.s3.yandex.net/12550/659c78c7abb56141723af6a81bfae39335aa8cb2/style_check/output.txt). + + +## PVS Check +Check the code with [PVS-studio](https://www.viva64.com/en/pvs-studio/), a static analysis tool. Look at the report to see the exact errors. Fix them if you can, if not -- ask a ClickHouse maintainer for help. + +### Report Details +- [Status page example](https://clickhouse-test-reports.s3.yandex.net/12550/67d716b5cc3987801996c31a67b31bf141bc3486/pvs_check.html) +- `test_run.txt.out.log` contains the building and analyzing log file. It includes only parsing or not-found errors. +- `HTML report` contains the analysis results. For its description visit PVS's [official site](https://www.viva64.com/en/m/0036/#ID14E9A2B2CD). + + +## Fast Test +Normally this is the first check that is ran for a PR. It builds ClickHouse and +runs most of [stateless functional tests](tests.md#functional-tests), omitting +some. If it fails, further checks are not started until it is fixed. Look at +the report to see which tests fail, then reproduce the failure locally as +described [here](tests.md#functional-test-locally). + +### Report Details +[Status page example](https://clickhouse-test-reports.s3.yandex.net/12550/67d716b5cc3987801996c31a67b31bf141bc3486/fast_test.html) + +#### Status Page Files +- `runlog.out.log` is the general log that includes all other logs. +- `test_log.txt` +- `submodule_log.txt` contains the messages about cloning and checkouting needed submodules. +- `stderr.log` +- `stdout.log` +- `clickhouse-server.log` +- `clone_log.txt` +- `install_log.txt` +- `clickhouse-server.err.log` +- `build_log.txt` +- `cmake_log.txt` contains messages about the C/C++ and Linux flags check. + +#### Status Page Columns + +- *Test name* contains the name of the test (without the path e.g. all types of tests will be stripped to the name). +- *Test status* -- one of _Skipped_, _Success_, or _Fail_. +- *Test time, sec.* -- empty on this test. + + +## Build Check {#build-check} + +Builds ClickHouse in various configurations for use in further steps. You have to fix the builds that fail. Build logs often has enough information to fix the error, but you might have to reproduce the failure locally. The `cmake` options can be found in the build log, grepping for `cmake`. Use these options and follow the [general build process](build.md). + +### Report Details + +[Status page example](https://clickhouse-builds.s3.yandex.net/12550/67d716b5cc3987801996c31a67b31bf141bc3486/clickhouse_build_check/report.html). + +- **Compiler**: `gcc-9` or `clang-10` (or `clang-10-xx` for other architectures e.g. `clang-10-freebsd`). +- **Build type**: `Debug` or `RelWithDebInfo` (cmake). +- **Sanitizer**: `none` (without sanitizers), `address` (ASan), `memory` (MSan), `undefined` (UBSan), or `thread` (TSan). +- **Bundled**: `bundled` build uses system libraries, and `unbundled` build uses libraries from `contrib` folder. +- **Splitted** `splitted` is a [split build](build.md#split-build) +- **Status**: `success` or `fail` +- **Build log**: link to the building and files copying log, useful when build failed. +- **Build time**. +- **Artifacts**: build result files (with `XXX` being the server version e.g. `20.8.1.4344`). + - `clickhouse-client_XXX_all.deb` + - `clickhouse-common-static-dbg_XXX[+asan, +msan, +ubsan, +tsan]_amd64.deb` + - `clickhouse-common-staticXXX_amd64.deb` + - `clickhouse-server_XXX_all.deb` + - `clickhouse-test_XXX_all.deb` + - `clickhouse_XXX_amd64.buildinfo` + - `clickhouse_XXX_amd64.changes` + - `clickhouse`: Main built binary. + - `clickhouse-odbc-bridge` + - `unit_tests_dbms`: GoogleTest binary with ClickHouse unit tests. + - `shared_build.tgz`: build with shared libraries. + - `performance.tgz`: Special package for performance tests. + + +## Special Build Check +Performs static analysis and code style checks using `clang-tidy`. The report is similar to the [build check](#build-check). Fix the errors found in the build log. + + +## Functional Stateless Tests +Runs [stateless functional tests](tests.md#functional-tests) for ClickHouse +binaries built in various configurations -- release, debug, with sanitizers, +etc. Look at the report to see which tests fail, then reproduce the failure +locally as described [here](tests.md#functional-test-locally). Note that you +have to use the correct build configuration to reproduce -- a test might fail +under AddressSanitizer but pass in Debug. Download the binary from [CI build +checks page](build.md#you-dont-have-to-build-clickhouse), or build it locally. + + +## Functional Stateful Tests +Runs [stateful functional tests](tests.md#functional-tests). Treat them in the same way as the functional stateless tests. The difference is that they require `hits` and `visits` tables from the [Yandex.Metrica dataset](../getting-started/example-datasets/metrica.md) to run. + + +## Integration Tests +Runs [integration tests](tests.md#integration-tests). + + +## Testflows Check +Runs some tests using Testflows test system. See [here](https://github.com/ClickHouse/ClickHouse/tree/master/tests/testflows#running-tests-locally) how to run them locally. + + +## Stress Test +Runs stateless functional tests concurrently from several clients to detect +concurrency-related errors. If it fails: + + * Fix all other test failures first; + * Look at the report to find the server logs and check them for possible causes + of error. + + +## Split Build Smoke Test + +Checks that the server build in [split build](build.md#split-build) +configuration can start and run simple queries. If it fails: + + * Fix other test errors first; + * Build the server in [split build](build.md#split-build) configuration + locally and check whether it can start and run `select 1`. + + +## Compatibility Check +Checks that `clickhouse` binary runs on distributions with old libc versions. If it fails, ask a maintainer for help. + + +## AST Fuzzer +Runs randomly generated queries to catch program errors. If it fails, ask a maintainer for help. + + +## Performance Tests +Measure changes in query performance. This is the longest check that takes just below 6 hours to run. The performance test report is described in detail [here](https://github.com/ClickHouse/ClickHouse/tree/master/docker/test/performance-comparison#how-to-read-the-report). + + + +# QA + +> What is a `Task (private network)` item on status pages? + +It's a link to the Yandex's internal job system. Yandex employees can see the check's start time and its more verbose status. + +> Where the tests are run + +Somewhere on Yandex internal infrastructure. diff --git a/docs/en/development/style.md b/docs/en/development/style.md index d1a066343cf..b2007e8042c 100644 --- a/docs/en/development/style.md +++ b/docs/en/development/style.md @@ -703,7 +703,7 @@ But other things being equal, cross-platform or portable code is preferred. **3.** Compiler: `gcc`. At this time (August 2020), the code is compiled using version 9.3. (It can also be compiled using `clang 8`.) -The standard library is used (`libstdc++` or `libc++`). +The standard library is used (`libc++`). **4.**OS: Linux Ubuntu, not older than Precise. diff --git a/docs/en/development/tests.md b/docs/en/development/tests.md index 31e309130cb..e95a836cc8a 100644 --- a/docs/en/development/tests.md +++ b/docs/en/development/tests.md @@ -27,6 +27,18 @@ If you want to use distributed queries in functional tests, you can leverage `re Some tests are marked with `zookeeper`, `shard` or `long` in their names. `zookeeper` is for tests that are using ZooKeeper. `shard` is for tests that requires server to listen `127.0.0.*`; `distributed` or `global` have the same meaning. `long` is for tests that run slightly longer that one second. You can disable these groups of tests using `--no-zookeeper`, `--no-shard` and `--no-long` options, respectively. +### Running a particular test locally {#functional-test-locally} + +Start the ClickHouse server locally, listening on the default port (9000). To +run, for example, the test `01428_hash_set_nan_key`, change to the repository +folder and run the following command: + +``` +PATH=$PATH: tests/clickhouse-test 01428_hash_set_nan_key +``` + +For more options, see `tests/clickhouse-test --help`. + ## Known Bugs {#known-bugs} 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. @@ -168,7 +180,7 @@ Main ClickHouse code (that is located in `dbms` directory) is built with `-Wall Clang has even more useful warnings - you can look for them with `-Weverything` and pick something to default build. -For production builds, gcc is used (it still generates slightly more efficient code than clang). For development, clang is usually more convenient to use. You can build on your own machine with debug mode (to save battery of your laptop), but please note that compiler is able to generate more warnings with `-O3` due to better control flow and inter-procedure analysis. When building with clang, `libc++` is used instead of `libstdc++` and when building with debug mode, debug version of `libc++` is used that allows to catch more errors at runtime. +For production builds, gcc is used (it still generates slightly more efficient code than clang). For development, clang is usually more convenient to use. You can build on your own machine with debug mode (to save battery of your laptop), but please note that compiler is able to generate more warnings with `-O3` due to better control flow and inter-procedure analysis. When building with clang in debug mode, debug version of `libc++` is used that allows to catch more errors at runtime. ## Sanitizers {#sanitizers} diff --git a/docs/en/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/en/engines/table-engines/mergetree-family/replacingmergetree.md index 684e7e28112..109ae6c4601 100644 --- a/docs/en/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/en/engines/table-engines/mergetree-family/replacingmergetree.md @@ -31,7 +31,7 @@ For a description of request parameters, see [statement description](../../../sq **ReplacingMergeTree Parameters** -- `ver` — column with version. Type `UInt*`, `Date` or `DateTime`. Optional parameter. +- `ver` — column with version. Type `UInt*`, `Date`, `DateTime` or `DateTime64`. Optional parameter. When merging, `ReplacingMergeTree` from all the rows with the same sorting key leaves only one: diff --git a/docs/en/engines/table-engines/special/materializedview.md b/docs/en/engines/table-engines/special/materializedview.md index d450c8814a7..1d98eb2e3b7 100644 --- a/docs/en/engines/table-engines/special/materializedview.md +++ b/docs/en/engines/table-engines/special/materializedview.md @@ -5,6 +5,6 @@ toc_title: MaterializedView # MaterializedView Table Engine {#materializedview} -Used for implementing materialized views (for more information, see [CREATE TABLE](../../../sql-reference/statements/create/table.md)). For storing data, it uses a different engine that was specified when creating the view. When reading from a table, it just uses that engine. +Used for implementing materialized views (for more information, see [CREATE VIEW](../../../sql-reference/statements/create/view.md#materialized)). For storing data, it uses a different engine that was specified when creating the view. When reading from a table, it just uses that engine. [Original article](https://clickhouse.tech/docs/en/operations/table_engines/materializedview/) diff --git a/docs/en/faq/integration/json-import.md b/docs/en/faq/integration/json-import.md index ef939b2c0d6..067b407a079 100644 --- a/docs/en/faq/integration/json-import.md +++ b/docs/en/faq/integration/json-import.md @@ -19,7 +19,7 @@ $ echo '{"foo":"bar"}' | curl 'http://localhost:8123/?query=INSERT%20INTO%20test Using [CLI interface](../../interfaces/cli.md): ``` bash -$ echo '{"foo":"bar"}' | clickhouse-client ---query="INSERT INTO test FORMAT 20JSONEachRow" +$ echo '{"foo":"bar"}' | clickhouse-client ---query="INSERT INTO test FORMAT JSONEachRow" ``` Instead of inserting data manually, you might consider to use one of [client libraries](../../interfaces/index.md) instead. diff --git a/docs/en/interfaces/third-party/client-libraries.md b/docs/en/interfaces/third-party/client-libraries.md index 44186ec9135..9dbbe0a0022 100644 --- a/docs/en/interfaces/third-party/client-libraries.md +++ b/docs/en/interfaces/third-party/client-libraries.md @@ -46,6 +46,7 @@ toc_title: Client Libraries - Kotlin - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [ClickHouse.Ado](https://github.com/killwort/ClickHouse-Net) - [ClickHouse.Client](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/en/introduction/adopters.md b/docs/en/introduction/adopters.md index 308e29c52ec..ef95b4d4372 100644 --- a/docs/en/introduction/adopters.md +++ b/docs/en/introduction/adopters.md @@ -15,6 +15,7 @@ toc_title: Adopters | Amadeus | Travel | Analytics | — | — | [Press Release, April 2018](https://www.altinity.com/blog/2018/4/5/amadeus-technologies-launches-investment-and-insights-tool-based-on-machine-learning-and-strategy-algorithms) | | Appsflyer | Mobile analytics | Main product | — | — | [Talk in Russian, July 2019](https://www.youtube.com/watch?v=M3wbRlcpBbY) | | ArenaData | Data Platform | Main product | — | — | [Slides in Russian, December 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup38/indexes.pdf) | +| Avito | Classifieds | Monitoring | — | — | [Meetup, April 2020](https://www.youtube.com/watch?v=n1tm4j4W8ZQ) | | Badoo | Dating | Timeseries | — | — | [Slides in Russian, December 2019](https://presentations.clickhouse.tech/meetup38/forecast.pdf) | | Benocs | Network Telemetry and Analytics | Main Product | — | — | [Slides in English, October 2017](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup9/lpm.pdf) | | Bloomberg | Finance, Media | Monitoring | 102 servers | — | [Slides, May 2018](https://www.slideshare.net/Altinity/http-analytics-for-6m-requests-per-second-using-clickhouse-by-alexander-bocharov) | @@ -34,7 +35,9 @@ toc_title: Adopters | Dataliance for China Telecom | Telecom | Analytics | — | — | [Slides in Chinese, January 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup12/telecom.pdf) | | Deutsche Bank | Finance | BI Analytics | — | — | [Slides in English, October 2019](https://bigdatadays.ru/wp-content/uploads/2019/10/D2-H3-3_Yakunin-Goihburg.pdf) | | Diva-e | Digital consulting | Main Product | — | — | [Slides in English, September 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup29/ClickHouse-MeetUp-Unusual-Applications-sd-2019-09-17.pdf) | +| Ecwid | E-commerce SaaS | Metrics, Logging | — | — | [Slides in Russian, April 2019](https://nastachku.ru/var/files/1/presentation/backend/2_Backend_6.pdf) | | Exness | Trading | Metrics, Logging | — | — | [Talk in Russian, May 2019](https://youtu.be/_rpU-TvSfZ8?t=3215) | +| FastNetMon | DDoS Protection | Main Product | | — | [Official website](https://fastnetmon.com/docs-fnm-advanced/fastnetmon-advanced-traffic-persistency/) | | Flipkart | e-Commerce | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=239) | | FunCorp | Games | | — | — | [Article](https://www.altinity.com/blog/migrating-from-redshift-to-clickhouse) | | Geniee | Ad network | Main product | — | — | [Blog post in Japanese, July 2017](https://tech.geniee.co.jp/entry/2017/07/20/160100) | @@ -45,6 +48,7 @@ toc_title: Adopters | Instana | APM Platform | Main product | — | — | [Twitter post](https://twitter.com/mieldonkers/status/1248884119158882304) | | Integros | Platform for video services | Analytics | — | — | [Slides in Russian, May 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup22/strategies.pdf) | | Ippon Technologies | Technology Consulting | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=205) | +| Ivi | Online Cinema | Analytics, Monitoring | — | — | [Article in Russian, Jan 2018](https://habr.com/en/company/ivi/blog/347408/) | | Jinshuju 金数据 | BI Analytics | Main product | — | — | [Slides in Chinese, October 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup24/3.%20金数据数据架构调整方案Public.pdf) | | Kodiak Data | Clouds | Main product | — | — | [Slides in Engish, April 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup13/kodiak_data.pdf) | | Kontur | Software Development | Metrics | — | — | [Talk in Russian, November 2018](https://www.youtube.com/watch?v=U4u4Bd0FtrY) | @@ -53,7 +57,9 @@ toc_title: Adopters | Mail.ru Cloud Solutions | Cloud services | Main product | — | — | [Article in Russian](https://mcs.mail.ru/help/db-create/clickhouse#) | | Marilyn | Advertising | Statistics | — | — | [Talk in Russian, June 2017](https://www.youtube.com/watch?v=iXlIgx2khwc) | | MessageBird | Telecommunications | Statistics | — | — | [Slides in English, November 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup20/messagebird.pdf) | +| MindsDB | Machine Learning | Main Product | — | — | [Official Website](https://www.mindsdb.com/blog/machine-learning-models-as-tables-in-ch) | | MGID | Ad network | Web-analytics | — | — | [Blog post in Russian, April 2020](http://gs-studio.com/news-about-it/32777----clickhouse---c) | +| NOC Project | Network Monitoring | Analytics | Main Product | — | [Official Website](https://getnoc.com/features/big-data/) | | Nuna Inc. | Health Data Analytics | — | — | — | [Talk in English, July 2020](https://youtu.be/GMiXCMFDMow?t=170) | | OneAPM | Monitorings and Data Analysis | Main product | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/8.%20clickhouse在OneAPM的应用%20杜龙.pdf) | | Percent 百分点 | Analytics | Main Product | — | — | [Slides in Chinese, June 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup24/4.%20ClickHouse万亿数据双中心的设计与实践%20.pdf) | @@ -63,6 +69,7 @@ toc_title: Adopters | QINGCLOUD | Cloud services | Main product | — | — | [Slides in Chinese, October 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup19/4.%20Cloud%20%2B%20TSDB%20for%20ClickHouse%20张健%20QingCloud.pdf) | | Qrator | DDoS protection | Main product | — | — | [Blog Post, March 2019](https://blog.qrator.net/en/clickhouse-ddos-mitigation_37/) | | Rambler | Internet services | Analytics | — | — | [Talk in Russian, April 2018](https://medium.com/@ramblertop/разработка-api-clickhouse-для-рамблер-топ-100-f4c7e56f3141) | +| Rspamd | Antispam | Analytics | — | — | [Official Website](https://rspamd.com/doc/modules/clickhouse.html) | | S7 Airlines | Airlines | Metrics, Logging | — | — | [Talk in Russian, March 2019](https://www.youtube.com/watch?v=nwG68klRpPg&t=15s) | | scireum GmbH | e-Commerce | Main product | — | — | [Talk in German, February 2020](https://www.youtube.com/watch?v=7QWAn5RbyR4) | | Segment | Data processing | Main product | 9 * i3en.3xlarge nodes 7.5TB NVME SSDs, 96GB Memory, 12 vCPUs | — | [Slides, 2019](https://slides.com/abraithwaite/segment-clickhouse) | @@ -91,5 +98,6 @@ toc_title: Adopters | Yandex Metrica | Web analytics | Main product | 360 servers in one cluster, 1862 servers in one department | 66.41 PiB / 5.68 PiB | [Slides, February 2020](https://presentations.clickhouse.tech/meetup40/introduction/#13) | | ЦВТ | Software Development | Metrics, Logging | — | — | [Blog Post, March 2019, in Russian](https://vc.ru/dev/62715-kak-my-stroili-monitoring-na-prometheus-clickhouse-i-elk) | | МКБ | Bank | Web-system monitoring | — | — | [Slides in Russian, September 2019](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup28/mkb.pdf) | +| ЦФТ | Banking, Financial products, Payments | — | — | — | [Meetup in Russian, April 2020](https://team.cft.ru/events/162) | [Original article](https://clickhouse.tech/docs/en/introduction/adopters/) diff --git a/docs/en/operations/quotas.md b/docs/en/operations/quotas.md index deac786bc50..c637ef03f71 100644 --- a/docs/en/operations/quotas.md +++ b/docs/en/operations/quotas.md @@ -8,7 +8,7 @@ toc_title: Quotas Quotas allow you to limit resource usage over a period of time or track the use of resources. Quotas are set up in the user config, which is usually ‘users.xml’. -The system also has a feature for limiting the complexity of a single query. See the section “Restrictions on query complexity”). +The system also has a feature for limiting the complexity of a single query. See the section [Restrictions on query complexity](../operations/settings/query-complexity.md). In contrast to query complexity restrictions, quotas: diff --git a/docs/en/operations/server-configuration-parameters/settings.md b/docs/en/operations/server-configuration-parameters/settings.md index 80d4d659bd3..c1ac1d0d92d 100644 --- a/docs/en/operations/server-configuration-parameters/settings.md +++ b/docs/en/operations/server-configuration-parameters/settings.md @@ -339,13 +339,13 @@ Writing to the syslog is also supported. Config example: ``` -Keys: +Keys for syslog: - use\_syslog — Required setting if you want to write to the syslog. - address — The host\[:port\] of syslogd. If omitted, the local daemon is used. - hostname — Optional. The name of the host that logs are sent from. - facility — [The syslog facility keyword](https://en.wikipedia.org/wiki/Syslog#Facility) in uppercase letters with the “LOG\_” prefix: (`LOG_USER`, `LOG_DAEMON`, `LOG_LOCAL3`, and so on). - Default value: `LOG_USER` if `address` is specified, `LOG_DAEMON otherwise.` + Default value: `LOG_USER` if `address` is specified, `LOG_DAEMON` otherwise. - format – Message format. Possible values: `bsd` and `syslog.` ## send\_crash\_reports {#server_configuration_parameters-logger} @@ -357,8 +357,8 @@ The server will need an access to public Internet via IPv4 (at the time of writi Keys: -- `enabled` – Boolean flag to enable the feature. Set to `true` to allow sending crash reports. -- `endpoint` – Overrides the Sentry endpoint. +- `enabled` – Boolean flag to enable the feature, `false` by default. Set to `true` to allow sending crash reports. +- `endpoint` – You can override the Sentry endpoint URL for sending crash reports. It can be either separate Sentry account or your self-hosted Sentry instance. Use the [Sentry DSN](https://docs.sentry.io/error-reporting/quickstart/?platform=native#configure-the-sdk) syntax. - `anonymize` - Avoid attaching the server hostname to crash report. - `http_proxy` - Configure HTTP proxy for sending crash reports. - `debug` - Sets the Sentry client into debug mode. @@ -397,6 +397,7 @@ The cache is shared for the server and memory is allocated as needed. The cache ``` xml 5368709120 ``` + ## max\_server\_memory\_usage {#max_server_memory_usage} Limits total RAM usage by the ClickHouse server. @@ -589,7 +590,8 @@ Use the following parameters to configure logging: - `database` – Name of the database. - `table` – Name of the system table. -- `partition_by` – Sets a [custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md). +- `partition_by` — [Custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. Can't be used if `engine` defined. +- `engine` - [MergeTree Engine Definition](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) for a system table. Can't be used if `partition_by` defined. - `flush_interval_milliseconds` – Interval for flushing data from the buffer in memory to the table. **Example** @@ -650,7 +652,8 @@ Use the following parameters to configure logging: - `database` – Name of the database. - `table` – Name of the system table the queries will be logged in. -- `partition_by` – Sets a [custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a table. +- `partition_by` — [Custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. Can't be used if `engine` defined. +- `engine` - [MergeTree Engine Definition](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) for a system table. Can't be used if `partition_by` defined. - `flush_interval_milliseconds` – Interval for flushing data from the buffer in memory to the table. If the table doesn’t exist, ClickHouse will create it. If the structure of the query log changed when the ClickHouse server was updated, the table with the old structure is renamed, and a new table is created automatically. @@ -661,7 +664,7 @@ If the table doesn’t exist, ClickHouse will create it. If the structure of the system query_log
- toMonday(event_date) + Engine = MergeTree PARTITION BY event_date ORDER BY event_time TTL event_date + INTERVAL 30 day 7500
``` @@ -676,7 +679,8 @@ Use the following parameters to configure logging: - `database` – Name of the database. - `table` – Name of the system table the queries will be logged in. -- `partition_by` – Sets a [custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. +- `partition_by` — [Custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. Can't be used if `engine` defined. +- `engine` - [MergeTree Engine Definition](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) for a system table. Can't be used if `partition_by` defined. - `flush_interval_milliseconds` – Interval for flushing data from the buffer in memory to the table. If the table doesn’t exist, ClickHouse will create it. If the structure of the query thread log changed when the ClickHouse server was updated, the table with the old structure is renamed, and a new table is created automatically. @@ -692,6 +696,34 @@ If the table doesn’t exist, ClickHouse will create it. If the structure of the ``` +## text\_log {#server_configuration_parameters-text_log} + +Settings for the [text\_log](../../operations/system-tables/text_log.md#system_tables-text_log) system table for logging text messages. + +Parameters: + +- `level` — Maximum Message Level (by default `Trace`) which will be stored in a table. +- `database` — Database name. +- `table` — Table name. +- `partition_by` — [Custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. Can't be used if `engine` defined. +- `engine` - [MergeTree Engine Definition](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) for a system table. Can't be used if `partition_by` defined. +- `flush_interval_milliseconds` — Interval for flushing data from the buffer in memory to the table. + +**Example** +```xml + + + notice + system + text_log
+ 7500 + + Engine = MergeTree PARTITION BY event_date ORDER BY event_time TTL event_date + INTERVAL 30 day +
+
+``` + + ## trace\_log {#server_configuration_parameters-trace_log} Settings for the [trace\_log](../../operations/system-tables/trace_log.md#system_tables-trace_log) system table operation. @@ -700,7 +732,8 @@ Parameters: - `database` — Database for storing a table. - `table` — Table name. -- `partition_by` — [Custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. +- `partition_by` — [Custom partitioning key](../../engines/table-engines/mergetree-family/custom-partitioning-key.md) for a system table. Can't be used if `engine` defined. +- `engine` - [MergeTree Engine Definition](../../engines/table-engines/mergetree-family/index.md) for a system table. Can't be used if `partition_by` defined. - `flush_interval_milliseconds` — Interval for flushing data from the buffer in memory to the table. The default server configuration file `config.xml` contains the following settings section: @@ -717,7 +750,7 @@ The default server configuration file `config.xml` contains the following settin ## query\_masking\_rules {#query-masking-rules} Regexp-based rules, which will be applied to queries as well as all log messages before storing them in server logs, -`system.query_log`, `system.text_log`, `system.processes` table, and in logs sent to the client. That allows preventing +`system.query_log`, `system.text_log`, `system.processes` tables, and in logs sent to the client. That allows preventing sensitive data leakage from SQL queries (like names, emails, personal identifiers or credit card numbers) to logs. diff --git a/docs/en/operations/settings/settings.md b/docs/en/operations/settings/settings.md index cae6d9d789e..c844a88613d 100644 --- a/docs/en/operations/settings/settings.md +++ b/docs/en/operations/settings/settings.md @@ -1546,6 +1546,17 @@ Sets [Confluent Schema Registry](https://docs.confluent.io/current/schema-regist Default value: `Empty`. +## input_format_avro_allow_missing_fields {#input_format_avro_allow_missing_fields} + +Enables using fields that are not specified in [Avro](../../interfaces/formats.md#data-format-avro) or [AvroConfluent](../../interfaces/formats.md#data-format-avro-confluent) format schema. When a field is not found in the schema, ClickHouse uses the default value instead of throwing an exception. + +Possible values: + +- 0 — Disabled. +- 1 — Enabled. + +Default value: 0. + ## background\_pool\_size {#background_pool_size} Sets the number of threads performing background operations in table engines (for example, merges in [MergeTree engine](../../engines/table-engines/mergetree-family/index.md) tables). This setting is applied from `default` profile at ClickHouse server start and can’t be changed in a user session. By adjusting this setting, you manage CPU and disk load. Smaller pool size utilizes less CPU and disk resources, but background processes advance slower which might eventually impact query performance. diff --git a/docs/en/operations/system-tables/text_log.md b/docs/en/operations/system-tables/text_log.md index f4ba37e9568..bd92519b96b 100644 --- a/docs/en/operations/system-tables/text_log.md +++ b/docs/en/operations/system-tables/text_log.md @@ -1,4 +1,4 @@ -# system.text_log {#system-tables-text-log} +# system.text\_log {#system_tables-text_log} Contains logging entries. Logging level which goes to this table can be limited with `text_log.level` server setting. diff --git a/docs/en/sql-reference/aggregate-functions/reference/grouparraysample.md b/docs/en/sql-reference/aggregate-functions/reference/grouparraysample.md new file mode 100644 index 00000000000..36fa6a9d661 --- /dev/null +++ b/docs/en/sql-reference/aggregate-functions/reference/grouparraysample.md @@ -0,0 +1,81 @@ +--- +toc_priority: 114 +--- + +# groupArraySample {#grouparraysample} + +Creates an array of sample argument values. The size of the resulting array is limited to `max_size` elements. Argument values are selected and added to the array randomly. + +**Syntax** + +``` sql +groupArraySample(max_size[, seed])(x) +``` + +**Parameters** + +- `max_size` — Maximum size of the resulting array. [UInt64](../../data-types/int-uint.md). +- `seed` — Seed for the random number generator. Optional. [UInt64](../../data-types/int-uint.md). Default value: `123456`. +- `x` — Argument (column name or expression). + +**Returned values** + +- Array of randomly selected `x` arguments. + +Type: [Array](../../data-types/array.md). + +**Examples** + +Consider table `colors`: + +``` text +┌─id─┬─color──┐ +│ 1 │ red │ +│ 2 │ blue │ +│ 3 │ green │ +│ 4 │ white │ +│ 5 │ orange │ +└────┴────────┘ +``` + +Query with column name as argument: + +``` sql +SELECT groupArraySample(3)(color) as newcolors FROM colors; +``` + +Result: + +```text +┌─newcolors──────────────────┐ +│ ['white','blue','green'] │ +└────────────────────────────┘ +``` + +Query with column name and different seed: + +``` sql +SELECT groupArraySample(3, 987654321)(color) as newcolors FROM colors; +``` + +Result: + +```text +┌─newcolors──────────────────┐ +│ ['red','orange','green'] │ +└────────────────────────────┘ +``` + +Query with expression as argument: + +``` sql +SELECT groupArraySample(3)(concat('light-', color)) as newcolors FROM colors; +``` + +Result: + +```text +┌─newcolors───────────────────────────────────┐ +│ ['light-blue','light-orange','light-green'] │ +└─────────────────────────────────────────────┘ +``` diff --git a/docs/en/sql-reference/aggregate-functions/reference/index.md b/docs/en/sql-reference/aggregate-functions/reference/index.md index 675448a321b..6e00ad8d991 100644 --- a/docs/en/sql-reference/aggregate-functions/reference/index.md +++ b/docs/en/sql-reference/aggregate-functions/reference/index.md @@ -60,6 +60,8 @@ ClickHouse-specific aggregate functions: - [quantile](../../../sql-reference/aggregate-functions/reference/quantile.md) - [quantiles](../../../sql-reference/aggregate-functions/reference/quantiles.md) - [quantileExact](../../../sql-reference/aggregate-functions/reference/quantileexact.md) +- [quantileExactLow](../../../sql-reference/aggregate-functions/reference/quantileexact.md#quantileexactlow) +- [quantileExactHigh](../../../sql-reference/aggregate-functions/reference/quantileexact.md#quantileexacthigh) - [quantileExactWeighted](../../../sql-reference/aggregate-functions/reference/quantileexactweighted.md) - [quantileTiming](../../../sql-reference/aggregate-functions/reference/quantiletiming.md) - [quantileTimingWeighted](../../../sql-reference/aggregate-functions/reference/quantiletimingweighted.md) diff --git a/docs/en/sql-reference/aggregate-functions/reference/quantileexact.md b/docs/en/sql-reference/aggregate-functions/reference/quantileexact.md index 100d6ea129d..40b25c14988 100644 --- a/docs/en/sql-reference/aggregate-functions/reference/quantileexact.md +++ b/docs/en/sql-reference/aggregate-functions/reference/quantileexact.md @@ -49,6 +49,114 @@ Result: └───────────────────────┘ ``` +# quantileExactLow {#quantileexactlow} + +Similar to `quantileExact`, this computes the exact [quantile](https://en.wikipedia.org/wiki/Quantile) of a numeric data sequence. + +To get exact value, all the passed values are combined into an array, which is then fully sorted. The sorting [algorithm's](https://en.cppreference.com/w/cpp/algorithm/sort) complexity is `O(N·log(N))`, where `N = std::distance(first, last)` comparisons. + +Depending on the level, i.e if the level is 0.5 then the exact lower median value is returned if there are even number of elements and the middle value is returned if there are odd number of elements. Median is calculated similar to the [median_low](https://docs.python.org/3/library/statistics.html#statistics.median_low) implementation which is used in python. + +For all other levels, the element at the the index corresponding to the value of `level * size_of_array` is returned. For example: + +```$sql +SELECT quantileExactLow(0.1)(number) FROM numbers(10) + +┌─quantileExactLow(0.1)(number)─┐ +│ 1 │ +└───────────────────────────────┘ +``` + +When using multiple `quantile*` functions with different levels in a query, the internal states are not combined (that is, the query works less efficiently than it could). In this case, use the [quantiles](../../../sql-reference/aggregate-functions/reference/quantiles.md#quantiles) function. + +**Syntax** + +``` sql +quantileExact(level)(expr) +``` + +Alias: `medianExactLow`. + +**Parameters** + +- `level` — Level of quantile. Optional parameter. Constant floating-point number from 0 to 1. We recommend using a `level` value in the range of `[0.01, 0.99]`. Default value: 0.5. At `level=0.5` the function calculates [median](https://en.wikipedia.org/wiki/Median). +- `expr` — Expression over the column values resulting in numeric [data types](../../../sql-reference/data-types/index.md#data_types), [Date](../../../sql-reference/data-types/date.md) or [DateTime](../../../sql-reference/data-types/datetime.md). + +**Returned value** + +- Quantile of the specified level. + +Type: + +- [Float64](../../../sql-reference/data-types/float.md) for numeric data type input. +- [Date](../../../sql-reference/data-types/date.md) if input values have the `Date` type. +- [DateTime](../../../sql-reference/data-types/datetime.md) if input values have the `DateTime` type. + +**Example** + +Query: + +``` sql +SELECT quantileExactLow(number) FROM numbers(10) +``` + +Result: + +``` text +┌─quantileExactLow(number)─┐ +│ 4 │ +└──────────────────────────┘ +``` +# quantileExactHigh {#quantileexacthigh} + +Similar to `quantileExact`, this computes the exact [quantile](https://en.wikipedia.org/wiki/Quantile) of a numeric data sequence. + +To get exact value, all the passed values are combined into an array, which is then fully sorted. The sorting [algorithm's](https://en.cppreference.com/w/cpp/algorithm/sort) complexity is `O(N·log(N))`, where `N = std::distance(first, last)` comparisons. + +Depending on the level, i.e if the level is 0.5 then the exact higher median value is returned if there are even number of elements and the middle value is returned if there are odd number of elements. Median is calculated similar to the [median_high](https://docs.python.org/3/library/statistics.html#statistics.median_high) implementation which is used in python. For all other levels, the element at the the index corresponding to the value of `level * size_of_array` is returned. + +This implementation behaves exactly similar to the current `quantileExact` implementation. + +When using multiple `quantile*` functions with different levels in a query, the internal states are not combined (that is, the query works less efficiently than it could). In this case, use the [quantiles](../../../sql-reference/aggregate-functions/reference/quantiles.md#quantiles) function. + +**Syntax** + +``` sql +quantileExactHigh(level)(expr) +``` + +Alias: `medianExactHigh`. + +**Parameters** + +- `level` — Level of quantile. Optional parameter. Constant floating-point number from 0 to 1. We recommend using a `level` value in the range of `[0.01, 0.99]`. Default value: 0.5. At `level=0.5` the function calculates [median](https://en.wikipedia.org/wiki/Median). +- `expr` — Expression over the column values resulting in numeric [data types](../../../sql-reference/data-types/index.md#data_types), [Date](../../../sql-reference/data-types/date.md) or [DateTime](../../../sql-reference/data-types/datetime.md). + +**Returned value** + +- Quantile of the specified level. + +Type: + +- [Float64](../../../sql-reference/data-types/float.md) for numeric data type input. +- [Date](../../../sql-reference/data-types/date.md) if input values have the `Date` type. +- [DateTime](../../../sql-reference/data-types/datetime.md) if input values have the `DateTime` type. + +**Example** + +Query: + +``` sql +SELECT quantileExactHigh(number) FROM numbers(10) +``` + +Result: + +``` text +┌─quantileExactHigh(number)─┐ +│ 5 │ +└───────────────────────────┘ +``` **See Also** - [median](../../../sql-reference/aggregate-functions/reference/median.md#median) diff --git a/docs/en/sql-reference/functions/string-search-functions.md b/docs/en/sql-reference/functions/string-search-functions.md index 067644c30b2..a625af14505 100644 --- a/docs/en/sql-reference/functions/string-search-functions.md +++ b/docs/en/sql-reference/functions/string-search-functions.md @@ -21,15 +21,16 @@ For a case-insensitive search, use the function [positionCaseInsensitive](#posit **Syntax** ``` sql -position(haystack, needle) +position(haystack, needle[, start_pos]) ``` -Alias: `locate(haystack, needle)`. +Alias: `locate(haystack, needle[, start_pos])`. **Parameters** - `haystack` — string, in which substring will to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). - `needle` — substring to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Returned values** @@ -56,6 +57,18 @@ Result: └────────────────────────────────┘ ``` +``` sql +SELECT + position('Hello, world!', 'o', 1), + position('Hello, world!', 'o', 7) +``` + +``` text +┌─position('Hello, world!', 'o', 1)─┬─position('Hello, world!', 'o', 7)─┐ +│ 5 │ 9 │ +└───────────────────────────────────┴───────────────────────────────────┘ +``` + The same phrase in Russian contains characters which can’t be represented using a single byte. The function returns some unexpected result (use [positionUTF8](#positionutf8) function for multi-byte encoded text): Query: @@ -81,13 +94,14 @@ Works under the assumption that the string contains a set of bytes representing **Syntax** ``` sql -positionCaseInsensitive(haystack, needle) +positionCaseInsensitive(haystack, needle[, start_pos]) ``` **Parameters** - `haystack` — string, in which substring will to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). - `needle` — substring to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Returned values** @@ -123,13 +137,14 @@ For a case-insensitive search, use the function [positionCaseInsensitiveUTF8](#p **Syntax** ``` sql -positionUTF8(haystack, needle) +positionUTF8(haystack, needle[, start_pos]) ``` **Parameters** - `haystack` — string, in which substring will to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). - `needle` — substring to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Returned values** @@ -195,13 +210,14 @@ Works under the assumption that the string contains a set of bytes representing **Syntax** ``` sql -positionCaseInsensitiveUTF8(haystack, needle) +positionCaseInsensitiveUTF8(haystack, needle[, start_pos]) ``` **Parameters** - `haystack` — string, in which substring will to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). - `needle` — substring to be searched. [String](../../sql-reference/syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Returned value** diff --git a/docs/en/sql-reference/statements/alter/order-by.md b/docs/en/sql-reference/statements/alter/order-by.md index 1e2dadb2946..d41b9a91724 100644 --- a/docs/en/sql-reference/statements/alter/order-by.md +++ b/docs/en/sql-reference/statements/alter/order-by.md @@ -14,5 +14,4 @@ The command changes the [sorting key](../../../engines/table-engines/mergetree-f The command is lightweight in a sense that it only changes metadata. To keep the property that data part rows are ordered by the sorting key expression you cannot add expressions containing existing columns to the sorting key (only columns added by the `ADD COLUMN` command in the same `ALTER` query). !!! note "Note" - It only works for tables in the [`MergeTree`](../../../engines/table-engines/mergetree-family/mergetree.md) family (including -[replicated](../../../engines/table-engines/mergetree-family/replication.md) tables). + It only works for tables in the [`MergeTree`](../../../engines/table-engines/mergetree-family/mergetree.md) family (including [replicated](../../../engines/table-engines/mergetree-family/replication.md) tables). diff --git a/docs/es/development/style.md b/docs/es/development/style.md index 7e69423cf67..cca56a3bd22 100644 --- a/docs/es/development/style.md +++ b/docs/es/development/style.md @@ -705,7 +705,7 @@ Pero en igualdad de condiciones, se prefiere el código multiplataforma o portá **3.** Compilación: `gcc`. En este momento (agosto 2020), el código se compila utilizando la versión 9.3. (También se puede compilar usando `clang 8`.) -Se utiliza la biblioteca estándar (`libstdc++` o `libc++`). +Se utiliza la biblioteca estándar (`libc++`). **4.**OS: Linux Ubuntu, no más viejo que Precise. diff --git a/docs/es/development/tests.md b/docs/es/development/tests.md index 0d2931c97fa..b6c225894a5 100644 --- a/docs/es/development/tests.md +++ b/docs/es/development/tests.md @@ -175,7 +175,7 @@ Código principal de ClickHouse (que se encuentra en `dbms` directorio) se const Clang tiene advertencias aún más útiles: puedes buscarlas con `-Weverything` y elige algo para la compilación predeterminada. -Para las compilaciones de producción, se usa gcc (todavía genera un código ligeramente más eficiente que clang). Para el desarrollo, el clang suele ser más conveniente de usar. Puede construir en su propia máquina con el modo de depuración (para ahorrar batería de su computadora portátil), pero tenga en cuenta que el compilador puede generar más advertencias con `-O3` debido a un mejor flujo de control y análisis entre procedimientos. Al construir con clang, `libc++` se utiliza en lugar de `libstdc++` y al construir con el modo de depuración, la versión de depuración de `libc++` se utiliza que permite detectar más errores en tiempo de ejecución. +Para las compilaciones de producción, se usa gcc (todavía genera un código ligeramente más eficiente que clang). Para el desarrollo, el clang suele ser más conveniente de usar. Puede construir en su propia máquina con el modo de depuración (para ahorrar batería de su computadora portátil), pero tenga en cuenta que el compilador puede generar más advertencias con `-O3` debido a un mejor flujo de control y análisis entre procedimientos. Al construir con clang con el modo de depuración, la versión de depuración de `libc++` se utiliza que permite detectar más errores en tiempo de ejecución. ## Desinfectantes {#sanitizers} diff --git a/docs/es/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/es/engines/table-engines/mergetree-family/replacingmergetree.md index a1e95c5b5f4..cb3c6aea34b 100644 --- a/docs/es/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/es/engines/table-engines/mergetree-family/replacingmergetree.md @@ -33,7 +33,7 @@ Para obtener una descripción de los parámetros de solicitud, consulte [descrip **ReplacingMergeTree Parámetros** -- `ver` — column with version. Type `UInt*`, `Date` o `DateTime`. Parámetro opcional. +- `ver` — column with version. Type `UInt*`, `Date`, `DateTime` o `DateTime64`. Parámetro opcional. Al fusionar, `ReplacingMergeTree` de todas las filas con la misma clave primaria deja solo una: diff --git a/docs/es/interfaces/third-party/client-libraries.md b/docs/es/interfaces/third-party/client-libraries.md index 44186ec9135..9dbbe0a0022 100644 --- a/docs/es/interfaces/third-party/client-libraries.md +++ b/docs/es/interfaces/third-party/client-libraries.md @@ -46,6 +46,7 @@ toc_title: Client Libraries - Kotlin - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [ClickHouse.Ado](https://github.com/killwort/ClickHouse-Net) - [ClickHouse.Client](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/es/operations/system-tables.md b/docs/es/operations/system-tables.md index aca9c0cc917..6f487ce66e3 100644 --- a/docs/es/operations/system-tables.md +++ b/docs/es/operations/system-tables.md @@ -532,7 +532,7 @@ Columna: - `query` (String) – The query text. For `INSERT`, no incluye los datos para insertar. - `query_id` (String) – Query ID, if defined. -## sistema.text\_log {#system-tables-text-log} +## sistema.text\_log {#system_tables-text_log} Contiene entradas de registro. El nivel de registro que va a esta tabla se puede limitar con `text_log.level` configuración del servidor. diff --git a/docs/es/sql-reference/functions/string-search-functions.md b/docs/es/sql-reference/functions/string-search-functions.md index 3236745b22c..c448872a186 100644 --- a/docs/es/sql-reference/functions/string-search-functions.md +++ b/docs/es/sql-reference/functions/string-search-functions.md @@ -20,15 +20,16 @@ Para una búsqueda sin distinción de mayúsculas y minúsculas, utilice la func **Sintaxis** ``` sql -position(haystack, needle) +position(haystack, needle[, start_pos]) ``` -Apodo: `locate(haystack, needle)`. +Apodo: `locate(haystack, needle[, start_pos])`. **Parámetros** - `haystack` — string, in which substring will to be searched. [Cadena](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Cadena](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Valores devueltos** @@ -80,13 +81,14 @@ Funciona bajo el supuesto de que la cadena contiene un conjunto de bytes que rep **Sintaxis** ``` sql -positionCaseInsensitive(haystack, needle) +positionCaseInsensitive(haystack, needle[, start_pos]) ``` **Parámetros** - `haystack` — string, in which substring will to be searched. [Cadena](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Cadena](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Valores devueltos** @@ -122,13 +124,14 @@ Para una búsqueda sin distinción de mayúsculas y minúsculas, utilice la func **Sintaxis** ``` sql -positionUTF8(haystack, needle) +positionUTF8(haystack, needle[, start_pos]) ``` **Parámetros** - `haystack` — string, in which substring will to be searched. [Cadena](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Cadena](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Valores devueltos** @@ -194,13 +197,14 @@ Funciona bajo el supuesto de que la cadena contiene un conjunto de bytes que rep **Sintaxis** ``` sql -positionCaseInsensitiveUTF8(haystack, needle) +positionCaseInsensitiveUTF8(haystack, needle[, start_pos]) ``` **Parámetros** - `haystack` — string, in which substring will to be searched. [Cadena](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Cadena](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Valor devuelto** diff --git a/docs/fa/development/style.md b/docs/fa/development/style.md index 094d666e716..7bfe43c49fe 100644 --- a/docs/fa/development/style.md +++ b/docs/fa/development/style.md @@ -706,7 +706,7 @@ auto s = std::string{"Hello"}; **3.** کامپایلر: `gcc`. در این زمان (اوت 2020), کد با استفاده از نسخه وارد شده 9.3. (همچنین می تواند با استفاده از وارد شود `clang 8`.) -کتابخانه استاندارد استفاده شده است (`libstdc++` یا `libc++`). +کتابخانه استاندارد استفاده شده است (`libc++`). **4.**سیستم عامل: لینوکس اوبونتو, مسن تر از دقیق نیست. diff --git a/docs/fa/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/fa/engines/table-engines/mergetree-family/replacingmergetree.md index 0ace0e05afc..4ece20461cb 100644 --- a/docs/fa/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/fa/engines/table-engines/mergetree-family/replacingmergetree.md @@ -33,7 +33,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] **پارامترهای جایگزین** -- `ver` — column with version. Type `UInt*`, `Date` یا `DateTime`. پارامتر اختیاری. +- `ver` — column with version. Type `UInt*`, `Date`, `DateTime` یا `DateTime64`. پارامتر اختیاری. هنگام ادغام, `ReplacingMergeTree` از تمام ردیف ها با همان کلید اصلی تنها یک برگ دارد: diff --git a/docs/fa/interfaces/third-party/client-libraries.md b/docs/fa/interfaces/third-party/client-libraries.md index 60829aded12..4d35089e1d3 100644 --- a/docs/fa/interfaces/third-party/client-libraries.md +++ b/docs/fa/interfaces/third-party/client-libraries.md @@ -49,6 +49,7 @@ toc_title: "\u06A9\u062A\u0627\u0628\u062E\u0627\u0646\u0647 \u0647\u0627\u06CC - کوتلین - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [فاحشه خانه.ادو](https://github.com/killwort/ClickHouse-Net) - [فاحشه خانه.کارگیر](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/fa/operations/system-tables.md b/docs/fa/operations/system-tables.md index f601dbc5804..39e90e4130f 100644 --- a/docs/fa/operations/system-tables.md +++ b/docs/fa/operations/system-tables.md @@ -532,7 +532,7 @@ CurrentMetric_ReplicatedChecks: 0 - `query` (String) – The query text. For `INSERT` این شامل داده ها برای وارد کردن نیست. - `query_id` (String) – Query ID, if defined. -## سیستم.\_خروج {#system-tables-text-log} +## سیستم.\_خروج {#system_tables-text_log} شامل ورودی ورود به سیستم. سطح ورود به سیستم که می رود به این جدول را می توان با محدود `text_log.level` تنظیم سرور. diff --git a/docs/fa/sql-reference/functions/string-search-functions.md b/docs/fa/sql-reference/functions/string-search-functions.md index af68dee0afa..cce6f8f5a4e 100644 --- a/docs/fa/sql-reference/functions/string-search-functions.md +++ b/docs/fa/sql-reference/functions/string-search-functions.md @@ -21,15 +21,16 @@ toc_title: "\u0628\u0631\u0627\u06CC \u062C\u0633\u062A\u062C\u0648\u06CC \u0631 **نحو** ``` sql -position(haystack, needle) +position(haystack, needle[, start_pos]) ``` -نام مستعار: `locate(haystack, needle)`. +نام مستعار: `locate(haystack, needle[, start_pos])`. **پارامترها** - `haystack` — string, in which substring will to be searched. [رشته](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [رشته](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **مقادیر بازگشتی** @@ -81,13 +82,14 @@ SELECT position('Привет, мир!', '!') **نحو** ``` sql -positionCaseInsensitive(haystack, needle) +positionCaseInsensitive(haystack, needle[, start_pos]) ``` **پارامترها** - `haystack` — string, in which substring will to be searched. [رشته](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [رشته](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **مقادیر بازگشتی** @@ -123,13 +125,14 @@ SELECT positionCaseInsensitive('Hello, world!', 'hello') **نحو** ``` sql -positionUTF8(haystack, needle) +positionUTF8(haystack, needle[, start_pos]) ``` **پارامترها** - `haystack` — string, in which substring will to be searched. [رشته](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [رشته](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **مقادیر بازگشتی** @@ -195,13 +198,14 @@ SELECT positionUTF8('Salut, étudiante!', '!') **نحو** ``` sql -positionCaseInsensitiveUTF8(haystack, needle) +positionCaseInsensitiveUTF8(haystack, needle[, start_pos]) ``` **پارامترها** - `haystack` — string, in which substring will to be searched. [رشته](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [رشته](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **مقدار بازگشتی** diff --git a/docs/fr/development/style.md b/docs/fr/development/style.md index 65cc1a507a9..9a0035ce41e 100644 --- a/docs/fr/development/style.md +++ b/docs/fr/development/style.md @@ -705,7 +705,7 @@ Mais toutes choses étant égales par ailleurs, le code multi-plateforme ou port **3.** Compilateur: `gcc`. En ce moment (août 2020), le code est compilé en utilisant la version 9.3. (Il peut également être compilé en utilisant `clang 8`.) -La bibliothèque standard est utilisée (`libstdc++` ou `libc++`). +La bibliothèque standard est utilisée (`libc++`). **4.**OS: Linux Ubuntu, pas plus vieux que précis. diff --git a/docs/fr/development/tests.md b/docs/fr/development/tests.md index c059472bb0c..4664f533c0a 100644 --- a/docs/fr/development/tests.md +++ b/docs/fr/development/tests.md @@ -175,7 +175,7 @@ Code ClickHouse principal (qui est situé dans `dbms` annuaire) est construit av Clang a des avertissements encore plus utiles - vous pouvez les chercher avec `-Weverything` et choisissez quelque chose à construire par défaut. -Pour les builds de production, gcc est utilisé (il génère toujours un code légèrement plus efficace que clang). Pour le développement, clang est généralement plus pratique à utiliser. Vous pouvez construire sur votre propre machine avec le mode débogage (pour économiser la batterie de votre ordinateur portable), mais veuillez noter que le compilateur est capable de générer plus d'Avertissements avec `-O3` grâce à une meilleure analyse du flux de contrôle et de l'inter-procédure. Lors de la construction avec clang, `libc++` est utilisé au lieu de `libstdc++` et lors de la construction avec le mode débogage, la version de débogage de `libc++` est utilisé qui permet d'attraper plus d'erreurs à l'exécution. +Pour les builds de production, gcc est utilisé (il génère toujours un code légèrement plus efficace que clang). Pour le développement, clang est généralement plus pratique à utiliser. Vous pouvez construire sur votre propre machine avec le mode débogage (pour économiser la batterie de votre ordinateur portable), mais veuillez noter que le compilateur est capable de générer plus d'Avertissements avec `-O3` grâce à une meilleure analyse du flux de contrôle et de l'inter-procédure. Lors de la construction avec clang avec le mode débogage, la version de débogage de `libc++` est utilisé qui permet d'attraper plus d'erreurs à l'exécution. ## Désinfectant {#sanitizers} diff --git a/docs/fr/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/fr/engines/table-engines/mergetree-family/replacingmergetree.md index ac3c0f3b021..755249c1a38 100644 --- a/docs/fr/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/fr/engines/table-engines/mergetree-family/replacingmergetree.md @@ -33,7 +33,7 @@ Pour une description des paramètres de requête, voir [demande de description]( **ReplacingMergeTree Paramètres** -- `ver` — column with version. Type `UInt*`, `Date` ou `DateTime`. Paramètre facultatif. +- `ver` — column with version. Type `UInt*`, `Date`, `DateTime` ou `DateTime64`. Paramètre facultatif. Lors de la fusion, `ReplacingMergeTree` de toutes les lignes avec la même clé primaire ne laisse qu'un: diff --git a/docs/fr/interfaces/third-party/client-libraries.md b/docs/fr/interfaces/third-party/client-libraries.md index f07a27aec6c..c3385d207a3 100644 --- a/docs/fr/interfaces/third-party/client-libraries.md +++ b/docs/fr/interfaces/third-party/client-libraries.md @@ -48,6 +48,7 @@ toc_title: "Biblioth\xE8ques Clientes" - Kotlin - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [ClickHouse.Ado](https://github.com/killwort/ClickHouse-Net) - [ClickHouse.Client](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/fr/operations/system-tables.md b/docs/fr/operations/system-tables.md index 85451607b86..d779f20a96a 100644 --- a/docs/fr/operations/system-tables.md +++ b/docs/fr/operations/system-tables.md @@ -532,7 +532,7 @@ Colonne: - `query` (String) – The query text. For `INSERT` il n'inclut pas les données à insérer. - `query_id` (String) – Query ID, if defined. -## système.text\_log {#system-tables-text-log} +## système.text\_log {#system_tables-text_log} Contient des entrées de journalisation. Niveau de journalisation qui va à cette table peut être limité `text_log.level` paramètre de serveur. diff --git a/docs/fr/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md b/docs/fr/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md index 559d8adaa6f..f1e65631a56 100644 --- a/docs/fr/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md +++ b/docs/fr/sql-reference/dictionaries/external-dictionaries/external-dicts-dict-layout.md @@ -320,10 +320,9 @@ ou LAYOUT(DIRECT()) ``` -### complex\_key\_cache {#complex-key-cache} - -Ce type de stockage est pour une utilisation avec composite [touches](external-dicts-dict-structure.md). Semblable à `direct`. +### complex\_key\_direct {#complex-key-direct} +Ce type de stockage est destiné à être utilisé avec des [clés](../../../sql-reference/dictionaries/external-dictionaries/external-dicts-dict-structure.md) composites. Similaire à `direct` ### ip\_trie {#ip-trie} diff --git a/docs/ja/development/style.md b/docs/ja/development/style.md index 21051c6cc12..d0f6fb89900 100644 --- a/docs/ja/development/style.md +++ b/docs/ja/development/style.md @@ -705,7 +705,7 @@ auto s = std::string{"Hello"}; **3.** コンパイラ: `gcc`. 2020年現在、コードはバージョン9.3を使用してコンパイルされている。 (以下を使ってコンパイルできます `clang 8`.) -標準ライブラリが使用されます (`libstdc++` または `libc++`). +標準ライブラリが使用されます (`libc++`). **4.**OS:LinuxのUbuntuの、正確よりも古いではありません。 diff --git a/docs/ja/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/ja/engines/table-engines/mergetree-family/replacingmergetree.md index c3df9559415..e2cce893e3a 100644 --- a/docs/ja/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/ja/engines/table-engines/mergetree-family/replacingmergetree.md @@ -33,7 +33,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] **ReplacingMergeTreeパラメータ** -- `ver` — column with version. Type `UInt*`, `Date` または `DateTime`. 任意パラメータ。 +- `ver` — column with version. Type `UInt*`, `Date`, `DateTime` または `DateTime64`. 任意パラメータ。 マージ時, `ReplacingMergeTree` 同じ主キーを持つすべての行から、一つだけを残します: diff --git a/docs/ja/interfaces/third-party/client-libraries.md b/docs/ja/interfaces/third-party/client-libraries.md index 4a68c25281b..b88fe0c7389 100644 --- a/docs/ja/interfaces/third-party/client-libraries.md +++ b/docs/ja/interfaces/third-party/client-libraries.md @@ -48,6 +48,7 @@ toc_title: "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8" - コトリン - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [クリックハウスAdo](https://github.com/killwort/ClickHouse-Net) - [クリックハウスクライアン](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/ja/operations/system-tables.md b/docs/ja/operations/system-tables.md index 117076b897d..e7488b0fa44 100644 --- a/docs/ja/operations/system-tables.md +++ b/docs/ja/operations/system-tables.md @@ -532,7 +532,7 @@ CurrentMetric_ReplicatedChecks: 0 - `query` (String) – The query text. For `INSERT`,挿入するデータは含まれません。 - `query_id` (String) – Query ID, if defined. -## システムtext\_log {#system-tables-text-log} +## システムtext\_log {#system_tables-text_log} を含むログイン作品の応募がありました。 ログレベルがこのテーブルで限定 `text_log.level` サーバー設定。 diff --git a/docs/ja/sql-reference/functions/string-search-functions.md b/docs/ja/sql-reference/functions/string-search-functions.md index 00f68c061dd..e5858ba4941 100644 --- a/docs/ja/sql-reference/functions/string-search-functions.md +++ b/docs/ja/sql-reference/functions/string-search-functions.md @@ -20,15 +20,16 @@ toc_title: "\u6587\u5B57\u5217\u3092\u691C\u7D22\u3059\u308B\u5834\u5408" **構文** ``` sql -position(haystack, needle) +position(haystack, needle[, start_pos]) ``` -別名: `locate(haystack, needle)`. +別名: `locate(haystack, needle[, start_pos])`. **パラメータ** - `haystack` — string, in which substring will to be searched. [文字列](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [文字列](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **戻り値** @@ -80,13 +81,14 @@ SELECT position('Привет, мир!', '!') **構文** ``` sql -positionCaseInsensitive(haystack, needle) +positionCaseInsensitive(haystack, needle[, start_pos]) ``` **パラメータ** - `haystack` — string, in which substring will to be searched. [文字列](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [文字列](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **戻り値** @@ -122,13 +124,14 @@ SELECT positionCaseInsensitive('Hello, world!', 'hello') **構文** ``` sql -positionUTF8(haystack, needle) +positionUTF8(haystack, needle[, start_pos]) ``` **パラメータ** - `haystack` — string, in which substring will to be searched. [文字列](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [文字列](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **戻り値** @@ -194,13 +197,14 @@ SELECT positionUTF8('Salut, étudiante!', '!') **構文** ``` sql -positionCaseInsensitiveUTF8(haystack, needle) +positionCaseInsensitiveUTF8(haystack, needle[, start_pos]) ``` **パラメータ** - `haystack` — string, in which substring will to be searched. [文字列](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [文字列](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **戻り値** diff --git a/docs/ru/engines/table-engines/log-family/index.md b/docs/ru/engines/table-engines/log-family/index.md index 4aa7540c0a8..d2cb0df5a8a 100644 --- a/docs/ru/engines/table-engines/log-family/index.md +++ b/docs/ru/engines/table-engines/log-family/index.md @@ -26,7 +26,7 @@ toc_priority: 29 Во время запросов `INSERT` таблица блокируется, а другие запросы на чтение и запись ожидают разблокировки таблицы. Если запросов на запись данных нет, то можно выполнять любое количество конкуретных запросов на чтение. -- Не поддерживают операции [мутации](../../../sql-reference/statements/alter.md#mutations). +- Не поддерживают операции [мутации](../../../sql-reference/statements/alter/index.md#mutations). - Не поддерживают индексы. diff --git a/docs/ru/engines/table-engines/mergetree-family/custom-partitioning-key.md b/docs/ru/engines/table-engines/mergetree-family/custom-partitioning-key.md index 2e8b946ee8c..89980a3bd73 100644 --- a/docs/ru/engines/table-engines/mergetree-family/custom-partitioning-key.md +++ b/docs/ru/engines/table-engines/mergetree-family/custom-partitioning-key.md @@ -113,7 +113,7 @@ drwxr-xr-x 2 clickhouse clickhouse 4096 Feb 1 16:48 detached ‘201901\_1\_1\_0’, ‘201901\_1\_7\_1’ и т. д. – это директории кусков партиции. Каждый кусок содержит данные только для соответствующего месяца (таблица в данном примере содержит партиционирование по месяцам). -Директория `detached` содержит куски, отсоединенные от таблицы с помощью запроса [DETACH](../../../sql-reference/statements/alter.md#alter_detach-partition). Поврежденные куски также попадают в эту директорию – они не удаляются с сервера. +Директория `detached` содержит куски, отсоединенные от таблицы с помощью запроса [DETACH](../../../sql-reference/statements/alter/partition.md#alter_detach-partition). Поврежденные куски также попадают в эту директорию – они не удаляются с сервера. Сервер не использует куски из директории `detached`. Вы можете в любое время добавлять, удалять, модифицировать данные в директории detached - сервер не будет об этом знать, пока вы не сделаете запрос [ATTACH](../../../engines/table-engines/mergetree-family/custom-partitioning-key.md#alter_attach-partition). diff --git a/docs/ru/engines/table-engines/mergetree-family/mergetree.md b/docs/ru/engines/table-engines/mergetree-family/mergetree.md index 5eed6ddd3b4..f04fbae18ba 100644 --- a/docs/ru/engines/table-engines/mergetree-family/mergetree.md +++ b/docs/ru/engines/table-engines/mergetree-family/mergetree.md @@ -601,7 +601,7 @@ SETTINGS storage_policy = 'moving_from_ssd_to_hdd' В таблицах `MergeTree` данные попадают на диск несколькими способами: - В результате вставки (запрос `INSERT`). -- В фоновых операциях слияний и [мутаций](../../../sql-reference/statements/alter.md#mutations). +- В фоновых операциях слияний и [мутаций](../../../sql-reference/statements/alter/index.md#mutations). - При скачивании данных с другой реплики. - В результате заморозки партиций [ALTER TABLE … FREEZE PARTITION](../../../engines/table-engines/mergetree-family/mergetree.md#alter_freeze-partition). diff --git a/docs/ru/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/ru/engines/table-engines/mergetree-family/replacingmergetree.md index 4aa1eb556f3..fefc3c65b38 100644 --- a/docs/ru/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/ru/engines/table-engines/mergetree-family/replacingmergetree.md @@ -25,7 +25,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] **Параметры ReplacingMergeTree** -- `ver` — столбец с версией, тип `UInt*`, `Date` или `DateTime`. Необязательный параметр. +- `ver` — столбец с версией, тип `UInt*`, `Date`, `DateTime` или `DateTime64`. Необязательный параметр. При слиянии, из всех строк с одинаковым значением ключа сортировки `ReplacingMergeTree` оставляет только одну: diff --git a/docs/ru/interfaces/third-party/client-libraries.md b/docs/ru/interfaces/third-party/client-libraries.md index 928c1393c26..52ff782b790 100644 --- a/docs/ru/interfaces/third-party/client-libraries.md +++ b/docs/ru/interfaces/third-party/client-libraries.md @@ -40,6 +40,7 @@ - Kotlin - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [ClickHouse.Ado](https://github.com/killwort/ClickHouse-Net) - [ClickHouse.Client](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/ru/operations/access-rights.md b/docs/ru/operations/access-rights.md index edce9f3920e..27dbc2fbf62 100644 --- a/docs/ru/operations/access-rights.md +++ b/docs/ru/operations/access-rights.md @@ -56,7 +56,7 @@ ClickHouse поддерживает управление доступом на Запросы управления: - [CREATE USER](../sql-reference/statements/create/user.md#create-user-statement) -- [ALTER USER](../sql-reference/statements/alter.md#alter-user-statement) +- [ALTER USER](../sql-reference/statements/alter/user.md) - [DROP USER](../sql-reference/statements/misc.md#drop-user-statement) - [SHOW CREATE USER](../sql-reference/statements/show.md#show-create-user-statement) @@ -83,7 +83,7 @@ ClickHouse поддерживает управление доступом на Запросы управления: - [CREATE ROLE](../sql-reference/statements/create/index.md#create-role-statement) -- [ALTER ROLE](../sql-reference/statements/alter.md#alter-role-statement) +- [ALTER ROLE](../sql-reference/statements/alter/role.md) - [DROP ROLE](../sql-reference/statements/misc.md#drop-role-statement) - [SET ROLE](../sql-reference/statements/misc.md#set-role-statement) - [SET DEFAULT ROLE](../sql-reference/statements/misc.md#set-default-role-statement) @@ -98,7 +98,7 @@ ClickHouse поддерживает управление доступом на Запросы управления: - [CREATE ROW POLICY](../sql-reference/statements/create/index.md#create-row-policy-statement) -- [ALTER ROW POLICY](../sql-reference/statements/alter.md#alter-row-policy-statement) +- [ALTER ROW POLICY](../sql-reference/statements/alter/row-policy.md) - [DROP ROW POLICY](../sql-reference/statements/misc.md#drop-row-policy-statement) - [SHOW CREATE ROW POLICY](../sql-reference/statements/show.md#show-create-row-policy-statement) @@ -110,7 +110,7 @@ ClickHouse поддерживает управление доступом на Запросы управления: - [CREATE SETTINGS PROFILE](../sql-reference/statements/create/index.md#create-settings-profile-statement) -- [ALTER SETTINGS PROFILE](../sql-reference/statements/alter.md#alter-settings-profile-statement) +- [ALTER SETTINGS PROFILE](../sql-reference/statements/alter/settings-profile.md) - [DROP SETTINGS PROFILE](../sql-reference/statements/misc.md#drop-settings-profile-statement) - [SHOW CREATE SETTINGS PROFILE](../sql-reference/statements/show.md#show-create-settings-profile-statement) @@ -124,7 +124,7 @@ ClickHouse поддерживает управление доступом на Запросы управления: - [CREATE QUOTA](../sql-reference/statements/create/index.md#create-quota-statement) -- [ALTER QUOTA](../sql-reference/statements/alter.md#alter-quota-statement) +- [ALTER QUOTA](../sql-reference/statements/alter/quota.md) - [DROP QUOTA](../sql-reference/statements/misc.md#drop-quota-statement) - [SHOW CREATE QUOTA](../sql-reference/statements/show.md#show-create-quota-statement) diff --git a/docs/ru/operations/backup.md b/docs/ru/operations/backup.md index 6badaa7f724..89fb0403543 100644 --- a/docs/ru/operations/backup.md +++ b/docs/ru/operations/backup.md @@ -27,7 +27,7 @@ ClickHouse позволяет использовать запрос `ALTER TABLE ... FREEZE PARTITION ...` для создания локальной копии партиций таблицы. Это реализуется с помощью жестких ссылок (hardlinks) на каталог `/var/lib/clickhouse/shadow/`, поэтому такая копия обычно не занимает дополнительное место на диске для старых данных. Созданные копии файлов не обрабатываются сервером ClickHouse, поэтому вы можете просто оставить их там: у вас будет простая резервная копия, которая не требует дополнительной внешней системы, однако при аппаратных проблемах вы можете утратить и актуальные данные и сохраненную копию. По этой причине, лучше удаленно скопировать их в другое место, а затем удалить локальную копию. Распределенные файловые системы и хранилища объектов по-прежнему являются хорошими вариантами для этого, однако можно использовать и обычные присоединенные файловые серверы с достаточно большой ёмкостью (в этом случае передача будет происходить через сетевую файловую систему или, возможно, [rsync](https://en.wikipedia.org/wiki/Rsync)). -Дополнительные сведения о запросах, связанных с манипуляциями партициями, см. в разделе [ALTER](../sql-reference/statements/alter.md#alter_manipulations-with-partitions). +Дополнительные сведения о запросах, связанных с манипуляциями партициями, см. в разделе [ALTER](../sql-reference/statements/alter/partition.md#alter_manipulations-with-partitions). Для автоматизации этого подхода доступен инструмент от сторонних разработчиков: [clickhouse-backup](https://github.com/AlexAkulov/clickhouse-backup). diff --git a/docs/ru/operations/server-configuration-parameters/settings.md b/docs/ru/operations/server-configuration-parameters/settings.md index 63319ed2c01..795a9f5893a 100644 --- a/docs/ru/operations/server-configuration-parameters/settings.md +++ b/docs/ru/operations/server-configuration-parameters/settings.md @@ -26,21 +26,28 @@ ClickHouse перезагружает встроенные словари с з ``` xml - + ... + ... + ... ... ``` -Можно сконфигурировать несколько разделов ``. - Поля блока ``: - `min_part_size` - Минимальный размер части таблицы. - `min_part_size_ratio` - Отношение размера минимальной части таблицы к полному размеру таблицы. -- `method` - Метод сжатия. Возможные значения: `lz4`, `zstd` (экспериментальный). +- `method` - Метод сжатия. Возможные значения: `lz4`, `zstd`. -ClickHouse проверит условия `min_part_size` и `min_part_size_ratio` и выполнит те блоки `case`, для которых условия совпали. Если ни один `` не подходит, то ClickHouse применит алгоритм сжатия `lz4`. +Можно сконфигурировать несколько разделов ``. + +ClickHouse проверяет условия для `min_part_size` и `min_part_size_ratio` и выполнит те блоки `case`, для которых условия совпали. + +- Если кусок данных совпадает с условиями, ClickHouse использует указанные метод сжатия. +- Если кусок данных совпадает с несколькими блоками `case`, ClickHouse использует перый совпавший блок условий. + +Если ни один `` не подходит, то ClickHouse применит алгоритм сжатия `lz4`. **Пример** @@ -217,7 +224,7 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat Путь к файлу с подстановками. -Подробности смотрите в разделе «[Конфигурационный файлы](../configuration-files.md#configuration_files)». +Подробности смотрите в разделе «[Конфигурационные файлы](../configuration-files.md#configuration_files)». **Пример** @@ -295,11 +302,11 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat Ключи: -- level - Уровень логирования. Допустимые значения: `trace`, `debug`, `information`, `warning`, `error`. -- log - Файл лога. Содержит все записи согласно `level`. -- errorlog - Файл лога ошибок. -- size - Размер файла. Действует для `log` и `errorlog`. Как только файл достиг размера `size`, ClickHouse архивирует и переименовывает его, а на его месте создает новый файл лога. -- count - Количество заархивированных файлов логов, которые сохраняет ClickHouse. +- `level` - Уровень логирования. Допустимые значения: `trace`, `debug`, `information`, `warning`, `error`. +- `log` - Файл лога. Содержит все записи согласно `level`. +- `errorlog` - Файл лога ошибок. +- `size` - Размер файла. Действует для `log` и `errorlog`. Как только файл достиг размера `size`, ClickHouse архивирует и переименовывает его, а на его месте создает новый файл лога. +- `count` - Количество заархивированных файлов логов, которые сохраняет ClickHouse. **Пример** @@ -327,14 +334,38 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat ``` +Ключи для syslog: + +- use\_syslog - обязательная настройка, если требуется запись в syslog +- address - хост\[:порт\] демона syslogd. Если не указан, используется локальный +- hostname - опционально, имя хоста, с которого отсылаются логи +- facility - [категория syslog](https://en.wikipedia.org/wiki/Syslog#Facility), записанная в верхнем регистре, с префиксом «LOG\_»: (`LOG_USER`, `LOG_DAEMON`, `LOG_LOCAL3` и прочие). + Значения по умолчанию: при указанном `address` - `LOG_USER`, иначе - `LOG_DAEMON` +- format - формат сообщений. Возможные значения - `bsd` и `syslog` + +## send\_crash\_reports {#server_configuration_parameters-logger} + +Настройки для отправки сообщений о сбоях в команду разработчиков ядра ClickHouse через [Sentry](https://sentry.io). +Включение этих настроек, особенно в pre-production среде, может дать очень ценную информацию и поможет развитию ClickHouse. + +Сервер на котором включены данные настройки должен иметь доступ в Интернет по протоколу IPv4 (на момент написания документации IPv6 не поддерживается публичным облаком Sentry) для правильной работы данной функциональности. + Ключи: -- use\_syslog - обязательная настройка, если требуется запись в syslog -- address - хост\[:порт\] демона syslogd. Если не указан, используется локальный -- hostname - опционально, имя хоста, с которого отсылаются логи -- facility - [категория syslog](https://en.wikipedia.org/wiki/Syslog#Facility), -записанная в верхнем регистре, с префиксом «LOG\_»: (`LOG_USER`, `LOG_DAEMON`, `LOG_LOCAL3` и прочие). -Значения по умолчанию: при указанном `address` - `LOG_USER`, иначе - `LOG_DAEMON` -- format - формат сообщений. Возможные значения - `bsd` и `syslog` + +- `enabled` – Булевый флаг чтобы включить функциональность, по умолчанию `false`. Установите `true` чтобы разрешить отправку отчетов о сбоях. +- `endpoint` – Вы можете переопределить URL на который будут отсылаться отчеты об ошибках и использовать собственную инсталяцию Sentry. Используйте URL синтаксис [Sentry DSN](https://docs.sentry.io/error-reporting/quickstart/?platform=native#configure-the-sdk). +- `anonymize` - Запретить отсылку имени хоста сервера в отчете о сбое. +- `http_proxy` - Настройка HTTP proxy для отсылки отчетов о сбоях. +- `debug` - Настроить клиентскую библиотеку Sentry в debug режим. +- `tmp_path` - Путь в файловой системе для временного хранения состояния отчетов о сбоях перед отправкой на сервер Sentry. + +**Рекомендованые настройки** + +``` xml + + true + +``` ## macros {#macros} @@ -362,19 +393,9 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat 5368709120 ``` -## max\_concurrent\_queries {#max-concurrent-queries} +## max\_server\_memory\_usage {#max_server_memory_usage} -Максимальное количество одновременно обрабатываемых запросов. - -**Пример** - -``` xml -100 -``` - -## max_server_memory_usage {#max_server_memory_usage} - -Ограничивает объём оперативной памяти, используемой сервером ClickHouse. +Ограничивает объём оперативной памяти, используемой сервером ClickHouse. Настройка может быть задана только для профиля `default`. Возможные значения: @@ -389,7 +410,8 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat **См. также** -- [max_memory_usage](../settings/query-complexity.md#settings_max_memory_usage) +- [max\_memory\_usage](../../operations/settings/query-complexity.md#settings_max_memory_usage) +- [max_server_memory_usage_to_ram_ratio](#max_server_memory_usage_to_ram_ratio) ## max_server_memory_usage_to_ram_ratio {#max_server_memory_usage_to_ram_ratio} @@ -416,6 +438,16 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat - [max_server_memory_usage](#max_server_memory_usage) +## max\_concurrent\_queries {#max-concurrent-queries} + +Максимальное количество одновременно обрабатываемых запросов. + +**Пример** + +``` xml +100 +``` + ## max\_connections {#max-connections} Максимальное количество входящих соединений. @@ -458,6 +490,18 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat 0 ``` +## max\_thread\_pool\_size {#max-thread-pool-size} + +Максимальное кол-во потоков в глобальном пуле потоков. + +Default value: 10000. + +**Example** + +``` xml +12000 +``` + ## merge\_tree {#server_configuration_parameters-merge_tree} Тонкая настройка таблиц семейства [MergeTree](../../operations/server-configuration-parameters/settings.md). @@ -533,15 +577,16 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat ## part\_log {#server_configuration_parameters-part-log} -Логирование событий, связанных с данными типа [MergeTree](../../operations/server-configuration-parameters/settings.md). Например, события добавления или мержа данных. Лог можно использовать для симуляции алгоритмов слияния, чтобы сравнивать их характеристики. Также, можно визуализировать процесс слияния. +Логирование событий, связанных с данными типа [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md). Например, события добавления или мержа данных. Лог можно использовать для симуляции алгоритмов слияния, чтобы сравнивать их характеристики. Также, можно визуализировать процесс слияния. -Запросы логируются не в отдельный файл, а в таблицу [system.part\_log](../../operations/server-configuration-parameters/settings.md#system_tables-part-log). Вы можете изменить название этой таблицы в параметре `table` (см. ниже). +Запросы логируются не в отдельный файл, а в таблицу [system.part\_log](../../operations/system-tables/part_log.md#system_tables-part-log). Вы можете изменить название этой таблицы в параметре `table` (см. ниже). При настройке логирования используются следующие параметры: - `database` — имя базы данных; - `table` — имя таблицы; -- `partition_by` — устанавливает [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md); +- `partition_by` — устанавливает [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md). Нельзя использовать если используется `engine` +- `engine` - устанавливает [настройки MergeTree Engine](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) для системной таблицы. Нельзя использовать если используется `partition_by`. - `flush_interval_milliseconds` — период сброса данных из буфера в памяти в таблицу. **Пример** @@ -594,15 +639,16 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat ## query\_log {#server_configuration_parameters-query-log} -Настройка логирования запросов, принятых с настройкой [log\_queries=1](../settings/settings.md). +Настройка логирования запросов, принятых с настройкой [log\_queries=1](../../operations/settings/settings.md). -Запросы логируются не в отдельный файл, а в системную таблицу [system.query\_log](../../operations/server-configuration-parameters/settings.md#system_tables-query_log). Вы можете изменить название этой таблицы в параметре `table` (см. ниже). +Запросы логируются не в отдельный файл, а в системную таблицу [system.query\_log](../../operations/system-tables/query_log.md#system_tables-query_log). Вы можете изменить название этой таблицы в параметре `table` (см. ниже). При настройке логирования используются следующие параметры: - `database` — имя базы данных; - `table` — имя таблицы, куда будет записываться лог; -- `partition_by` — [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md) для таблицы с логами; +- `partition_by` — устанавливает [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md). Нельзя использовать если используется `engine` +- `engine` - устанавливает [настройки MergeTree Engine](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) для системной таблицы. Нельзя использовать если используется `partition_by`. - `flush_interval_milliseconds` — период сброса данных из буфера в памяти в таблицу. Если таблица не существует, то ClickHouse создаст её. Если структура журнала запросов изменилась при обновлении сервера ClickHouse, то таблица со старой структурой переименовывается, а новая таблица создается автоматически. @@ -613,7 +659,7 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat system query_log
- toMonday(event_date) + Engine = MergeTree PARTITION BY event_date ORDER BY event_time TTL event_date + INTERVAL 30 day 7500
``` @@ -622,13 +668,14 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat Настройка логирования потоков выполнения запросов, принятых с настройкой [log\_query\_threads=1](../settings/settings.md#settings-log-query-threads). -Запросы логируются не в отдельный файл, а в системную таблицу [system.query\_thread\_log](../../operations/server-configuration-parameters/settings.md#system_tables-query_thread_log). Вы можете изменить название этой таблицы в параметре `table` (см. ниже). +Запросы логируются не в отдельный файл, а в системную таблицу [system.query\_thread\_log](../../operations/system-tables/query_thread_log.md#system_tables-query_thread_log). Вы можете изменить название этой таблицы в параметре `table` (см. ниже). При настройке логирования используются следующие параметры: - `database` — имя базы данных; - `table` — имя таблицы, куда будет записываться лог; -- `partition_by` — [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md) для таблицы с логами; +- `partition_by` — устанавливает [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md). Нельзя использовать если используется `engine` +- `engine` - устанавливает [настройки MergeTree Engine](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) для системной таблицы. Нельзя использовать если используется `partition_by`. - `flush_interval_milliseconds` — период сброса данных из буфера в памяти в таблицу. Если таблица не существует, то ClickHouse создаст её. Если структура журнала запросов изменилась при обновлении сервера ClickHouse, то таблица со старой структурой переименовывается, а новая таблица создается автоматически. @@ -644,15 +691,44 @@ ClickHouse проверит условия `min_part_size` и `min_part_size_rat ``` +## text\_log {#server_configuration_parameters-text_log} + +Настройка логирования текстовых сообщений в системную таблицу [text\_log](../../operations/system-tables/text_log.md#system_tables-text_log). + +Параметры: + +- `level` — Максимальный уровень сообщения (по умолчанию `Trace`) которое будет сохранено в таблице. +- `database` — имя базы данных для хранения таблицы. +- `table` — имя таблицы, куда будут записываться текстовые сообщения. +- `partition_by` — устанавливает [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md). Нельзя использовать если используется `engine` +- `engine` - устанавливает [настройки MergeTree Engine](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) для системной таблицы. Нельзя использовать если используется `partition_by`. +- `flush_interval_milliseconds` — период сброса данных из буфера в памяти в таблицу. + +**Пример** +```xml + + + notice + system + text_log
+ 7500 + + Engine = MergeTree PARTITION BY event_date ORDER BY event_time TTL event_date + INTERVAL 30 day +
+
+``` + + ## trace\_log {#server_configuration_parameters-trace_log} -Settings for the [trace\_log](../../operations/server-configuration-parameters/settings.md#system_tables-trace_log) system table operation. +Настройки для [trace\_log](../../operations/system-tables/trace_log.md#system_tables-trace_log) system table operation. Parameters: - `database` — Database for storing a table. - `table` — Table name. -- `partition_by` — [Custom partitioning key](../../operations/server-configuration-parameters/settings.md) for a system table. +- `partition_by` — устанавливает [произвольный ключ партиционирования](../../operations/server-configuration-parameters/settings.md). Нельзя использовать если используется `engine` +- `engine` - устанавливает [настройки MergeTree Engine](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) для системной таблицы. Нельзя использовать если используется `partition_by`. - `flush_interval_milliseconds` — Interval for flushing data from the buffer in memory to the table. The default server configuration file `config.xml` contains the following settings section: @@ -666,6 +742,36 @@ The default server configuration file `config.xml` contains the following settin ``` +## query\_masking\_rules {#query-masking-rules} + +Правила основанные на регурялных выражениях, которые будут применены для всех запросов а также для всех сообщений перед сохранением их в лог на сервере, +`system.query_log`, `system.text_log`, `system.processes` таблицы, а также в логах отсылаемых клиенту. Это позволяет предотвратить +утечку конфиденциальных данных из SQL запросов (такие как имена, электронные письма, личные идентификаторы или номера кредитных карт) в логи. + +**Пример** + +``` xml + + + hide SSN + (^|\D)\d{3}-\d{2}-\d{4}($|\D) + 000-00-0000 + + +``` + +Параметры конфигурации: +- `name` - имя правила (необязательно) +- `regexp` - совместимое с RE2 регулярное выражение (обязательное) +- `replace` - строка замены для конфиденциальных данных (опционально, по умолчанию - шесть звездочек) + +Правила маскировки применяются ко всему запросу (для предотвращения утечки конфиденциальных данных из неправильно оформленных / не интерпритируемых запросов). + +`system.events` таблица содержит счетчик `QueryMaskingRulesMatch` который считает общее кол-во совпадений правил маскировки. + +Для распределенных запросов каждый сервер должен быть сконфигурирован отдельно, иначе, подзапросы, +переданные на другие узлы, будут сохраняться без маскировки. + ## remote\_servers {#server-settings-remote-servers} Конфигурация кластеров, которые использует движок таблиц [Distributed](../../operations/server-configuration-parameters/settings.md) и табличная функция `cluster`. @@ -724,6 +830,10 @@ TCP порт для защищённого обмена данными с кли Порт для взаимодействия с клиентами по протоколу MySQL. +**Возможные значения** + +Положительное целое. + Пример ``` xml @@ -742,7 +852,8 @@ TCP порт для защищённого обмена данными с кли ``` xml /var/lib/clickhouse/tmp/ ``` -## tmp_policy {#tmp-policy} + +## tmp\_policy {#tmp-policy} Политика из [storage_configuration](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-multiple-volumes) для хранения временных файлов. @@ -833,6 +944,7 @@ ClickHouse использует ZooKeeper для хранения метадан 2181 30000 + 10000 /path/to/zookeeper/node @@ -853,11 +965,11 @@ ClickHouse использует ZooKeeper для хранения метадан - Глобально в разделе [merge\_tree](#server_configuration_parameters-merge_tree) файла `config.xml`. - ClickHouse использует этот параметр для всех таблиц на сервере. Вы можете изменить настройку в любое время. Существующие таблицы изменяют свое поведение при изменении параметра. + ClickHouse использует этот параметр для всех таблиц на сервере. Вы можете изменить настройку в любое время. Существующие таблицы изменяют свое поведение при изменении параметра. - Для каждой отдельной таблицы. - При создании таблицы укажите соответствующую [настройку движка](../../operations/server_configuration_parameters/settings.md#table_engine-mergetree-creating-a-table). Поведение существующей таблицы с установленным параметром не изменяется даже при изменении глобального параметра. + При создании таблицы укажите соответствующую [настройку движка](../../operations/server-configuration-parameters/settings.md#table_engine-mergetree-creating-a-table). Поведение существующей таблицы с установленным параметром не изменяется даже при изменении глобального параметра. **Возможные значения** diff --git a/docs/ru/operations/settings/settings.md b/docs/ru/operations/settings/settings.md index 66d82d5a5c8..e8d3f1057df 100644 --- a/docs/ru/operations/settings/settings.md +++ b/docs/ru/operations/settings/settings.md @@ -1549,6 +1549,16 @@ SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1; Значение по умолчанию: `Пустая строка`. +## input_format_avro_allow_missing_fields {#input_format_avro_allow_missing_fields} +Позволяет использовать данные, которых не нашлось в схеме формата [Avro](../../interfaces/formats.md#data-format-avro) или [AvroConfluent](../../interfaces/formats.md#data-format-avro-confluent). Если поле не найдено в схеме, ClickHouse подставит значение по умолчанию вместо исключения. + +Возможные значения: + +- 0 — Выключена. +- 1 — Включена. + +Значение по умолчанию: `0`. + ## min_insert_block_size_rows_for_materialized_views {#min-insert-block-size-rows-for-materialized-views} Устанавливает минимальное количество строк в блоке, который может быть вставлен в таблицу запросом `INSERT`. Блоки меньшего размера склеиваются в блоки большего размера. Настройка применяется только для блоков, вставляемых в [материализованное представление](../../sql-reference/statements/create/view.md#create-view). Настройка позволяет избежать избыточного потребления памяти. @@ -1596,7 +1606,7 @@ SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1; ## mutations_sync {#mutations_sync} -Позволяет выполнять запросы `ALTER TABLE ... UPDATE|DELETE` ([мутации](../../sql-reference/statements/alter.md#mutations)) синхронно. +Позволяет выполнять запросы `ALTER TABLE ... UPDATE|DELETE` ([мутации](../../sql-reference/statements/alter/index.md#mutations)) синхронно. Возможные значения: @@ -1608,8 +1618,8 @@ SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1; **См. также** -- [Синхронность запросов ALTER](../../sql-reference/statements/alter.md#synchronicity-of-alter-queries) -- [Мутации](../../sql-reference/statements/alter.md#mutations) +- [Синхронность запросов ALTER](../../sql-reference/statements/alter/index.md#synchronicity-of-alter-queries) +- [Мутации](../../sql-reference/statements/alter/index.md#mutations) [Оригинальная статья](https://clickhouse.tech/docs/ru/operations/settings/settings/) diff --git a/docs/ru/operations/system-tables/mutations.md b/docs/ru/operations/system-tables/mutations.md index 4653e6ad418..044677030ba 100644 --- a/docs/ru/operations/system-tables/mutations.md +++ b/docs/ru/operations/system-tables/mutations.md @@ -1,6 +1,6 @@ # system.mutations {#system_tables-mutations} -Таблица содержит информацию о ходе выполнения [мутаций](../../sql-reference/statements/alter.md#mutations) таблиц семейства MergeTree. Каждой команде мутации соответствует одна строка таблицы. +Таблица содержит информацию о ходе выполнения [мутаций](../../sql-reference/statements/alter/index.md#mutations) таблиц семейства MergeTree. Каждой команде мутации соответствует одна строка таблицы. Столбцы: @@ -41,7 +41,7 @@ **См. также** -- [Мутации](../../sql-reference/statements/alter.md#mutations) +- [Мутации](../../sql-reference/statements/alter/index.md#mutations) - [Движок MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) - [Репликация данных](../../engines/table-engines/mergetree-family/replication.md) (семейство ReplicatedMergeTree) diff --git a/docs/ru/operations/system-tables/part_log.md b/docs/ru/operations/system-tables/part_log.md index 409947a1bda..255ece76ee2 100644 --- a/docs/ru/operations/system-tables/part_log.md +++ b/docs/ru/operations/system-tables/part_log.md @@ -10,7 +10,7 @@ - `NEW_PART` — вставка нового куска. - `MERGE_PARTS` — слияние кусков. - `DOWNLOAD_PART` — загрузка с реплики. - - `REMOVE_PART` — удаление или отсоединение из таблицы с помощью [DETACH PARTITION](../../sql-reference/statements/alter.md#alter_detach-partition). + - `REMOVE_PART` — удаление или отсоединение из таблицы с помощью [DETACH PARTITION](../../sql-reference/statements/alter/partition.md#alter_detach-partition). - `MUTATE_PART` — изменение куска. - `MOVE_PART` — перемещение куска между дисками. - `event_date` (Date) — дата события. diff --git a/docs/ru/operations/system-tables/parts.md b/docs/ru/operations/system-tables/parts.md index afedf20caf0..950e652332d 100644 --- a/docs/ru/operations/system-tables/parts.md +++ b/docs/ru/operations/system-tables/parts.md @@ -6,7 +6,7 @@ Столбцы: -- `partition` ([String](../../sql-reference/data-types/string.md)) – имя партиции. Что такое партиция можно узнать из описания запроса [ALTER](../../sql-reference/statements/alter.md#query_language_queries_alter). +- `partition` ([String](../../sql-reference/data-types/string.md)) – имя партиции. Что такое партиция можно узнать из описания запроса [ALTER](../../sql-reference/statements/alter/index.md#query_language_queries_alter). Форматы: @@ -66,7 +66,7 @@ - `primary_key_bytes_in_memory_allocated` ([UInt64](../../sql-reference/data-types/int-uint.md)) – объём памяти (в байтах) выделенный для размещения первичных ключей. -- `is_frozen` ([UInt8](../../sql-reference/data-types/int-uint.md)) – Признак, показывающий существование бэкапа партиции. 1, бэкап есть. 0, бэкапа нет. Смотрите раздел [FREEZE PARTITION](../../sql-reference/statements/alter.md#alter_freeze-partition). +- `is_frozen` ([UInt8](../../sql-reference/data-types/int-uint.md)) – Признак, показывающий существование бэкапа партиции. 1, бэкап есть. 0, бэкапа нет. Смотрите раздел [FREEZE PARTITION](../../sql-reference/statements/alter/partition.md#alter_freeze-partition). - `database` ([String](../../sql-reference/data-types/string.md)) – имя базы данных. diff --git a/docs/ru/operations/system-tables/text_log.md b/docs/ru/operations/system-tables/text_log.md index 984303b5f1f..01e34c914e6 100644 --- a/docs/ru/operations/system-tables/text_log.md +++ b/docs/ru/operations/system-tables/text_log.md @@ -1,4 +1,4 @@ -# system.text_log {#system-tables-text-log} +# system.text_log {#system_tables-text_log} Содержит записи логов. Уровень логирования для таблицы может быть ограничен параметром сервера `text_log.level`. diff --git a/docs/ru/operations/system-tables/trace_log.md b/docs/ru/operations/system-tables/trace_log.md index 12d33b7ba18..dec74b48487 100644 --- a/docs/ru/operations/system-tables/trace_log.md +++ b/docs/ru/operations/system-tables/trace_log.md @@ -1,33 +1,33 @@ # system.trace_log {#system_tables-trace_log} -Contains stack traces collected by the sampling query profiler. +Содержит экземпляры трассировки стека адресов вызова, собранные с помощью семплирующего профайлера запросов. -ClickHouse creates this table when the [trace\_log](../server-configuration-parameters/settings.md#server_configuration_parameters-trace_log) server configuration section is set. Also the [query_profiler_real_time_period_ns](../settings/settings.md#query_profiler_real_time_period_ns) and [query_profiler_cpu_time_period_ns](../settings/settings.md#query_profiler_cpu_time_period_ns) settings should be set. +ClickHouse создает эту таблицу когда утсановлена настройка [trace\_log](../server-configuration-parameters/settings.md#server_configuration_parameters-trace_log) в конфигурационном файле сервереа. А также настройки [query_profiler_real_time_period_ns](../settings/settings.md#query_profiler_real_time_period_ns) и [query_profiler_cpu_time_period_ns](../settings/settings.md#query_profiler_cpu_time_period_ns). -To analyze logs, use the `addressToLine`, `addressToSymbol` and `demangle` introspection functions. +Для анализа stack traces, используйте функции интроспекции `addressToLine`, `addressToSymbol` и `demangle`. -Columns: +Колонки: -- `event_date`([Date](../../sql-reference/data-types/date.md)) — Date of sampling moment. +- `event_date`([Date](../../sql-reference/data-types/date.md)) — Дата в момент снятия экземпляра стэка адресов вызова. -- `event_time`([DateTime](../../sql-reference/data-types/datetime.md)) — Timestamp of sampling moment. +- `event_time`([DateTime](../../sql-reference/data-types/datetime.md)) — Дата и время в момент снятия экземпляра стэка адресов вызова. -- `revision`([UInt32](../../sql-reference/data-types/int-uint.md)) — ClickHouse server build revision. +- `revision`([UInt32](../../sql-reference/data-types/int-uint.md)) — ревизия сборки сервера ClickHouse. - When connecting to server by `clickhouse-client`, you see the string similar to `Connected to ClickHouse server version 19.18.1 revision 54429.`. This field contains the `revision`, but not the `version` of a server. + Во время соединения с сервером через `clickhouse-client`, вы видите строку похожую на `Connected to ClickHouse server version 19.18.1 revision 54429.`. Это поле содержит номер после `revision`, но не содержит строку после `version`. -- `timer_type`([Enum8](../../sql-reference/data-types/enum.md)) — Timer type: +- `timer_type`([Enum8](../../sql-reference/data-types/enum.md)) — Тип таймера: - - `Real` represents wall-clock time. - - `CPU` represents CPU time. + - `Real` означает wall-clock время. + - `CPU` означает относительное CPU время. -- `thread_number`([UInt32](../../sql-reference/data-types/int-uint.md)) — Thread identifier. +- `thread_number`([UInt32](../../sql-reference/data-types/int-uint.md)) — Идентификатор треда. -- `query_id`([String](../../sql-reference/data-types/string.md)) — Query identifier that can be used to get details about a query that was running from the [query_log](#system_tables-query_log) system table. +- `query_id`([String](../../sql-reference/data-types/string.md)) — Идентификатор запроса который может быть использован для получения деталей о запросе из таблицы [query_log](query_log.md#system_tables-query_log) system table. -- `trace`([Array(UInt64)](../../sql-reference/data-types/array.md)) — Stack trace at the moment of sampling. Each element is a virtual memory address inside ClickHouse server process. +- `trace`([Array(UInt64)](../../sql-reference/data-types/array.md)) — Трассировка стека адресов вызова в момент семплирования. Каждый элемент массива это адрес виртуальной памяти внутри процесса сервера ClickHouse. -**Example** +**Пример** ``` sql SELECT * FROM system.trace_log LIMIT 1 \G diff --git a/docs/ru/sql-reference/aggregate-functions/reference/grouparraysample.md b/docs/ru/sql-reference/aggregate-functions/reference/grouparraysample.md new file mode 100644 index 00000000000..4c2dafe1a3c --- /dev/null +++ b/docs/ru/sql-reference/aggregate-functions/reference/grouparraysample.md @@ -0,0 +1,80 @@ +--- +toc_priority: 114 +--- + +# groupArraySample {#grouparraysample} + +Создает массив из случайно выбранных значений аргумента. Количество элементов в массиве ограничено значением параметра `max_size`. Элементы добавляются в результирующий массив в случайном порядке. + +**Синтаксис** + +``` sql +groupArraySample(max_size[, seed])(x) +``` + +**Параметры** + +- `max_size` — максимальное количество элементов в возвращаемом массиве. [UInt64](../../data-types/int-uint.md). +- `seed` — состояние генератора случайных чисел. Необязательный параметр. [UInt64](../../data-types/int-uint.md). Значение по умолчанию: `123456`. +- `x` — аргумент (название колонки таблицы или выражение). + +**Возвращаемые значения** + +- Массив случайно выбранных значений аргумента `x`. + +Тип: [Массив](../../data-types/array.md). + +**Примеры** + +Рассмотрим таблицу `colors`: + +``` text +┌─id─┬─color──┐ +│ 1 │ red │ +│ 2 │ blue │ +│ 3 │ green │ +│ 4 │ white │ +│ 5 │ orange │ +└────┴────────┘ +``` + +Запрос с названием колонки таблицы в качестве аргумента: + +``` sql +SELECT groupArraySample(3)(color) as newcolors FROM colors; +``` + +Результат: + +```text +┌─newcolors──────────────────┐ +│ ['white','blue','green'] │ +└────────────────────────────┘ +``` + +Запрос с названием колонки и другим состоянием генератора случайных чисел: + +``` sql +SELECT groupArraySample(3, 987654321)(color) as newcolors FROM colors; +``` + +Результат: + +```text +┌─newcolors─────────────────────────────┐ +│ ['red','orange','green'] │ +└───────────────────────────────────────┘ +``` + +Запрос с выражением в качестве аргумента: + +``` sql +SELECT groupArraySample(3)(concat('light-', color)) as newcolors FROM colors; +``` +Результат: + +```text +┌─newcolors───────────────────────────────────┐ +│ ['light-blue','light-orange','light-green'] │ +└─────────────────────────────────────────────┘ +``` diff --git a/docs/ru/sql-reference/data-types/special-data-types/interval.md b/docs/ru/sql-reference/data-types/special-data-types/interval.md index 8a4ace179a6..a77d05ab8be 100644 --- a/docs/ru/sql-reference/data-types/special-data-types/interval.md +++ b/docs/ru/sql-reference/data-types/special-data-types/interval.md @@ -74,5 +74,5 @@ Code: 43. DB::Exception: Received from localhost:9000. DB::Exception: Wrong argu ## Смотрите также {#smotrite-takzhe} -- Оператор[INTERVAL](../../../sql-reference/data-types/special-data-types/interval.md#operator-interval) +- Оператор [INTERVAL](../../../sql-reference/data-types/special-data-types/interval.md#operator-interval) - Функция приведения типа [toInterval](../../../sql-reference/data-types/special-data-types/interval.md#function-tointerval) diff --git a/docs/ru/sql-reference/functions/array-functions.md b/docs/ru/sql-reference/functions/array-functions.md index 99eda1bf45e..00d039ca3eb 100644 --- a/docs/ru/sql-reference/functions/array-functions.md +++ b/docs/ru/sql-reference/functions/array-functions.md @@ -964,7 +964,7 @@ SELECT flatten([[[1]], [[2], [3]]]) ## arrayCompact {#arraycompact} -Удаляет дубликаты из массива. Порядок результирующих значений определяется порядком в исходном массиве. +Удаляет последовательно повторяющиеся элементы из массива. Порядок результирующих значений определяется порядком в исходном массиве. **Синтаксис** @@ -978,7 +978,7 @@ arrayCompact(arr) **Возвращаемое значение** -Массив без дубликатов. +Массив без последовательных дубликатов. Тип: `Array`. diff --git a/docs/ru/sql-reference/functions/string-search-functions.md b/docs/ru/sql-reference/functions/string-search-functions.md index b363211d6d0..de713031046 100644 --- a/docs/ru/sql-reference/functions/string-search-functions.md +++ b/docs/ru/sql-reference/functions/string-search-functions.md @@ -15,15 +15,16 @@ **Синтаксис** ``` sql -position(haystack, needle) +position(haystack, needle[, start_pos]) ``` -Алиас: `locate(haystack, needle)`. +Алиас: `locate(haystack, needle[, start_pos])`. **Параметры** - `haystack` — строка, по которой выполняется поиск. [Строка](../syntax.md#syntax-string-literal). - `needle` — подстрока, которую необходимо найти. [Строка](../syntax.md#syntax-string-literal). +- `start_pos` – Опциональный параметр, позиция символа в строке, с которого начинается поиск. [UInt](../../sql-reference/data-types/int-uint.md) **Возвращаемые значения** @@ -75,13 +76,14 @@ SELECT position('Привет, мир!', '!') **Синтаксис** ``` sql -positionCaseInsensitive(haystack, needle) +positionCaseInsensitive(haystack, needle[, start_pos]) ``` **Параметры** - `haystack` — строка, по которой выполняется поиск. [Строка](../syntax.md#syntax-string-literal). - `needle` — подстрока, которую необходимо найти. [Строка](../syntax.md#syntax-string-literal). +- `start_pos` – Опциональный параметр, позиция символа в строке, с которого начинается поиск. [UInt](../../sql-reference/data-types/int-uint.md) **Возвращаемые значения** @@ -117,13 +119,14 @@ SELECT positionCaseInsensitive('Hello, world!', 'hello') **Синтаксис** ``` sql -positionUTF8(haystack, needle) +positionUTF8(haystack, needle[, start_pos]) ``` **Параметры** - `haystack` — строка, по которой выполняется поиск. [Строка](../syntax.md#syntax-string-literal). - `needle` — подстрока, которую необходимо найти. [Строка](../syntax.md#syntax-string-literal). +- `start_pos` – Опциональный параметр, позиция символа в строке, с которого начинается поиск. [UInt](../../sql-reference/data-types/int-uint.md) **Возвращаемые значения** @@ -189,13 +192,14 @@ SELECT positionUTF8('Salut, étudiante!', '!') **Синтаксис** ``` sql -positionCaseInsensitiveUTF8(haystack, needle) +positionCaseInsensitiveUTF8(haystack, needle[, start_pos]) ``` **Параметры** - `haystack` — строка, по которой выполняется поиск. [Строка](../syntax.md#syntax-string-literal). - `needle` — подстрока, которую необходимо найти. [Строка](../syntax.md#syntax-string-literal). +- `start_pos` – Опциональный параметр, позиция символа в строке, с которого начинается поиск. [UInt](../../sql-reference/data-types/int-uint.md) **Возвращаемые значения** diff --git a/docs/ru/sql-reference/index.md b/docs/ru/sql-reference/index.md index 92983d6d18a..f59232ee047 100644 --- a/docs/ru/sql-reference/index.md +++ b/docs/ru/sql-reference/index.md @@ -10,7 +10,7 @@ toc_title: hidden - [SELECT](statements/select/index.md) - [INSERT INTO](statements/insert-into.md) - [CREATE](statements/create/index.md) -- [ALTER](statements/alter.md#query_language_queries_alter) +- [ALTER](statements/alter/index.md#query_language_queries_alter) - [Прочие виды запросов](statements/misc.md) [Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/) diff --git a/docs/ru/sql-reference/statements/alter.md b/docs/ru/sql-reference/statements/alter.md deleted file mode 100644 index 7cac767e842..00000000000 --- a/docs/ru/sql-reference/statements/alter.md +++ /dev/null @@ -1,613 +0,0 @@ ---- -toc_priority: 36 -toc_title: ALTER ---- - -## ALTER {#query_language_queries_alter} - -Запрос `ALTER` поддерживается только для таблиц типа `*MergeTree`, а также `Merge` и `Distributed`. Запрос имеет несколько вариантов. - -### Манипуляции со столбцами {#manipuliatsii-so-stolbtsami} - -Изменение структуры таблицы. - -``` sql -ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ... -``` - -В запросе указывается список из одного или более действий через запятую. -Каждое действие — операция над столбцом. - -Существуют следующие действия: - -- [ADD COLUMN](#alter_add-column) — добавляет столбец в таблицу; -- [DROP COLUMN](#alter_drop-column) — удаляет столбец; -- [CLEAR COLUMN](#alter_clear-column) — сбрасывает все значения в столбце для заданной партиции; -- [COMMENT COLUMN](#alter_comment-column) — добавляет комментарий к столбцу; -- [MODIFY COLUMN](#alter_modify-column) — изменяет тип столбца, выражение для значения по умолчанию и TTL. - -Подробное описание для каждого действия приведено ниже. - -#### ADD COLUMN {#alter_add-column} - -``` sql -ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [codec] [AFTER name_after] -``` - -Добавляет в таблицу новый столбец с именем `name`, типом `type`, [кодеком](create/table.md#codecs) `codec` и выражением для умолчания `default_expr` (смотрите раздел [Значения по умолчанию](create/index.md#create-default-values)). - -Если указано `IF NOT EXISTS`, запрос не будет возвращать ошибку, если столбец уже существует. Если указано `AFTER name_after` (имя другого столбца), то столбец добавляется (в список столбцов таблицы) после указанного. Иначе, столбец добавляется в конец таблицы. Обратите внимание, ClickHouse не позволяет добавлять столбцы в начало таблицы. Для цепочки действий, `name_after` может быть именем столбца, который добавляется в одном из предыдущих действий. - -Добавление столбца всего лишь меняет структуру таблицы, и не производит никаких действий с данными - соответствующие данные не появляются на диске после ALTER-а. При чтении из таблицы, если для какого-либо столбца отсутствуют данные, то он заполняется значениями по умолчанию (выполняя выражение по умолчанию, если такое есть, или нулями, пустыми строками). Также, столбец появляется на диске при слиянии кусков данных (см. [MergeTree](../../sql-reference/statements/alter.md)). - -Такая схема позволяет добиться мгновенной работы запроса `ALTER` и отсутствия необходимости увеличивать объём старых данных. - -Пример: - -``` sql -ALTER TABLE visits ADD COLUMN browser String AFTER user_id -``` - -#### DROP COLUMN {#alter_drop-column} - -``` sql -DROP COLUMN [IF EXISTS] name -``` - -Удаляет столбец с именем `name`. Если указано `IF EXISTS`, запрос не будет возвращать ошибку, если столбца не существует. - -Запрос удаляет данные из файловой системы. Так как это представляет собой удаление целых файлов, запрос выполняется почти мгновенно. - -Пример: - -``` sql -ALTER TABLE visits DROP COLUMN browser -``` - -#### CLEAR COLUMN {#alter_clear-column} - -``` sql -CLEAR COLUMN [IF EXISTS] name IN PARTITION partition_name -``` - -Сбрасывает все значения в столбце для заданной партиции. Если указано `IF EXISTS`, запрос не будет возвращать ошибку, если столбца не существует. - -Как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -Пример: - -``` sql -ALTER TABLE visits CLEAR COLUMN browser IN PARTITION tuple() -``` - -#### COMMENT COLUMN {#alter_comment-column} - -``` sql -COMMENT COLUMN [IF EXISTS] name 'Text comment' -``` - -Добавляет комментарий к таблице. Если указано `IF EXISTS`, запрос не будет возвращать ошибку, если столбца не существует. - -Каждый столбец может содержать только один комментарий. При выполнении запроса существующий комментарий заменяется на новый. - -Посмотреть комментарии можно в столбце `comment_expression` из запроса [DESCRIBE TABLE](misc.md#misc-describe-table). - -Пример: - -``` sql -ALTER TABLE visits COMMENT COLUMN browser 'Столбец показывает, из каких браузеров пользователи заходили на сайт.' -``` - -#### MODIFY COLUMN {#alter_modify-column} - -``` sql -MODIFY COLUMN [IF EXISTS] name [type] [default_expr] [TTL] -``` - -Запрос изменяет следующие свойства столбца `name`: - -- Тип - -- Значение по умолчанию - -- TTL - - Примеры изменения TTL столбца смотрите в разделе [TTL столбца](../../sql_reference/statements/alter.md#mergetree-column-ttl). - -Если указано `IF EXISTS`, запрос не возвращает ошибку, если столбца не существует. - -При изменении типа, значения преобразуются так, как если бы к ним была применена функция [toType](../../sql-reference/statements/alter.md). Если изменяется только выражение для умолчания, запрос не делает никакой сложной работы и выполняется мгновенно. - -Пример запроса: - -``` sql -ALTER TABLE visits MODIFY COLUMN browser Array(String) -``` - -Изменение типа столбца - это единственное действие, которое выполняет сложную работу - меняет содержимое файлов с данными. Для больших таблиц, выполнение может занять длительное время. - -Выполнение производится в несколько стадий: - -- подготовка временных (новых) файлов с изменёнными данными; -- переименование старых файлов; -- переименование временных (новых) файлов в старые; -- удаление старых файлов. - -Из них, длительной является только первая стадия. Если на этой стадии возникнет сбой, то данные не поменяются. -Если на одной из следующих стадий возникнет сбой, то данные будет можно восстановить вручную. За исключением случаев, когда старые файлы удалены из файловой системы, а данные для новых файлов не доехали на диск и потеряны. - -Запрос `ALTER` на изменение столбцов реплицируется. Соответствующие инструкции сохраняются в ZooKeeper, и затем каждая реплика их применяет. Все запросы `ALTER` выполняются в одном и том же порядке. Запрос ждёт выполнения соответствующих действий на всех репликах. Но при этом, запрос на изменение столбцов в реплицируемой таблице можно прервать, и все действия будут осуществлены асинхронно. - -#### Ограничения запроса ALTER {#ogranicheniia-zaprosa-alter} - -Запрос `ALTER` позволяет создавать и удалять отдельные элементы (столбцы) вложенных структур данных, но не вложенные структуры данных целиком. Для добавления вложенной структуры данных, вы можете добавить столбцы с именем вида `name.nested_name` и типом `Array(T)` - вложенная структура данных полностью эквивалентна нескольким столбцам-массивам с именем, имеющим одинаковый префикс до точки. - -Отсутствует возможность удалять столбцы, входящие в первичный ключ или ключ для сэмплирования (в общем, входящие в выражение `ENGINE`). Изменение типа у столбцов, входящих в первичный ключ возможно только в том случае, если это изменение не приводит к изменению данных (например, разрешено добавление значения в Enum или изменение типа с `DateTime` на `UInt32`). - -Если возможностей запроса `ALTER` не хватает для нужного изменения таблицы, вы можете создать новую таблицу, скопировать туда данные с помощью запроса [INSERT SELECT](insert-into.md#insert_query_insert-select), затем поменять таблицы местами с помощью запроса [RENAME](misc.md#misc_operations-rename), и удалить старую таблицу. В качестве альтернативы для запроса `INSERT SELECT`, можно использовать инструмент [clickhouse-copier](../../sql-reference/statements/alter.md). - -Запрос `ALTER` блокирует все чтения и записи для таблицы. То есть, если на момент запроса `ALTER`, выполнялся долгий `SELECT`, то запрос `ALTER` сначала дождётся его выполнения. И в это время, все новые запросы к той же таблице, будут ждать, пока завершится этот `ALTER`. - -Для таблиц, которые не хранят данные самостоятельно (типа [Merge](../../sql-reference/statements/alter.md) и [Distributed](../../sql-reference/statements/alter.md)), `ALTER` всего лишь меняет структуру таблицы, но не меняет структуру подчинённых таблиц. Для примера, при ALTER-е таблицы типа `Distributed`, вам также потребуется выполнить запрос `ALTER` для таблиц на всех удалённых серверах. - -### Манипуляции с ключевыми выражениями таблиц {#manipuliatsii-s-kliuchevymi-vyrazheniiami-tablits} - -Поддерживается операция: - -``` sql -MODIFY ORDER BY new_expression -``` - -Работает только для таблиц семейства [`MergeTree`](../../sql-reference/statements/alter.md) (в том числе [реплицированных](../../sql-reference/statements/alter.md)). После выполнения запроса -[ключ сортировки](../../sql-reference/statements/alter.md) таблицы -заменяется на `new_expression` (выражение или кортеж выражений). Первичный ключ при этом остаётся прежним. - -Операция затрагивает только метаданные. Чтобы сохранить свойство упорядоченности кусков данных по ключу -сортировки, разрешено добавлять в ключ только новые столбцы (т.е. столбцы, добавляемые командой `ADD COLUMN` -в том же запросе `ALTER`), у которых нет выражения по умолчанию. - -### Манипуляции с индексами {#manipuliatsii-s-indeksami} - -Добавить или удалить индекс можно с помощью операций - -``` sql -ALTER TABLE [db].name ADD INDEX name expression TYPE type GRANULARITY value [AFTER name] -ALTER TABLE [db].name DROP INDEX name -``` - -Поддерживается только таблицами семейства `*MergeTree`. - -Команда `ADD INDEX` добавляет описание индексов в метаданные, а `DROP INDEX` удаляет индекс из метаданных и стирает файлы индекса с диска, поэтому они легковесные и работают мгновенно. - -Если индекс появился в метаданных, то он начнет считаться в последующих слияниях и записях в таблицу, а не сразу после выполнения операции `ALTER`. - -Запрос на изменение индексов реплицируется, сохраняя новые метаданные в ZooKeeper и применяя изменения на всех репликах. - -### Манипуляции с ограничениями (constraints) {#manipuliatsii-s-ogranicheniiami-constraints} - -Про ограничения подробнее написано [тут](create/index.md#constraints). - -Добавить или удалить ограничение можно с помощью запросов - -``` sql -ALTER TABLE [db].name ADD CONSTRAINT constraint_name CHECK expression; -ALTER TABLE [db].name DROP CONSTRAINT constraint_name; -``` - -Запросы выполняют добавление или удаление метаданных об ограничениях таблицы `[db].name`, поэтому выполняются мнгновенно. - -Если ограничение появилось для непустой таблицы, то *проверка ограничения для имеющихся данных не производится*. - -Запрос на изменение ограничений для Replicated таблиц реплицируется, сохраняя новые метаданные в ZooKeeper и применяя изменения на всех репликах. - -### Манипуляции с партициями и кусками {#alter_manipulations-with-partitions} - -Для работы с [партициями](../../sql-reference/statements/alter.md) доступны следующие операции: - -- [DETACH PARTITION](#alter_detach-partition) — перенести партицию в директорию `detached`; -- [DROP PARTITION](#alter_drop-partition) — удалить партицию; -- [ATTACH PARTITION\|PART](#alter_attach-partition) — добавить партицию/кусок в таблицу из директории `detached`; -- [ATTACH PARTITION FROM](#alter_attach-partition-from) — скопировать партицию из другой таблицы; -- [REPLACE PARTITION](#alter_replace-partition) — скопировать партицию из другой таблицы с заменой; -- [MOVE PARTITION TO TABLE](#alter_move_to_table-partition) — переместить партицию в другую таблицу; -- [CLEAR COLUMN IN PARTITION](#alter_clear-column-partition) — удалить все значения в столбце для заданной партиции; -- [CLEAR INDEX IN PARTITION](#alter_clear-index-partition) — очистить построенные вторичные индексы для заданной партиции; -- [FREEZE PARTITION](#alter_freeze-partition) — создать резервную копию партиции; -- [FETCH PARTITION](#alter_fetch-partition) — скачать партицию с другого сервера; -- [MOVE PARTITION\|PART](#alter_move-partition) — переместить партицию/кускок на другой диск или том. - -#### DETACH PARTITION {#alter_detach-partition} - -``` sql -ALTER TABLE table_name DETACH PARTITION partition_expr -``` - -Перемещает заданную партицию в директорию `detached`. Сервер не будет знать об этой партиции до тех пор, пока вы не выполните запрос [ATTACH](#alter_attach-partition). - -Пример: - -``` sql -ALTER TABLE visits DETACH PARTITION 201901 -``` - -Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -После того как запрос будет выполнен, вы сможете производить любые операции с данными в директории `detached`. Например, можно удалить их из файловой системы. - -Запрос реплицируется — данные будут перенесены в директорию `detached` и забыты на всех репликах. Обратите внимание, запрос может быть отправлен только на реплику-лидер. Чтобы узнать, является ли реплика лидером, выполните запрос `SELECT` к системной таблице [system.replicas](../../operations/system-tables/replicas.md#system_tables-replicas). Либо можно выполнить запрос `DETACH` на всех репликах — тогда на всех репликах, кроме реплики-лидера, запрос вернет ошибку. - -#### DROP PARTITION {#alter_drop-partition} - -``` sql -ALTER TABLE table_name DROP PARTITION partition_expr -``` - -Удаляет партицию. Партиция помечается как неактивная и будет полностью удалена примерно через 10 минут. - -Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -Запрос реплицируется — данные будут удалены на всех репликах. - -#### DROP DETACHED PARTITION\|PART {#alter_drop-detached} - -``` sql -ALTER TABLE table_name DROP DETACHED PARTITION|PART partition_expr -``` - -Удаляет из `detached` кусок или все куски, принадлежащие партиции. -Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -#### ATTACH PARTITION\|PART {#alter_attach-partition} - -``` sql -ALTER TABLE table_name ATTACH PARTITION|PART partition_expr -``` - -Добавляет данные в таблицу из директории `detached`. Можно добавить данные как для целой партиции, так и для отдельного куска. Примеры: - -``` sql -ALTER TABLE visits ATTACH PARTITION 201901; -ALTER TABLE visits ATTACH PART 201901_2_2_0; -``` - -Как корректно задать имя партиции или куска, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -Этот запрос реплицируется. Реплика-иницатор проверяет, есть ли данные в директории `detached`. Если данные есть, то запрос проверяет их целостность. В случае успеха данные добавляются в таблицу. Все остальные реплики загружают данные с реплики-инициатора запроса. - -Это означает, что вы можете разместить данные в директории `detached` на одной реплике и с помощью запроса `ALTER ... ATTACH` добавить их в таблицу на всех репликах. - -#### ATTACH PARTITION FROM {#alter_attach-partition-from} - -``` sql -ALTER TABLE table2 ATTACH PARTITION partition_expr FROM table1 -``` - -Копирует партицию из таблицы `table1` в таблицу `table2` и добавляет к существующим данным `table2`. Данные из `table1` не удаляются. - -Следует иметь в виду: - -- Таблицы должны иметь одинаковую структуру. -- Для таблиц должен быть задан одинаковый ключ партиционирования. - -Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -#### REPLACE PARTITION {#alter_replace-partition} - -``` sql -ALTER TABLE table2 REPLACE PARTITION partition_expr FROM table1 -``` - -Копирует партицию из таблицы `table1` в таблицу `table2` с заменой существующих данных в `table2`. Данные из `table1` не удаляются. - -Следует иметь в виду: - -- Таблицы должны иметь одинаковую структуру. -- Для таблиц должен быть задан одинаковый ключ партиционирования. - -Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -#### MOVE PARTITION TO TABLE {#alter_move_to_table-partition} - -``` sql -ALTER TABLE table_source MOVE PARTITION partition_expr TO TABLE table_dest -``` - -Перемещает партицию из таблицы `table_source` в таблицу `table_dest` (добавляет к существующим данным в `table_dest`) с удалением данных из таблицы `table_source`. - -Следует иметь в виду: - -- Таблицы должны иметь одинаковую структуру. -- Для таблиц должен быть задан одинаковый ключ партиционирования. -- Движки таблиц должны быть одинакового семейства (реплицированные или нереплицированные). -- Для таблиц должна быть задана одинаковая политика хранения. - -#### CLEAR COLUMN IN PARTITION {#alter_clear-column-partition} - -``` sql -ALTER TABLE table_name CLEAR COLUMN column_name IN PARTITION partition_expr -``` - -Сбрасывает все значения в столбце для заданной партиции. Если для столбца определено значение по умолчанию (в секции `DEFAULT`), то будет выставлено это значение. - -Пример: - -``` sql -ALTER TABLE visits CLEAR COLUMN hour in PARTITION 201902 -``` - -#### CLEAR INDEX IN PARTITION {#alter_clear-index-partition} - -``` sql -ALTER TABLE table_name CLEAR INDEX index_name IN PARTITION partition_expr -``` - -Работает как `CLEAR COLUMN`, но сбрасывает индексы вместо данных в столбцах. - -#### FREEZE PARTITION {#alter_freeze-partition} - -``` sql -ALTER TABLE table_name FREEZE [PARTITION partition_expr] -``` - -Создаёт резервную копию для заданной партиции. Если выражение `PARTITION` опущено, резервные копии будут созданы для всех партиций. - -!!! note "Примечание" - Создание резервной копии не требует остановки сервера. - -Для таблиц старого стиля имя партиций можно задавать в виде префикса (например, ‘2019’). В этом случае резервные копии будут созданы для всех соответствующих партиций. Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). - -Запрос делает следующее — для текущего состояния таблицы он формирует жесткие ссылки на данные в этой таблице. Ссылки размещаются в директории `/var/lib/clickhouse/shadow/N/...`, где: - -- `/var/lib/clickhouse/` — рабочая директория ClickHouse, заданная в конфигурационном файле; -- `N` — инкрементальный номер резервной копии. - -!!! note "Примечание" - При использовании [нескольких дисков для хранения данных таблицы](../../sql-reference/statements/alter.md#table_engine-mergetree-multiple-volumes) директория `shadow/N` появляется на каждом из дисков, на которых были куски, попавшие под выражение `PARTITION`. - -Структура директорий внутри резервной копии такая же, как внутри `/var/lib/clickhouse/`. Запрос выполнит ‘chmod’ для всех файлов, запрещая запись в них. - -Обратите внимание, запрос `ALTER TABLE t FREEZE PARTITION` не реплицируется. Он создает резервную копию только на локальном сервере. После создания резервной копии данные из `/var/lib/clickhouse/shadow/` можно скопировать на удалённый сервер, а локальную копию удалить. - -Резервная копия создается почти мгновенно (однако сначала запрос дожидается завершения всех запросов, которые выполняются для соответствующей таблицы). - -`ALTER TABLE t FREEZE PARTITION` копирует только данные, но не метаданные таблицы. Чтобы сделать резервную копию метаданных таблицы, скопируйте файл `/var/lib/clickhouse/metadata/database/table.sql` - -Чтобы восстановить данные из резервной копии, выполните следующее: - -1. Создайте таблицу, если она ещё не существует. Запрос на создание можно взять из .sql файла (замените в нём `ATTACH` на `CREATE`). -2. Скопируйте данные из директории `data/database/table/` внутри резервной копии в директорию `/var/lib/clickhouse/data/database/table/detached/`. -3. С помощью запросов `ALTER TABLE t ATTACH PARTITION` добавьте данные в таблицу. - -Восстановление данных из резервной копии не требует остановки сервера. - -Подробнее о резервном копировании и восстановлении данных читайте в разделе [Резервное копирование данных](../../operations/backup.md). - -#### FETCH PARTITION {#alter_fetch-partition} - -``` sql -ALTER TABLE table_name FETCH PARTITION partition_expr FROM 'path-in-zookeeper' -``` - -Загружает партицию с другого сервера. Этот запрос работает только для реплицированных таблиц. - -Запрос выполняет следующее: - -1. Загружает партицию с указанного шарда. Путь к шарду задается в секции `FROM` (‘path-in-zookeeper’). Обратите внимание, нужно задавать путь к шарду в ZooKeeper. -2. Помещает загруженные данные в директорию `detached` таблицы `table_name`. Чтобы прикрепить эти данные к таблице, используйте запрос [ATTACH PARTITION\|PART](#alter_attach-partition). - -Например: - -``` sql -ALTER TABLE users FETCH PARTITION 201902 FROM '/clickhouse/tables/01-01/visits'; -ALTER TABLE users ATTACH PARTITION 201902; -``` - -Следует иметь в виду: - -- Запрос `ALTER TABLE t FETCH PARTITION` не реплицируется. Он загружает партицию в директорию `detached` только на локальном сервере. -- Запрос `ALTER TABLE t ATTACH` реплицируется — он добавляет данные в таблицу сразу на всех репликах. На одной из реплик данные будут добавлены из директории `detached`, а на других — из соседних реплик. - -Перед загрузкой данных система проверяет, существует ли партиция и совпадает ли её структура со структурой таблицы. При этом автоматически выбирается наиболее актуальная реплика среди всех живых реплик. - -Несмотря на то что запрос называется `ALTER TABLE`, он не изменяет структуру таблицы и не изменяет сразу доступные данные в таблице. - -#### MOVE PARTITION\|PART {#alter_move-partition} - -Перемещает партицию или кусок данных на другой том или диск для таблиц с движком `MergeTree`. Смотрите [Хранение данных таблицы на нескольких блочных устройствах](../../sql-reference/statements/alter.md#table_engine-mergetree-multiple-volumes). - -``` sql -ALTER TABLE table_name MOVE PARTITION|PART partition_expr TO DISK|VOLUME 'disk_name' -``` - -Запрос `ALTER TABLE t MOVE`: - -- Не реплицируется, т.к. на разных репликах могут быть различные конфигурации политик хранения. -- Возвращает ошибку, если указан несконфигурированный том или диск. Ошибка также возвращается в случае невыполнения условий перемещения данных, которые указаны в конфигурации политики хранения. -- Может возвращать ошибку в случае, когда перемещаемые данные уже оказались перемещены в результате фонового процесса, конкурентного запроса `ALTER TABLE t MOVE` или как часть результата фоновой операции слияния. В данном случае никаких дополнительных действий от пользователя не требуется. - -Примеры: - -``` sql -ALTER TABLE hits MOVE PART '20190301_14343_16206_438' TO VOLUME 'slow' -ALTER TABLE hits MOVE PARTITION '2019-09-01' TO DISK 'fast_ssd' -``` - -#### Как задавать имя партиции в запросах ALTER {#alter-how-to-specify-part-expr} - -Чтобы задать нужную партицию в запросах `ALTER ... PARTITION`, можно использовать: - -- Имя партиции. Посмотреть имя партиции можно в столбце `partition` системной таблицы [system.parts](../../operations/system-tables/parts.md#system_tables-parts). Например, `ALTER TABLE visits DETACH PARTITION 201901`. -- Произвольное выражение из столбцов исходной таблицы. Также поддерживаются константы и константные выражения. Например, `ALTER TABLE visits DETACH PARTITION toYYYYMM(toDate('2019-01-25'))`. -- Строковый идентификатор партиции. Идентификатор партиции используется для именования кусков партиции на файловой системе и в ZooKeeper. В запросах `ALTER` идентификатор партиции нужно указывать в секции `PARTITION ID`, в одинарных кавычках. Например, `ALTER TABLE visits DETACH PARTITION ID '201901'`. -- Для запросов [ATTACH PART](#alter_attach-partition) и [DROP DETACHED PART](#alter_drop-detached): чтобы задать имя куска партиции, используйте строковой литерал со значением из столбца `name` системной таблицы [system.detached_parts](../../operations/system-tables/detached_parts.md#system_tables-detached_parts). Например, `ALTER TABLE visits ATTACH PART '201901_1_1_0'`. - -Использование кавычек в имени партиций зависит от типа данных столбца, по которому задано партиционирование. Например, для столбца с типом `String` имя партиции необходимо указывать в кавычках (одинарных). Для типов `Date` и `Int*` кавычки указывать не нужно. - -Замечание: для таблиц старого стиля партицию можно указывать и как число `201901`, и как строку `'201901'`. Синтаксис для таблиц нового типа более строг к типам (аналогично парсеру входного формата VALUES). - -Правила, сформулированные выше, актуальны также для запросов [OPTIMIZE](misc.md#misc_operations-optimize). Чтобы указать единственную партицию непартиционированной таблицы, укажите `PARTITION tuple()`. Например: - -``` sql -OPTIMIZE TABLE table_not_partitioned PARTITION tuple() FINAL; -``` - -Примеры запросов `ALTER ... PARTITION` можно посмотреть в тестах: [`00502_custom_partitioning_local`](https://github.com/ClickHouse/ClickHouse/blob/master/tests/queries/0_stateless/00502_custom_partitioning_local.sql) и [`00502_custom_partitioning_replicated_zookeeper`](https://github.com/ClickHouse/ClickHouse/blob/master/tests/queries/0_stateless/00502_custom_partitioning_replicated_zookeeper.sql). - -### Манипуляции с TTL таблицы {#manipuliatsii-s-ttl-tablitsy} - -Вы можете изменить [TTL для таблицы](../../sql-reference/statements/alter.md#mergetree-table-ttl) запросом следующего вида: - -``` sql -ALTER TABLE table-name MODIFY TTL ttl-expression -``` - -### Мутации {#mutations} - -Мутации - разновидность запроса ALTER, позволяющая изменять или удалять данные в таблице. В отличие от стандартных запросов `DELETE` и `UPDATE`, рассчитанных на точечное изменение данных, область применения мутаций - достаточно тяжёлые изменения, затрагивающие много строк в таблице. Поддержана для движков таблиц семейства `MergeTree`, в том числе для движков с репликацией. - -Конвертировать существующие таблицы для работы с мутациями не нужно. Но после применения первой мутации формат данных таблицы становится несовместимым с предыдущими версиями и откатиться на предыдущую версию уже не получится. - -На данный момент доступны команды: - -``` sql -ALTER TABLE [db.]table DELETE WHERE filter_expr -``` - -Выражение `filter_expr` должно иметь тип `UInt8`. Запрос удаляет строки таблицы, для которых это выражение принимает ненулевое значение. - -``` sql -ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr -``` - -Выражение `filter_expr` должно иметь тип `UInt8`. Запрос изменяет значение указанных столбцов на вычисленное значение соответствующих выражений в каждой строке, для которой `filter_expr` принимает ненулевое значение. Вычисленные значения преобразуются к типу столбца с помощью оператора `CAST`. Изменение столбцов, которые используются при вычислении первичного ключа или ключа партиционирования, не поддерживается. - -``` sql -ALTER TABLE [db.]table MATERIALIZE INDEX name IN PARTITION partition_name -``` - -Команда перестроит вторичный индекс `name` для партиции `partition_name`. - -В одном запросе можно указать несколько команд через запятую. - -Для \*MergeTree-таблиц мутации выполняются, перезаписывая данные по кускам (parts). При этом атомарности нет — куски заменяются на помутированные по мере выполнения и запрос `SELECT`, заданный во время выполнения мутации, увидит данные как из измененных кусков, так и из кусков, которые еще не были изменены. - -Мутации линейно упорядочены между собой и накладываются на каждый кусок в порядке добавления. Мутации также упорядочены со вставками - гарантируется, что данные, вставленные в таблицу до начала выполнения запроса мутации, будут изменены, а данные, вставленные после окончания запроса мутации, изменены не будут. При этом мутации никак не блокируют вставки. - -Запрос завершается немедленно после добавления информации о мутации (для реплицированных таблиц - в ZooKeeper, для нереплицированных - на файловую систему). Сама мутация выполняется асинхронно, используя настройки системного профиля. Следить за ходом её выполнения можно по таблице [`system.mutations`](../../operations/system-tables/mutations.md#system_tables-mutations). Добавленные мутации будут выполняться до конца даже в случае перезапуска серверов ClickHouse. Откатить мутацию после её добавления нельзя, но если мутация по какой-то причине не может выполниться до конца, её можно остановить с помощью запроса [`KILL MUTATION`](../../sql-reference/statements/kill.md#kill-mutation). - -Записи о последних выполненных мутациях удаляются не сразу (количество сохраняемых мутаций определяется параметром движка таблиц `finished_mutations_to_keep`). Более старые записи удаляются. - -### Синхронность запросов ALTER {#synchronicity-of-alter-queries} - -Для нереплицируемых таблиц, все запросы `ALTER` выполняются синхронно. Для реплицируемых таблиц, запрос всего лишь добавляет инструкцию по соответствующим действиям в `ZooKeeper`, а сами действия осуществляются при первой возможности. Но при этом, запрос может ждать завершения выполнения этих действий на всех репликах. - -Для запросов `ALTER ... ATTACH|DETACH|DROP` можно настроить ожидание, с помощью настройки `replication_alter_partitions_sync`. -Возможные значения: `0` - не ждать, `1` - ждать выполнения только у себя (по умолчанию), `2` - ждать всех. - -Для запросов `ALTER TABLE ... UPDATE|DELETE` синхронность выполнения определяется настройкой [mutations_sync](../../operations/settings/settings.md#mutations_sync). - -## ALTER USER {#alter-user-statement} - -Изменяет аккаунт пользователя ClickHouse. - -### Синтаксис {#alter-user-syntax} - -``` sql -ALTER USER [IF EXISTS] name [ON CLUSTER cluster_name] - [RENAME TO new_name] - [IDENTIFIED [WITH {PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD}] BY {'password'|'hash'}] - [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE] - [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ] - [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] -``` - -### Описание {#alter-user-dscr} - -Для выполнения `ALTER USER` необходима привилегия [ALTER USER](grant.md#grant-access-management). - -### Примеры {#alter-user-examples} - -Установить ролями по умолчанию роли, назначенные пользователю: - -``` sql -ALTER USER user DEFAULT ROLE role1, role2 -``` - -Если роли не были назначены пользователю, ClickHouse выбрасывает исключение. - -Установить ролями по умолчанию все роли, назначенные пользователю: - -``` sql -ALTER USER user DEFAULT ROLE ALL -``` - -Если роль будет впоследствии назначена пользователю, она автоматически станет ролью по умолчанию. - -Установить ролями по умолчанию все назначенные пользователю роли кроме `role1` и `role2`: - -``` sql -ALTER USER user DEFAULT ROLE ALL EXCEPT role1, role2 -``` - - -## ALTER ROLE {#alter-role-statement} - -Изменяет роль. - -### Синтаксис {#alter-role-syntax} - -``` sql -ALTER ROLE [IF EXISTS] name [ON CLUSTER cluster_name] - [RENAME TO new_name] - [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] -``` - - -## ALTER ROW POLICY {#alter-row-policy-statement} - -Изменяет политику доступа к строкам. - -### Синтаксис {#alter-row-policy-syntax} - -``` sql -ALTER [ROW] POLICY [IF EXISTS] name [ON CLUSTER cluster_name] ON [database.]table - [RENAME TO new_name] - [AS {PERMISSIVE | RESTRICTIVE}] - [FOR SELECT] - [USING {condition | NONE}][,...] - [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] -``` - - -## ALTER QUOTA {#alter-quota-statement} - -Изменяет квоту. - -### Синтаксис {#alter-quota-syntax} - -``` sql -ALTER QUOTA [IF EXISTS] name [ON CLUSTER cluster_name] - [RENAME TO new_name] - [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}] - [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR} - {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] | - NO LIMITS | TRACKING ONLY} [,...]] - [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] -``` - - -## ALTER SETTINGS PROFILE {#alter-settings-profile-statement} - -Изменяет профили настроек. - -### Синтаксис {#alter-settings-profile-syntax} - -``` sql -ALTER SETTINGS PROFILE [IF EXISTS] name [ON CLUSTER cluster_name] - [RENAME TO new_name] - [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...] -``` - - - -[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/) diff --git a/docs/ru/sql-reference/statements/alter/column.md b/docs/ru/sql-reference/statements/alter/column.md new file mode 100644 index 00000000000..811539d60d3 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/column.md @@ -0,0 +1,140 @@ +--- +toc_priority: 37 +toc_title: COLUMN +--- + +# Манипуляции со столбцами {#manipuliatsii-so-stolbtsami} + +Существуют следующие действия: + +- [ADD COLUMN](#alter_add-column) — добавляет столбец в таблицу; +- [DROP COLUMN](#alter_drop-column) — удаляет столбец; +- [CLEAR COLUMN](#alter_clear-column) — сбрасывает все значения в столбце для заданной партиции; +- [COMMENT COLUMN](#alter_comment-column) — добавляет комментарий к столбцу; +- [MODIFY COLUMN](#alter_modify-column) — изменяет тип столбца, выражение для значения по умолчанию и TTL. + +Подробное описание для каждого действия приведено ниже. + +## ADD COLUMN {#alter_add-column} + +``` sql +ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [codec] [AFTER name_after] +``` + +Добавляет в таблицу новый столбец с именем `name`, типом `type`, [кодеком](../create/table.md#codecs) `codec` и выражением для умолчания `default_expr` (смотрите раздел [Значения по умолчанию](../create/index.md#create-default-values)). + +Если указано `IF NOT EXISTS`, запрос не будет возвращать ошибку, если столбец уже существует. Если указано `AFTER name_after` (имя другого столбца), то столбец добавляется (в список столбцов таблицы) после указанного. Иначе, столбец добавляется в конец таблицы. Обратите внимание, ClickHouse не позволяет добавлять столбцы в начало таблицы. Для цепочки действий, `name_after` может быть именем столбца, который добавляется в одном из предыдущих действий. + +Добавление столбца всего лишь меняет структуру таблицы, и не производит никаких действий с данными - соответствующие данные не появляются на диске после ALTER-а. При чтении из таблицы, если для какого-либо столбца отсутствуют данные, то он заполняется значениями по умолчанию (выполняя выражение по умолчанию, если такое есть, или нулями, пустыми строками). Также, столбец появляется на диске при слиянии кусков данных (см. [MergeTree](../../../sql-reference/statements/alter/index.md)). + +Такая схема позволяет добиться мгновенной работы запроса `ALTER` и отсутствия необходимости увеличивать объём старых данных. + +Пример: + +``` sql +ALTER TABLE visits ADD COLUMN browser String AFTER user_id +``` + +## DROP COLUMN {#alter_drop-column} + +``` sql +DROP COLUMN [IF EXISTS] name +``` + +Удаляет столбец с именем `name`. Если указано `IF EXISTS`, запрос не будет возвращать ошибку, если столбца не существует. + +Запрос удаляет данные из файловой системы. Так как это представляет собой удаление целых файлов, запрос выполняется почти мгновенно. + +Пример: + +``` sql +ALTER TABLE visits DROP COLUMN browser +``` + +## CLEAR COLUMN {#alter_clear-column} + +``` sql +CLEAR COLUMN [IF EXISTS] name IN PARTITION partition_name +``` + +Сбрасывает все значения в столбце для заданной партиции. Если указано `IF EXISTS`, запрос не будет возвращать ошибку, если столбца не существует. + +Как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +Пример: + +``` sql +ALTER TABLE visits CLEAR COLUMN browser IN PARTITION tuple() +``` + +## COMMENT COLUMN {#alter_comment-column} + +``` sql +COMMENT COLUMN [IF EXISTS] name 'Text comment' +``` + +Добавляет комментарий к таблице. Если указано `IF EXISTS`, запрос не будет возвращать ошибку, если столбца не существует. + +Каждый столбец может содержать только один комментарий. При выполнении запроса существующий комментарий заменяется на новый. + +Посмотреть комментарии можно в столбце `comment_expression` из запроса [DESCRIBE TABLE](../misc.md#misc-describe-table). + +Пример: + +``` sql +ALTER TABLE visits COMMENT COLUMN browser 'Столбец показывает, из каких браузеров пользователи заходили на сайт.' +``` + +## MODIFY COLUMN {#alter_modify-column} + +``` sql +MODIFY COLUMN [IF EXISTS] name [type] [default_expr] [TTL] +``` + +Запрос изменяет следующие свойства столбца `name`: + +- Тип + +- Значение по умолчанию + +- TTL + + Примеры изменения TTL столбца смотрите в разделе [TTL столбца](ttl.md#mergetree-column-ttl). + +Если указано `IF EXISTS`, запрос не возвращает ошибку, если столбца не существует. + +При изменении типа, значения преобразуются так, как если бы к ним была применена функция [toType](../../../sql-reference/statements/alter/index.md). Если изменяется только выражение для умолчания, запрос не делает никакой сложной работы и выполняется мгновенно. + +Пример запроса: + +``` sql +ALTER TABLE visits MODIFY COLUMN browser Array(String) +``` + +Изменение типа столбца - это единственное действие, которое выполняет сложную работу - меняет содержимое файлов с данными. Для больших таблиц, выполнение может занять длительное время. + +Выполнение производится в несколько стадий: + +- подготовка временных (новых) файлов с изменёнными данными; +- переименование старых файлов; +- переименование временных (новых) файлов в старые; +- удаление старых файлов. + +Из них, длительной является только первая стадия. Если на этой стадии возникнет сбой, то данные не поменяются. +Если на одной из следующих стадий возникнет сбой, то данные будет можно восстановить вручную. За исключением случаев, когда старые файлы удалены из файловой системы, а данные для новых файлов не доехали на диск и потеряны. + +Запрос `ALTER` на изменение столбцов реплицируется. Соответствующие инструкции сохраняются в ZooKeeper, и затем каждая реплика их применяет. Все запросы `ALTER` выполняются в одном и том же порядке. Запрос ждёт выполнения соответствующих действий на всех репликах. Но при этом, запрос на изменение столбцов в реплицируемой таблице можно прервать, и все действия будут осуществлены асинхронно. + +## Ограничения запроса ALTER {#ogranicheniia-zaprosa-alter} + +Запрос `ALTER` позволяет создавать и удалять отдельные элементы (столбцы) вложенных структур данных, но не вложенные структуры данных целиком. Для добавления вложенной структуры данных, вы можете добавить столбцы с именем вида `name.nested_name` и типом `Array(T)` - вложенная структура данных полностью эквивалентна нескольким столбцам-массивам с именем, имеющим одинаковый префикс до точки. + +Отсутствует возможность удалять столбцы, входящие в первичный ключ или ключ для сэмплирования (в общем, входящие в выражение `ENGINE`). Изменение типа у столбцов, входящих в первичный ключ возможно только в том случае, если это изменение не приводит к изменению данных (например, разрешено добавление значения в Enum или изменение типа с `DateTime` на `UInt32`). + +Если возможностей запроса `ALTER` не хватает для нужного изменения таблицы, вы можете создать новую таблицу, скопировать туда данные с помощью запроса [INSERT SELECT](../insert-into.md#insert_query_insert-select), затем поменять таблицы местами с помощью запроса [RENAME](../misc.md#misc_operations-rename), и удалить старую таблицу. В качестве альтернативы для запроса `INSERT SELECT`, можно использовать инструмент [clickhouse-copier](../../../sql-reference/statements/alter/index.md). + +Запрос `ALTER` блокирует все чтения и записи для таблицы. То есть, если на момент запроса `ALTER`, выполнялся долгий `SELECT`, то запрос `ALTER` сначала дождётся его выполнения. И в это время, все новые запросы к той же таблице, будут ждать, пока завершится этот `ALTER`. + +Для таблиц, которые не хранят данные самостоятельно (типа [Merge](../../../sql-reference/statements/alter/index.md) и [Distributed](../../../sql-reference/statements/alter/index.md)), `ALTER` всего лишь меняет структуру таблицы, но не меняет структуру подчинённых таблиц. Для примера, при ALTER-е таблицы типа `Distributed`, вам также потребуется выполнить запрос `ALTER` для таблиц на всех удалённых серверах. + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/column/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/constraint.md b/docs/ru/sql-reference/statements/alter/constraint.md new file mode 100644 index 00000000000..bacdff9ff57 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/constraint.md @@ -0,0 +1,23 @@ +--- +toc_priority: 43 +toc_title: CONSTRAINT +--- + +# Манипуляции с ограничениями (constraints) {#manipuliatsii-s-ogranicheniiami-constraints} + +Про ограничения подробнее написано [тут](../create/table.md#constraints). + +Добавить или удалить ограничение можно с помощью запросов + +``` sql +ALTER TABLE [db].name ADD CONSTRAINT constraint_name CHECK expression; +ALTER TABLE [db].name DROP CONSTRAINT constraint_name; +``` + +Запросы выполняют добавление или удаление метаданных об ограничениях таблицы `[db].name`, поэтому выполняются мгновенно. + +Если ограничение появилось для непустой таблицы, то *проверка ограничения для имеющихся данных не производится*. + +Запрос на изменение ограничений для Replicated таблиц реплицируется, сохраняя новые метаданные в ZooKeeper и применяя изменения на всех репликах. + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/constraint/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/delete.md b/docs/ru/sql-reference/statements/alter/delete.md new file mode 100644 index 00000000000..29e1ae564d2 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/delete.md @@ -0,0 +1,29 @@ +--- +toc_priority: 39 +toc_title: DELETE +--- + +# ALTER TABLE … DELETE {#alter-mutations} + +``` sql +ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE WHERE filter_expr +``` + +Позволяет удалить данные, соответствующие указанному выражению фильтрации. Реализовано как [мутация](../../../sql-reference/statements/alter/index.md#mutations). + +!!! note "Note" + Префикс `ALTER TABLE` делает этот синтаксис отличным от большинства других систем, поддерживающих SQL. Он предназначен для обозначения того, что в отличие от аналогичных запросов в базах данных OLTP это тяжелая операция, не предназначенная для частого использования. + +Выражение `filter_expr` должно иметь тип `UInt8`. Запрос удаляет строки в таблице, для которых это выражение принимает ненулевое значение. + +Один запрос может содержать несколько команд, разделенных запятыми. + +Синхронность обработки запроса определяется параметром [mutations_sync](../../../operations/settings/settings.md#mutations_sync). По умолчанию он является асинхронным. + +**Смотрите также** + +- [Мутации](../../../sql-reference/statements/alter/index.md#mutations) +- [Синхронность запросов ALTER](../../../sql-reference/statements/alter/index.md#synchronicity-of-alter-queries) +- [mutations_sync](../../../operations/settings/settings.md#mutations_sync) setting + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/delete/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/index.md b/docs/ru/sql-reference/statements/alter/index.md new file mode 100644 index 00000000000..035be934eb4 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/index.md @@ -0,0 +1,72 @@ +--- +toc_priority: 36 +toc_title: ALTER +--- + +## ALTER {#query_language_queries_alter} + +Изменение структуры таблицы. + +``` sql +ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ... +``` + +В запросе указывается список из одного или более действий через запятую. +Каждое действие — операция над столбцом. + +Большинство запросов `ALTER` изменяют настройки таблицы или данные: + +- [COLUMN](../../../sql-reference/statements/alter/column.md) +- [PARTITION](../../../sql-reference/statements/alter/partition.md) +- [DELETE](../../../sql-reference/statements/alter/delete.md) +- [UPDATE](../../../sql-reference/statements/alter/update.md) +- [ORDER BY](../../../sql-reference/statements/alter/order-by.md) +- [INDEX](../../../sql-reference/statements/alter/index/index.md) +- [CONSTRAINT](../../../sql-reference/statements/alter/constraint.md) +- [TTL](../../../sql-reference/statements/alter/ttl.md) + +!!! note "Note" + Запрос `ALTER` поддерживается только для таблиц типа `*MergeTree`, а также `Merge` и `Distributed`. Запрос имеет несколько вариантов. + +Следующие запросы `ALTER` изменяют сущности, связанные с управлением доступом на основе ролей: + +- [USER](../../../sql-reference/statements/alter/user.md) +- [ROLE](../../../sql-reference/statements/alter/role.md) +- [QUOTA](../../../sql-reference/statements/alter/quota.md) +- [ROW POLICY](../../../sql-reference/statements/alter/row-policy.md) +- [SETTINGS PROFILE](../../../sql-reference/statements/alter/settings-profile.md) + +### Мутации {#mutations} + +Мутации - разновидность запроса ALTER, позволяющая изменять или удалять данные в таблице. В отличие от стандартных запросов [ALTER TABLE … DELETE](../../../sql-reference/statements/alter/delete.md) и [ALTER TABLE … UPDATE](../../../sql-reference/statements/alter/update.md), рассчитанных на точечное изменение данных, область применения мутаций - достаточно тяжёлые изменения, затрагивающие много строк в таблице. Поддержана для движков таблиц семейства [MergeTree](../../../engines/table-engines/mergetree-family/mergetree.md), в том числе для движков с репликацией. + +Конвертировать существующие таблицы для работы с мутациями не нужно. Но после применения первой мутации формат данных таблицы становится несовместимым с предыдущими версиями и откатиться на предыдущую версию уже не получится. + +На данный момент доступны команды: + +``` sql +ALTER TABLE [db.]table MATERIALIZE INDEX name IN PARTITION partition_name +``` + +Команда перестроит вторичный индекс `name` для партиции `partition_name`. + +В одном запросе можно указать несколько команд через запятую. + +Для `*MergeTree`-таблиц мутации выполняются, перезаписывая данные по кускам (parts). При этом атомарности нет — куски заменяются на помутированные по мере выполнения и запрос `SELECT`, заданный во время выполнения мутации, увидит данные как из измененных кусков, так и из кусков, которые еще не были изменены. + +Мутации линейно упорядочены между собой и накладываются на каждый кусок в порядке добавления. Мутации также упорядочены со вставками - гарантируется, что данные, вставленные в таблицу до начала выполнения запроса мутации, будут изменены, а данные, вставленные после окончания запроса мутации, изменены не будут. При этом мутации никак не блокируют вставки. + +Запрос завершается немедленно после добавления информации о мутации (для реплицированных таблиц - в ZooKeeper, для нереплицированных - на файловую систему). Сама мутация выполняется асинхронно, используя настройки системного профиля. Следить за ходом её выполнения можно по таблице [`system.mutations`](../../../operations/system-tables/mutations.md#system_tables-mutations). Добавленные мутации будут выполняться до конца даже в случае перезапуска серверов ClickHouse. Откатить мутацию после её добавления нельзя, но если мутация по какой-то причине не может выполниться до конца, её можно остановить с помощью запроса [`KILL MUTATION`](../../../sql-reference/statements/kill.md#kill-mutation). + +Записи о последних выполненных мутациях удаляются не сразу (количество сохраняемых мутаций определяется параметром движка таблиц `finished_mutations_to_keep`). Более старые записи удаляются. + +### Синхронность запросов ALTER {#synchronicity-of-alter-queries} + +Для нереплицируемых таблиц, все запросы `ALTER` выполняются синхронно. Для реплицируемых таблиц, запрос всего лишь добавляет инструкцию по соответствующим действиям в `ZooKeeper`, а сами действия осуществляются при первой возможности. Но при этом, запрос может ждать завершения выполнения этих действий на всех репликах. + +Для запросов `ALTER ... ATTACH|DETACH|DROP` можно настроить ожидание, с помощью настройки `replication_alter_partitions_sync`. +Возможные значения: `0` - не ждать, `1` - ждать выполнения только у себя (по умолчанию), `2` - ждать всех. + +Для запросов `ALTER TABLE ... UPDATE|DELETE` синхронность выполнения определяется настройкой [mutations_sync](../../../operations/settings/settings.md#mutations_sync). + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/index/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/index/index.md b/docs/ru/sql-reference/statements/alter/index/index.md new file mode 100644 index 00000000000..863f8b875dd --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/index/index.md @@ -0,0 +1,24 @@ +--- +toc_hidden_folder: true +toc_priority: 42 +toc_title: INDEX +--- + +# Манипуляции с индексами {#manipuliatsii-s-indeksami} + +Добавить или удалить индекс можно с помощью операций + +``` sql +ALTER TABLE [db].name ADD INDEX name expression TYPE type GRANULARITY value [AFTER name] +ALTER TABLE [db].name DROP INDEX name +``` + +Поддерживается только таблицами семейства `*MergeTree`. + +Команда `ADD INDEX` добавляет описание индексов в метаданные, а `DROP INDEX` удаляет индекс из метаданных и стирает файлы индекса с диска, поэтому они легковесные и работают мгновенно. + +Если индекс появился в метаданных, то он начнет считаться в последующих слияниях и записях в таблицу, а не сразу после выполнения операции `ALTER`. + +Запрос на изменение индексов реплицируется, сохраняя новые метаданные в ZooKeeper и применяя изменения на всех репликах. + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/index/index/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/order-by.md b/docs/ru/sql-reference/statements/alter/order-by.md new file mode 100644 index 00000000000..32c0e382445 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/order-by.md @@ -0,0 +1,22 @@ +--- +toc_priority: 41 +toc_title: ORDER BY +--- + +# Манипуляции с ключевыми выражениями таблиц {#manipuliatsii-s-kliuchevymi-vyrazheniiami-tablits} + +Поддерживается операция: + +``` sql +MODIFY ORDER BY new_expression +``` + +Работает только для таблиц семейства [`MergeTree`](../../../sql-reference/statements/alter/index.md) (в том числе [реплицированных](../../../sql-reference/statements/alter/index.md)). После выполнения запроса +[ключ сортировки](../../../sql-reference/statements/alter/index.md) таблицы +заменяется на `new_expression` (выражение или кортеж выражений). Первичный ключ при этом остаётся прежним. + +Операция затрагивает только метаданные. Чтобы сохранить свойство упорядоченности кусков данных по ключу +сортировки, разрешено добавлять в ключ только новые столбцы (т.е. столбцы, добавляемые командой `ADD COLUMN` +в том же запросе `ALTER`), у которых нет выражения по умолчанию. + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/order-by/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/partition.md b/docs/ru/sql-reference/statements/alter/partition.md new file mode 100644 index 00000000000..5c4a23428ad --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/partition.md @@ -0,0 +1,259 @@ +--- +toc_priority: 38 +toc_title: PARTITION +--- + +# Манипуляции с партициями и кусками {#alter_manipulations-with-partitions} + +Для работы с [партициями](../../../engines/table-engines/mergetree-family/custom-partitioning-key.md) доступны следующие операции: + +- [DETACH PARTITION](#alter_detach-partition) — перенести партицию в директорию `detached`; +- [DROP PARTITION](#alter_drop-partition) — удалить партицию; +- [ATTACH PARTITION\|PART](#alter_attach-partition) — добавить партицию/кусок в таблицу из директории `detached`; +- [ATTACH PARTITION FROM](#alter_attach-partition-from) — скопировать партицию из другой таблицы; +- [REPLACE PARTITION](#alter_replace-partition) — скопировать партицию из другой таблицы с заменой; +- [MOVE PARTITION TO TABLE](#alter_move_to_table-partition) — переместить партицию в другую таблицу; +- [CLEAR COLUMN IN PARTITION](#alter_clear-column-partition) — удалить все значения в столбце для заданной партиции; +- [CLEAR INDEX IN PARTITION](#alter_clear-index-partition) — очистить построенные вторичные индексы для заданной партиции; +- [FREEZE PARTITION](#alter_freeze-partition) — создать резервную копию партиции; +- [FETCH PARTITION](#alter_fetch-partition) — скачать партицию с другого сервера; +- [MOVE PARTITION\|PART](#alter_move-partition) — переместить партицию/кускок на другой диск или том. + +## DETACH PARTITION {#alter_detach-partition} + +``` sql +ALTER TABLE table_name DETACH PARTITION partition_expr +``` + +Перемещает заданную партицию в директорию `detached`. Сервер не будет знать об этой партиции до тех пор, пока вы не выполните запрос [ATTACH](#alter_attach-partition). + +Пример: + +``` sql +ALTER TABLE visits DETACH PARTITION 201901 +``` + +Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +После того как запрос будет выполнен, вы сможете производить любые операции с данными в директории `detached`. Например, можно удалить их из файловой системы. + +Запрос реплицируется — данные будут перенесены в директорию `detached` и забыты на всех репликах. Обратите внимание, запрос может быть отправлен только на реплику-лидер. Чтобы узнать, является ли реплика лидером, выполните запрос `SELECT` к системной таблице [system.replicas](../../../operations/system-tables/replicas.md#system_tables-replicas). Либо можно выполнить запрос `DETACH` на всех репликах — тогда на всех репликах, кроме реплики-лидера, запрос вернет ошибку. + +## DROP PARTITION {#alter_drop-partition} + +``` sql +ALTER TABLE table_name DROP PARTITION partition_expr +``` + +Удаляет партицию. Партиция помечается как неактивная и будет полностью удалена примерно через 10 минут. + +Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +Запрос реплицируется — данные будут удалены на всех репликах. + +## DROP DETACHED PARTITION\|PART {#alter_drop-detached} + +``` sql +ALTER TABLE table_name DROP DETACHED PARTITION|PART partition_expr +``` + +Удаляет из `detached` кусок или все куски, принадлежащие партиции. +Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +## ATTACH PARTITION\|PART {#alter_attach-partition} + +``` sql +ALTER TABLE table_name ATTACH PARTITION|PART partition_expr +``` + +Добавляет данные в таблицу из директории `detached`. Можно добавить данные как для целой партиции, так и для отдельного куска. Примеры: + +``` sql +ALTER TABLE visits ATTACH PARTITION 201901; +ALTER TABLE visits ATTACH PART 201901_2_2_0; +``` + +Как корректно задать имя партиции или куска, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +Этот запрос реплицируется. Реплика-иницатор проверяет, есть ли данные в директории `detached`. Если данные есть, то запрос проверяет их целостность. В случае успеха данные добавляются в таблицу. Все остальные реплики загружают данные с реплики-инициатора запроса. + +Это означает, что вы можете разместить данные в директории `detached` на одной реплике и с помощью запроса `ALTER ... ATTACH` добавить их в таблицу на всех репликах. + +## ATTACH PARTITION FROM {#alter_attach-partition-from} + +``` sql +ALTER TABLE table2 ATTACH PARTITION partition_expr FROM table1 +``` + +Копирует партицию из таблицы `table1` в таблицу `table2` и добавляет к существующим данным `table2`. Данные из `table1` не удаляются. + +Следует иметь в виду: + +- Таблицы должны иметь одинаковую структуру. +- Для таблиц должен быть задан одинаковый ключ партиционирования. + +Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +## REPLACE PARTITION {#alter_replace-partition} + +``` sql +ALTER TABLE table2 REPLACE PARTITION partition_expr FROM table1 +``` + +Копирует партицию из таблицы `table1` в таблицу `table2` с заменой существующих данных в `table2`. Данные из `table1` не удаляются. + +Следует иметь в виду: + +- Таблицы должны иметь одинаковую структуру. +- Для таблиц должен быть задан одинаковый ключ партиционирования. + +Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +## MOVE PARTITION TO TABLE {#alter_move_to_table-partition} + +``` sql +ALTER TABLE table_source MOVE PARTITION partition_expr TO TABLE table_dest +``` + +Перемещает партицию из таблицы `table_source` в таблицу `table_dest` (добавляет к существующим данным в `table_dest`) с удалением данных из таблицы `table_source`. + +Следует иметь в виду: + +- Таблицы должны иметь одинаковую структуру. +- Для таблиц должен быть задан одинаковый ключ партиционирования. +- Движки таблиц должны быть одинакового семейства (реплицированные или нереплицированные). +- Для таблиц должна быть задана одинаковая политика хранения. + +## CLEAR COLUMN IN PARTITION {#alter_clear-column-partition} + +``` sql +ALTER TABLE table_name CLEAR COLUMN column_name IN PARTITION partition_expr +``` + +Сбрасывает все значения в столбце для заданной партиции. Если для столбца определено значение по умолчанию (в секции `DEFAULT`), то будет выставлено это значение. + +Пример: + +``` sql +ALTER TABLE visits CLEAR COLUMN hour in PARTITION 201902 +``` + +## CLEAR INDEX IN PARTITION {#alter_clear-index-partition} + +``` sql +ALTER TABLE table_name CLEAR INDEX index_name IN PARTITION partition_expr +``` + +Работает как `CLEAR COLUMN`, но сбрасывает индексы вместо данных в столбцах. + +## FREEZE PARTITION {#alter_freeze-partition} + +``` sql +ALTER TABLE table_name FREEZE [PARTITION partition_expr] +``` + +Создаёт резервную копию для заданной партиции. Если выражение `PARTITION` опущено, резервные копии будут созданы для всех партиций. + +!!! note "Примечание" + Создание резервной копии не требует остановки сервера. + +Для таблиц старого стиля имя партиций можно задавать в виде префикса (например, ‘2019’). В этом случае резервные копии будут созданы для всех соответствующих партиций. Подробнее о том, как корректно задать имя партиции, см. в разделе [Как задавать имя партиции в запросах ALTER](#alter-how-to-specify-part-expr). + +Запрос делает следующее — для текущего состояния таблицы он формирует жесткие ссылки на данные в этой таблице. Ссылки размещаются в директории `/var/lib/clickhouse/shadow/N/...`, где: + +- `/var/lib/clickhouse/` — рабочая директория ClickHouse, заданная в конфигурационном файле; +- `N` — инкрементальный номер резервной копии. + +!!! note "Примечание" + При использовании [нескольких дисков для хранения данных таблицы](../../statements/alter/index.md#table_engine-mergetree-multiple-volumes) директория `shadow/N` появляется на каждом из дисков, на которых были куски, попавшие под выражение `PARTITION`. + +Структура директорий внутри резервной копии такая же, как внутри `/var/lib/clickhouse/`. Запрос выполнит ‘chmod’ для всех файлов, запрещая запись в них. + +Обратите внимание, запрос `ALTER TABLE t FREEZE PARTITION` не реплицируется. Он создает резервную копию только на локальном сервере. После создания резервной копии данные из `/var/lib/clickhouse/shadow/` можно скопировать на удалённый сервер, а локальную копию удалить. + +Резервная копия создается почти мгновенно (однако сначала запрос дожидается завершения всех запросов, которые выполняются для соответствующей таблицы). + +`ALTER TABLE t FREEZE PARTITION` копирует только данные, но не метаданные таблицы. Чтобы сделать резервную копию метаданных таблицы, скопируйте файл `/var/lib/clickhouse/metadata/database/table.sql` + +Чтобы восстановить данные из резервной копии, выполните следующее: + +1. Создайте таблицу, если она ещё не существует. Запрос на создание можно взять из .sql файла (замените в нём `ATTACH` на `CREATE`). +2. Скопируйте данные из директории `data/database/table/` внутри резервной копии в директорию `/var/lib/clickhouse/data/database/table/detached/`. +3. С помощью запросов `ALTER TABLE t ATTACH PARTITION` добавьте данные в таблицу. + +Восстановление данных из резервной копии не требует остановки сервера. + +Подробнее о резервном копировании и восстановлении данных читайте в разделе [Резервное копирование данных](../../../operations/backup.md). + +## FETCH PARTITION {#alter_fetch-partition} + +``` sql +ALTER TABLE table_name FETCH PARTITION partition_expr FROM 'path-in-zookeeper' +``` + +Загружает партицию с другого сервера. Этот запрос работает только для реплицированных таблиц. + +Запрос выполняет следующее: + +1. Загружает партицию с указанного шарда. Путь к шарду задается в секции `FROM` (‘path-in-zookeeper’). Обратите внимание, нужно задавать путь к шарду в ZooKeeper. +2. Помещает загруженные данные в директорию `detached` таблицы `table_name`. Чтобы прикрепить эти данные к таблице, используйте запрос [ATTACH PARTITION\|PART](#alter_attach-partition). + +Например: + +``` sql +ALTER TABLE users FETCH PARTITION 201902 FROM '/clickhouse/tables/01-01/visits'; +ALTER TABLE users ATTACH PARTITION 201902; +``` + +Следует иметь в виду: + +- Запрос `ALTER TABLE t FETCH PARTITION` не реплицируется. Он загружает партицию в директорию `detached` только на локальном сервере. +- Запрос `ALTER TABLE t ATTACH` реплицируется — он добавляет данные в таблицу сразу на всех репликах. На одной из реплик данные будут добавлены из директории `detached`, а на других — из соседних реплик. + +Перед загрузкой данных система проверяет, существует ли партиция и совпадает ли её структура со структурой таблицы. При этом автоматически выбирается наиболее актуальная реплика среди всех живых реплик. + +Несмотря на то что запрос называется `ALTER TABLE`, он не изменяет структуру таблицы и не изменяет сразу доступные данные в таблице. + +## MOVE PARTITION\|PART {#alter_move-partition} + +Перемещает партицию или кусок данных на другой том или диск для таблиц с движком `MergeTree`. Смотрите [Хранение данных таблицы на нескольких блочных устройствах](../../statements/alter/index.md#table_engine-mergetree-multiple-volumes). + +``` sql +ALTER TABLE table_name MOVE PARTITION|PART partition_expr TO DISK|VOLUME 'disk_name' +``` + +Запрос `ALTER TABLE t MOVE`: + +- Не реплицируется, т.к. на разных репликах могут быть различные конфигурации политик хранения. +- Возвращает ошибку, если указан несконфигурированный том или диск. Ошибка также возвращается в случае невыполнения условий перемещения данных, которые указаны в конфигурации политики хранения. +- Может возвращать ошибку в случае, когда перемещаемые данные уже оказались перемещены в результате фонового процесса, конкурентного запроса `ALTER TABLE t MOVE` или как часть результата фоновой операции слияния. В данном случае никаких дополнительных действий от пользователя не требуется. + +Примеры: + +``` sql +ALTER TABLE hits MOVE PART '20190301_14343_16206_438' TO VOLUME 'slow' +ALTER TABLE hits MOVE PARTITION '2019-09-01' TO DISK 'fast_ssd' +``` + +## Как задавать имя партиции в запросах ALTER {#alter-how-to-specify-part-expr} + +Чтобы задать нужную партицию в запросах `ALTER ... PARTITION`, можно использовать: + +- Имя партиции. Посмотреть имя партиции можно в столбце `partition` системной таблицы [system.parts](../../../operations/system-tables/parts.md#system_tables-parts). Например, `ALTER TABLE visits DETACH PARTITION 201901`. +- Произвольное выражение из столбцов исходной таблицы. Также поддерживаются константы и константные выражения. Например, `ALTER TABLE visits DETACH PARTITION toYYYYMM(toDate('2019-01-25'))`. +- Строковый идентификатор партиции. Идентификатор партиции используется для именования кусков партиции на файловой системе и в ZooKeeper. В запросах `ALTER` идентификатор партиции нужно указывать в секции `PARTITION ID`, в одинарных кавычках. Например, `ALTER TABLE visits DETACH PARTITION ID '201901'`. +- Для запросов [ATTACH PART](#alter_attach-partition) и [DROP DETACHED PART](#alter_drop-detached): чтобы задать имя куска партиции, используйте строковой литерал со значением из столбца `name` системной таблицы [system.detached_parts](../../../operations/system-tables/detached_parts.md#system_tables-detached_parts). Например, `ALTER TABLE visits ATTACH PART '201901_1_1_0'`. + +Использование кавычек в имени партиций зависит от типа данных столбца, по которому задано партиционирование. Например, для столбца с типом `String` имя партиции необходимо указывать в кавычках (одинарных). Для типов `Date` и `Int*` кавычки указывать не нужно. + +Замечание: для таблиц старого стиля партицию можно указывать и как число `201901`, и как строку `'201901'`. Синтаксис для таблиц нового типа более строг к типам (аналогично парсеру входного формата VALUES). + +Правила, сформулированные выше, актуальны также для запросов [OPTIMIZE](../../../sql-reference/statements/optimize.md). Чтобы указать единственную партицию непартиционированной таблицы, укажите `PARTITION tuple()`. Например: + +``` sql +OPTIMIZE TABLE table_not_partitioned PARTITION tuple() FINAL; +``` + +Примеры запросов `ALTER ... PARTITION` можно посмотреть в тестах: [`00502_custom_partitioning_local`](https://github.com/ClickHouse/ClickHouse/blob/master/tests/queries/0_stateless/00502_custom_partitioning_local.sql) и [`00502_custom_partitioning_replicated_zookeeper`](https://github.com/ClickHouse/ClickHouse/blob/master/tests/queries/0_stateless/00502_custom_partitioning_replicated_zookeeper.sql). + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/partition/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/quota.md b/docs/ru/sql-reference/statements/alter/quota.md new file mode 100644 index 00000000000..707f56e7cd4 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/quota.md @@ -0,0 +1,22 @@ +--- +toc_priority: 46 +toc_title: QUOTA +--- + +# ALTER QUOTA {#alter-quota-statement} + +Изменяет квоту. + +## Синтаксис {#alter-quota-syntax} + +``` sql +ALTER QUOTA [IF EXISTS] name [ON CLUSTER cluster_name] + [RENAME TO new_name] + [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}] + [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR} + {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] | + NO LIMITS | TRACKING ONLY} [,...]] + [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] +``` + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/quota/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/role.md b/docs/ru/sql-reference/statements/alter/role.md new file mode 100644 index 00000000000..c56f34e016f --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/role.md @@ -0,0 +1,18 @@ +--- +toc_priority: 46 +toc_title: ROLE +--- + +# ALTER ROLE {#alter-role-statement} + +Изменяет роль. + +## Синтаксис {#alter-role-syntax} + +``` sql +ALTER ROLE [IF EXISTS] name [ON CLUSTER cluster_name] + [RENAME TO new_name] + [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] +``` + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/role/) diff --git a/docs/ru/sql-reference/statements/alter/row-policy.md b/docs/ru/sql-reference/statements/alter/row-policy.md new file mode 100644 index 00000000000..0a7931d23de --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/row-policy.md @@ -0,0 +1,21 @@ +--- +toc_priority: 47 +toc_title: ROW POLICY +--- + +# ALTER ROW POLICY {#alter-row-policy-statement} + +Изменяет политику доступа к строкам. + +## Синтаксис {#alter-row-policy-syntax} + +``` sql +ALTER [ROW] POLICY [IF EXISTS] name [ON CLUSTER cluster_name] ON [database.]table + [RENAME TO new_name] + [AS {PERMISSIVE | RESTRICTIVE}] + [FOR SELECT] + [USING {condition | NONE}][,...] + [TO {role [,...] | ALL | ALL EXCEPT role [,...]}] +``` + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/row-policy/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/settings-profile.md b/docs/ru/sql-reference/statements/alter/settings-profile.md new file mode 100644 index 00000000000..7a39a0efae2 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/settings-profile.md @@ -0,0 +1,18 @@ +--- +toc_priority: 48 +toc_title: SETTINGS PROFILE +--- + +# ALTER SETTINGS PROFILE {#alter-settings-profile-statement} + +Изменяет профили настроек. + +## Синтаксис {#alter-settings-profile-syntax} + +``` sql +ALTER SETTINGS PROFILE [IF EXISTS] name [ON CLUSTER cluster_name] + [RENAME TO new_name] + [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...] +``` + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/settings-profile) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/ttl.md b/docs/ru/sql-reference/statements/alter/ttl.md new file mode 100644 index 00000000000..5e5f47c22e3 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/ttl.md @@ -0,0 +1,14 @@ +--- +toc_priority: 44 +toc_title: TTL +--- + +# Манипуляции с TTL таблицы {#manipuliatsii-s-ttl-tablitsy} + +Вы можете изменить [TTL для таблицы](../../../engines/table-engines/mergetree-family/mergetree.md#mergetree-column-ttl) запросом следующего вида: + +``` sql +ALTER TABLE table-name MODIFY TTL ttl-expression +``` + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/ttl/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/update.md b/docs/ru/sql-reference/statements/alter/update.md new file mode 100644 index 00000000000..f497b2c4511 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/update.md @@ -0,0 +1,29 @@ +--- +toc_priority: 40 +toc_title: UPDATE +--- + +# ALTER TABLE … UPDATE {#alter-table-update-statements} + +``` sql +ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr +``` + +Позволяет манипулировать данными, соответствующими заданному выражению фильтрации. Реализовано как [мутация](../../../sql-reference/statements/alter/index.md#mutations). + +!!! note "Note" + Префикс `ALTER TABLE` делает этот синтаксис отличным от большинства других систем, поддерживающих SQL. Он предназначен для обозначения того, что в отличие от аналогичных запросов в базах данных OLTP это тяжелая операция, не предназначенная для частого использования. + +Выражение `filter_expr` должно иметь тип `UInt8`. Запрос изменяет значение указанных столбцов на вычисленное значение соответствующих выражений в каждой строке, для которой `filter_expr` принимает ненулевое значение. Вычисленные значения преобразуются к типу столбца с помощью оператора `CAST`. Изменение столбцов, которые используются при вычислении первичного ключа или ключа партиционирования, не поддерживается. + +Один запрос может содержать несколько команд, разделенных запятыми. + +Синхронность обработки запроса определяется параметром [mutations_sync](../../../operations/settings/settings.md#mutations_sync). По умолчанию он является асинхронным. + +**Смотрите также** + +- [Мутации](../../../sql-reference/statements/alter/index.md#mutations) +- [Синхронность запросов ALTER](../../../sql-reference/statements/alter/index.md#synchronicity-of-alter-queries) +- [mutations_sync](../../../operations/settings/settings.md#mutations_sync) setting + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/update/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/alter/user.md b/docs/ru/sql-reference/statements/alter/user.md new file mode 100644 index 00000000000..0e8fda23380 --- /dev/null +++ b/docs/ru/sql-reference/statements/alter/user.md @@ -0,0 +1,49 @@ +--- +toc_priority: 45 +toc_title: USER +--- + +# ALTER USER {#alter-user-statement} + +Изменяет аккаунт пользователя ClickHouse. + +## Синтаксис {#alter-user-syntax} + +``` sql +ALTER USER [IF EXISTS] name [ON CLUSTER cluster_name] + [RENAME TO new_name] + [IDENTIFIED [WITH {PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD}] BY {'password'|'hash'}] + [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE] + [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ] + [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...] +``` + +## Описание {#alter-user-dscr} + +Для выполнения `ALTER USER` необходима привилегия [ALTER USER](../grant.md#grant-access-management). + +## Примеры {#alter-user-examples} + +Установить ролями по умолчанию роли, назначенные пользователю: + +``` sql +ALTER USER user DEFAULT ROLE role1, role2 +``` + +Если роли не были назначены пользователю, ClickHouse выбрасывает исключение. + +Установить ролями по умолчанию все роли, назначенные пользователю: + +``` sql +ALTER USER user DEFAULT ROLE ALL +``` + +Если роль будет впоследствии назначена пользователю, она автоматически станет ролью по умолчанию. + +Установить ролями по умолчанию все назначенные пользователю роли кроме `role1` и `role2`: + +``` sql +ALTER USER user DEFAULT ROLE ALL EXCEPT role1, role2 +``` + +[Оригинальная статья](https://clickhouse.tech/docs/ru/query_language/alter/user/) \ No newline at end of file diff --git a/docs/ru/sql-reference/statements/create/role.md b/docs/ru/sql-reference/statements/create/role.md index e8374320546..b8c0fc2b453 100644 --- a/docs/ru/sql-reference/statements/create/role.md +++ b/docs/ru/sql-reference/statements/create/role.md @@ -20,7 +20,7 @@ CREATE ROLE [IF NOT EXISTS | OR REPLACE] name Одному пользователю можно назначить несколько ролей. Пользователи могут применять назначенные роли в произвольных комбинациях с помощью выражения [SET ROLE](../misc.md#set-role-statement). Конечный объем привилегий — это комбинация всех привилегий всех примененных ролей. Если у пользователя имеются привилегии, присвоенные его аккаунту напрямую, они также прибавляются к привилегиям, присвоенным через роли. -Роли по умолчанию применяются при входе пользователя в систему. Установить роли по умолчанию можно с помощью выражений [SET DEFAULT ROLE](../misc.md#set-default-role-statement) или [ALTER USER](../alter.md#alter-user-statement). +Роли по умолчанию применяются при входе пользователя в систему. Установить роли по умолчанию можно с помощью выражений [SET DEFAULT ROLE](../misc.md#set-default-role-statement) или [ALTER USER](../alter/index.md#alter-user-statement). Для отзыва роли используется выражение [REVOKE](../../../sql-reference/statements/revoke.md). diff --git a/docs/ru/sql-reference/statements/grant.md b/docs/ru/sql-reference/statements/grant.md index 043df0f7397..8eea84ac594 100644 --- a/docs/ru/sql-reference/statements/grant.md +++ b/docs/ru/sql-reference/statements/grant.md @@ -249,7 +249,7 @@ GRANT INSERT(x,y) ON db.table TO john ### ALTER {#grant-alter} -Разрешает выполнять запросы [ALTER](alter.md) в соответствии со следующей иерархией привилегий: +Разрешает выполнять запросы [ALTER](alter/index.md) в соответствии со следующей иерархией привилегий: - `ALTER`. Уровень: `COLUMN`. - `ALTER TABLE`. Уровень: `GROUP` diff --git a/docs/ru/sql-reference/statements/kill.md b/docs/ru/sql-reference/statements/kill.md index 4fcfa9a61ce..dd2f24ffa27 100644 --- a/docs/ru/sql-reference/statements/kill.md +++ b/docs/ru/sql-reference/statements/kill.md @@ -51,7 +51,7 @@ KILL MUTATION [ON CLUSTER cluster] [FORMAT format] ``` -Пытается остановить выполняющиеся в данные момент [мутации](alter.md#mutations). Мутации для остановки выбираются из таблицы [`system.mutations`](../../operations/system-tables/mutations.md#system_tables-mutations) с помощью условия, указанного в секции `WHERE` запроса `KILL`. +Пытается остановить выполняющиеся в данные момент [мутации](alter/index.md#mutations). Мутации для остановки выбираются из таблицы [`system.mutations`](../../operations/system-tables/mutations.md#system_tables-mutations) с помощью условия, указанного в секции `WHERE` запроса `KILL`. Тестовый вариант запроса (`TEST`) только проверяет права пользователя и выводит список запросов для остановки. diff --git a/docs/ru/sql-reference/statements/optimize.md b/docs/ru/sql-reference/statements/optimize.md index c150f02c3d6..d94ba2aa5da 100644 --- a/docs/ru/sql-reference/statements/optimize.md +++ b/docs/ru/sql-reference/statements/optimize.md @@ -14,7 +14,7 @@ OPTIMIZE TABLE [db.]name [ON CLUSTER cluster] [PARTITION partition | PARTITION I Если `OPTIMIZE` применяется к таблицам семейства [ReplicatedMergeTree](../../engines/table-engines/mergetree-family/replication.md), ClickHouse создаёт задачу на мёрж и ожидает её исполнения на всех узлах (если активирована настройка `replication_alter_partitions_sync`). - Если `OPTIMIZE` не выполняет мёрж по любой причине, ClickHouse не оповещает об этом клиента. Чтобы включить оповещения, используйте настройку [optimize\_throw\_if\_noop](../../operations/settings/settings.md#setting-optimize_throw_if_noop). -- Если указать `PARTITION`, то оптимизация выполняется только для указанной партиции. [Как задавать имя партиции в запросах](alter.md#alter-how-to-specify-part-expr). +- Если указать `PARTITION`, то оптимизация выполняется только для указанной партиции. [Как задавать имя партиции в запросах](alter/index.md#alter-how-to-specify-part-expr). - Если указать `FINAL`, то оптимизация выполняется даже в том случае, если все данные уже лежат в одном куске. - Если указать `DEDUPLICATE`, то произойдет схлопывание полностью одинаковых строк (сравниваются значения во всех колонках), имеет смысл только для движка MergeTree. diff --git a/docs/ru/whats-new/extended-roadmap.md b/docs/ru/whats-new/extended-roadmap.md index d222fd4e284..fa371df2d4a 100644 --- a/docs/ru/whats-new/extended-roadmap.md +++ b/docs/ru/whats-new/extended-roadmap.md @@ -637,7 +637,7 @@ Upd. Готово (все директории кроме contrib). Требует 7.26. Коллеги начали делать, есть результат. Upd. В Аркадии частично работает небольшая часть тестов. И этого достаточно. -### 7.29. Опции clickhouse install, stop, start вместо postinst, init.d, systemd скриптов {#optsii-clickhouse-install-stop-start-vmesto-postinst-init-d-systemd-skriptov} +### 7.29. + Опции clickhouse install, stop, start вместо postinst, init.d, systemd скриптов {#optsii-clickhouse-install-stop-start-vmesto-postinst-init-d-systemd-skriptov} Низкий приоритет. @@ -786,7 +786,7 @@ Upd. Готово. Павел Круглов, ВШЭ и Яндекс. Есть pull request. Готово. -### 8.17. ClickHouse как MySQL реплика {#clickhouse-kak-mysql-replika} +### 8.17. + ClickHouse как MySQL реплика {#clickhouse-kak-mysql-replika} Задачу делает BohuTANG. @@ -1447,11 +1447,11 @@ Upd. Возможно будет отложено на следующий год Василий Морозов, Арслан Гумеров, Альберт Кидрачев, ВШЭ. В прошлом году задачу начинал делать другой человек, но не добился достаточного прогресса. -+ 1. Оптимизация top sort. +\+ 1. Оптимизация top sort. В ClickHouse используется неоптимальный вариант top sort. Суть его в том, что из каждого блока достаётся top N записей, а затем, все блоки мержатся. Но доставание top N записей у каждого следующего блока бессмысленно, если мы знаем, что из них в глобальный top N войдёт меньше. Конечно нужно реализовать вариацию на тему priority queue (heap) с быстрым пропуском целых блоков, если ни одна строка не попадёт в накопленный top. -+ 2. Рекурсивный вариант сортировки по кортежам. +\+ 2. Рекурсивный вариант сортировки по кортежам. Для сортировки по кортежам используется обычная сортировка с компаратором, который в цикле по элементам кортежа делает виртуальные вызовы `IColumn::compareAt`. Это неоптимально - как из-за короткого цикла по неизвестному в compile-time количеству элементов, так и из-за виртуальных вызовов. Чтобы обойтись без виртуальных вызовов, есть метод `IColumn::getPermutation`. Он используется в случае сортировки по одному столбцу. Есть вариант, что в случае сортировки по кортежу, что-то похожее тоже можно применить… например, сделать метод `updatePermutation`, принимающий аргументы offset и limit, и допереставляющий перестановку в диапазоне значений, в которых предыдущий столбец имел равные значения. @@ -1583,8 +1583,8 @@ Upd. Готово. После 10.14. -[\#7237](https://github.com/ClickHouse/ClickHouse/issues/7237) -[\#2655](https://github.com/ClickHouse/ClickHouse/issues/2655) +[#7237](https://github.com/ClickHouse/ClickHouse/issues/7237) +[#2655](https://github.com/ClickHouse/ClickHouse/issues/2655) ### 22.23. Правильная обработка Nullable в функциях, которые кидают исключение на default значении: modulo, intDiv {#pravilnaia-obrabotka-nullable-v-funktsiiakh-kotorye-kidaiut-iskliuchenie-na-default-znachenii-modulo-intdiv} @@ -1598,7 +1598,7 @@ Upd. Готово. ### 22.26. Плохая производительность quantileTDigest {#plokhaia-proizvoditelnost-quantiletdigest} -[\#2668](https://github.com/ClickHouse/ClickHouse/issues/2668) +[#2668](https://github.com/ClickHouse/ClickHouse/issues/2668) Алексей Миловидов или будет переназначено. diff --git a/docs/tools/requirements.txt b/docs/tools/requirements.txt index 03fa9fbb12c..9e916489ea4 100644 --- a/docs/tools/requirements.txt +++ b/docs/tools/requirements.txt @@ -21,7 +21,7 @@ mkdocs-htmlproofer-plugin==0.0.3 mkdocs-macros-plugin==0.4.9 nltk==3.5 nose==1.3.7 -protobuf==3.12.4 +protobuf==3.13.0 numpy==1.19.1 Pygments==2.5.2 pymdown-extensions==8.0 diff --git a/docs/tr/development/style.md b/docs/tr/development/style.md index bf2dd250ad0..1628641df52 100644 --- a/docs/tr/development/style.md +++ b/docs/tr/development/style.md @@ -705,7 +705,7 @@ Ama diğer şeyler eşit olmak, çapraz platform veya taşınabilir kod tercih e **3.** Derleyici: `gcc`. Şu anda (Ağustos 2020), kod sürüm 9.3 kullanılarak derlenmiştir. (Ayrıca kullanılarak derlenebilir `clang 8`.) -Standart kütüphane kullanılır (`libstdc++` veya `libc++`). +Standart kütüphane kullanılır (`libc++`). **4.**OS: Linux UB .untu, daha eski değil. diff --git a/docs/tr/development/tests.md b/docs/tr/development/tests.md index b2b9d83fe7a..4406cae6429 100644 --- a/docs/tr/development/tests.md +++ b/docs/tr/development/tests.md @@ -176,7 +176,7 @@ Ana ClickHouse kodu (bu `dbms` dizin) ile inşa edilmiştir `-Wall -Wextra -Werr Clang daha yararlı uyarılar vardır-Sen ile onları arayabilirsiniz `-Weverything` ve varsayılan oluşturmak için bir şey seçin. -Üretim yapıları için gcc kullanılır (hala clang'dan biraz daha verimli kod üretir). Geliştirme için, clang genellikle kullanımı daha uygundur. Hata ayıklama modu ile kendi makinenizde inşa edebilirsiniz (dizüstü bilgisayarınızın pilinden tasarruf etmek için), ancak derleyicinin daha fazla uyarı üretebileceğini lütfen unutmayın `-O3` daha iyi kontrol akışı ve prosedürler arası analiz nedeniyle. Clang ile inşa ederken, `libc++` yerine kullanılır `libstdc++` ve hata ayıklama modu ile oluştururken, hata ayıklama sürümü `libc++` çalışma zamanında daha fazla hata yakalamak için izin verir kullanılır. +Üretim yapıları için gcc kullanılır (hala clang'dan biraz daha verimli kod üretir). Geliştirme için, clang genellikle kullanımı daha uygundur. Hata ayıklama modu ile kendi makinenizde inşa edebilirsiniz (dizüstü bilgisayarınızın pilinden tasarruf etmek için), ancak derleyicinin daha fazla uyarı üretebileceğini lütfen unutmayın `-O3` daha iyi kontrol akışı ve prosedürler arası analiz nedeniyle. Clang ile inşa ederken ayıklama modu ile oluştururken, hata ayıklama sürümü `libc++` çalışma zamanında daha fazla hata yakalamak için izin verir kullanılır. ## Dezenfektanlar {#sanitizers} diff --git a/docs/tr/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/tr/engines/table-engines/mergetree-family/replacingmergetree.md index a24c84e9a16..f586b97cb2f 100644 --- a/docs/tr/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/tr/engines/table-engines/mergetree-family/replacingmergetree.md @@ -33,7 +33,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] **ReplacingMergeTree Parametreleri** -- `ver` — column with version. Type `UInt*`, `Date` veya `DateTime`. İsteğe bağlı parametre. +- `ver` — column with version. Type `UInt*`, `Date`, `DateTime` veya `DateTime64`. İsteğe bağlı parametre. Birleş whenirken, `ReplacingMergeTree` aynı birincil anahtara sahip tüm satırlardan sadece bir tane bırakır: diff --git a/docs/tr/interfaces/third-party/client-libraries.md b/docs/tr/interfaces/third-party/client-libraries.md index b9940b557b5..7fba28f662a 100644 --- a/docs/tr/interfaces/third-party/client-libraries.md +++ b/docs/tr/interfaces/third-party/client-libraries.md @@ -48,6 +48,7 @@ toc_title: "\u0130stemci Kitapl\u0131klar\u0131" - Kotlin - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [ClickHouse.Gürültü](https://github.com/killwort/ClickHouse-Net) - [ClickHouse.Müşteri](https://github.com/DarkWanderer/ClickHouse.Client) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) diff --git a/docs/tr/operations/system-tables.md b/docs/tr/operations/system-tables.md index 7d8339a9c0f..9412669287c 100644 --- a/docs/tr/operations/system-tables.md +++ b/docs/tr/operations/system-tables.md @@ -532,7 +532,7 @@ Sütun: - `query` (String) – The query text. For `INSERT`, eklemek için veri içermez. - `query_id` (String) – Query ID, if defined. -## sistem.text\_log {#system-tables-text-log} +## sistem.text\_log {#system_tables-text_log} Günlük girişleri içerir. Bu tabloya giden günlük seviyesi ile sınırlı olabilir `text_log.level` sunucu ayarı. diff --git a/docs/tr/sql-reference/functions/string-search-functions.md b/docs/tr/sql-reference/functions/string-search-functions.md index be30510ef2a..b80df910972 100644 --- a/docs/tr/sql-reference/functions/string-search-functions.md +++ b/docs/tr/sql-reference/functions/string-search-functions.md @@ -20,15 +20,16 @@ Büyük / küçük harf duyarsız arama için işlevi kullanın [positionCaseİn **Sözdizimi** ``` sql -position(haystack, needle) +position(haystack, needle[, start_pos]) ``` -Takma ad: `locate(haystack, needle)`. +Takma ad: `locate(haystack, needle[, start_pos])`. **Parametre** - `haystack` — string, in which substring will to be searched. [Dize](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Dize](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Döndürülen değerler** @@ -80,13 +81,14 @@ Dize, tek baytlık kodlanmış bir metni temsil eden bir bayt kümesi içerdiği **Sözdizimi** ``` sql -positionCaseInsensitive(haystack, needle) +positionCaseInsensitive(haystack, needle[, start_pos]) ``` **Parametre** - `haystack` — string, in which substring will to be searched. [Dize](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Dize](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Döndürülen değerler** @@ -122,13 +124,14 @@ Büyük / küçük harf duyarsız arama için işlevi kullanın [positionCaseİn **Sözdizimi** ``` sql -positionUTF8(haystack, needle) +positionUTF8(haystack, needle[, start_pos]) ``` **Parametre** - `haystack` — string, in which substring will to be searched. [Dize](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Dize](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Döndürülen değerler** @@ -194,13 +197,14 @@ Dizenin UTF-8 kodlanmış bir metni temsil eden bir bayt kümesi içerdiği vars **Sözdizimi** ``` sql -positionCaseInsensitiveUTF8(haystack, needle) +positionCaseInsensitiveUTF8(haystack, needle[, start_pos]) ``` **Parametre** - `haystack` — string, in which substring will to be searched. [Dize](../syntax.md#syntax-string-literal). - `needle` — substring to be searched. [Dize](../syntax.md#syntax-string-literal). +- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md) **Döndürülen değer** diff --git a/docs/zh/development/style.md b/docs/zh/development/style.md index 8451e5208e3..a87476d7748 100644 --- a/docs/zh/development/style.md +++ b/docs/zh/development/style.md @@ -698,7 +698,7 @@ auto s = std::string{"Hello"}; **3.** 编译器: `gcc`。 此时(2020年08月),代码使用9.3版编译。(它也可以使用`clang 8` 编译) -使用标准库 (`libstdc++` 或 `libc++`)。 +使用标准库 (`libc++`)。 **4.** 操作系统:Linux Ubuntu,不比 Precise 早。 diff --git a/docs/zh/engines/table-engines/mergetree-family/replacingmergetree.md b/docs/zh/engines/table-engines/mergetree-family/replacingmergetree.md index 626597eeaf0..03b47172400 100644 --- a/docs/zh/engines/table-engines/mergetree-family/replacingmergetree.md +++ b/docs/zh/engines/table-engines/mergetree-family/replacingmergetree.md @@ -25,7 +25,7 @@ CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] **参数** -- `ver` — 版本列。类型为 `UInt*`, `Date` 或 `DateTime`。可选参数。 +- `ver` — 版本列。类型为 `UInt*`, `Date`, `DateTime` 或 `DateTime64`。可选参数。 合并的时候,`ReplacingMergeTree` 从所有具有相同主键的行中选择一行留下: - 如果 `ver` 列未指定,选择最后一条。 diff --git a/docs/zh/interfaces/third-party/client-libraries.md b/docs/zh/interfaces/third-party/client-libraries.md index 007bc986452..7bc4ae0aa27 100644 --- a/docs/zh/interfaces/third-party/client-libraries.md +++ b/docs/zh/interfaces/third-party/client-libraries.md @@ -39,6 +39,7 @@ - Kotlin - [AORM](https://github.com/TanVD/AORM) - C\# + - [Octonica.ClickHouseClient](https://github.com/Octonica/ClickHouseClient) - [克莱克豪斯Ado](https://github.com/killwort/ClickHouse-Net) - [ClickHouse.Net](https://github.com/ilyabreev/ClickHouse.Net) - [克莱克豪斯客户](https://github.com/DarkWanderer/ClickHouse.Client) diff --git a/docs/zh/operations/settings/settings.md b/docs/zh/operations/settings/settings.md index ec31b8e82bc..2befb7ee15d 100644 --- a/docs/zh/operations/settings/settings.md +++ b/docs/zh/operations/settings/settings.md @@ -1252,3 +1252,61 @@ ClickHouse生成异常 默认值:16。 [原始文章](https://clickhouse.tech/docs/en/operations/settings/settings/) + +## transform\_null\_in {#transform_null_in} + +为[IN](../../sql-reference/operators/in.md) 运算符启用[NULL](../../sql-reference/syntax.md#null-literal) 值的相等性。 + +默认情况下,无法比较 `NULL` 值,因为 `NULL` 表示未定义的值。 因此,比较 `expr = NULL` 必须始终返回 `false`。 在此设置下,`NULL = NULL` 为IN运算符返回 `true`. + +可能的值: + +- 0 — 比较 `IN` 运算符中 `NULL` 值将返回 `false`。 +- 1 — 比较 `IN` 运算符中 `NULL` 值将返回 `true`。 + +默认值:0。 + +**例** + +考虑`null_in`表: + +``` text +┌──idx─┬─────i─┐ +│ 1 │ 1 │ +│ 2 │ NULL │ +│ 3 │ 3 │ +└──────┴───────┘ +``` + +查询: + +``` sql +SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 0; +``` + +结果: + +``` text +┌──idx─┬────i─┐ +│ 1 │ 1 │ +└──────┴──────┘ +``` + +查询: + +``` sql +SELECT idx, i FROM null_in WHERE i IN (1, NULL) SETTINGS transform_null_in = 1; +``` + +结果: + +``` text +┌──idx─┬─────i─┐ +│ 1 │ 1 │ +│ 2 │ NULL │ +└──────┴───────┘ +``` + +**另请参阅** + +- [IN 运算符中的 NULL 处理](../../sql-reference/operators/in.md#in-null-processing) diff --git a/docs/zh/operations/system-tables/text_log.md b/docs/zh/operations/system-tables/text_log.md index 60c7a3ed90c..9643fbef358 100644 --- a/docs/zh/operations/system-tables/text_log.md +++ b/docs/zh/operations/system-tables/text_log.md @@ -3,7 +3,7 @@ machine_translated: true machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 --- -# 系统。text\_log {#system-tables-text-log} +# 系统。text\_log {#system_tables-text_log} 包含日志记录条目。 进入该表的日志记录级别可以通过以下方式进行限制 `text_log.level` 服务器设置。 diff --git a/docs/zh/sql-reference/statements/select/array-join.md b/docs/zh/sql-reference/statements/select/array-join.md index e84682838f4..c5237bb7ea6 100644 --- a/docs/zh/sql-reference/statements/select/array-join.md +++ b/docs/zh/sql-reference/statements/select/array-join.md @@ -1,14 +1,12 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: ARRAY JOIN --- # ARRAY JOIN子句 {#select-array-join-clause} -对于包含数组列的表来说,这是一种常见的操作,用于生成一个新表,该表具有包含该初始列的每个单独数组元素的列,而其他列的值将被重复。 这是什么基本情况 `ARRAY JOIN` 子句有 +对于包含数组列的表来说是一种常见的操作,用于生成一个新表,该表具有包含该初始列中的每个单独数组元素的列,而其他列的值将被重复显示。 这是 `ARRAY JOIN` 语句最基本的场景。 -它的名字来自这样一个事实,即它可以被视为执行 `JOIN` 具有数组或嵌套数据结构。 意图类似于 [arrayJoin](../../../sql-reference/functions/array-join.md#functions_arrayjoin) 功能,但该子句功能更广泛。 +它可以被视为执行 `JOIN` 并具有数组或嵌套数据结构。 类似于 [arrayJoin](../../../sql-reference/functions/array-join.md#functions_arrayjoin) 功能,但该子句功能更广泛。 语法: @@ -20,16 +18,16 @@ FROM ... ``` -您只能指定一个 `ARRAY JOIN` a中的条款 `SELECT` 查询。 +您只能在 `SELECT` 查询指定一个 `ARRAY JOIN` 。 -支持的类型 `ARRAY JOIN` 下面列出: + `ARRAY JOIN` 支持的类型有: -- `ARRAY JOIN` -在基本情况下,空数组不包括在结果中 `JOIN`. -- `LEFT ARRAY JOIN` -的结果 `JOIN` 包含具有空数组的行。 空数组的值设置为数组元素类型的默认值(通常为0、空字符串或NULL)。 +- `ARRAY JOIN` - 一般情况下,空数组不包括在结果中 `JOIN`. +- `LEFT ARRAY JOIN` - 的结果 `JOIN` 包含具有空数组的行。 空数组的值设置为数组元素类型的默认值(通常为0、空字符串或NULL)。 -## 基本数组连接示例 {#basic-array-join-examples} +## 基本 ARRAY JOIN 示例 {#basic-array-join-examples} -下面的例子演示的用法 `ARRAY JOIN` 和 `LEFT ARRAY JOIN` 条款 让我们创建一个表 [阵列](../../../sql-reference/data-types/array.md) 键入column并在其中插入值: +下面的例子展示 `ARRAY JOIN` 和 `LEFT ARRAY JOIN` 的用法,让我们创建一个表包含一个 [Array](../../../sql-reference/data-types/array.md) 的列并插入值: ``` sql CREATE TABLE arrays_test @@ -50,7 +48,7 @@ VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); └─────────────┴─────────┘ ``` -下面的例子使用 `ARRAY JOIN` 条款: +下面的例子使用 `ARRAY JOIN` 子句: ``` sql SELECT s, arr @@ -68,7 +66,7 @@ ARRAY JOIN arr; └───────┴─────┘ ``` -下一个示例使用 `LEFT ARRAY JOIN` 条款: +下一个示例使用 `LEFT ARRAY JOIN` 子句: ``` sql SELECT s, arr @@ -89,7 +87,7 @@ LEFT ARRAY JOIN arr; ## 使用别名 {#using-aliases} -可以为数组中的别名指定 `ARRAY JOIN` 条款 在这种情况下,数组项目可以通过此别名访问,但数组本身可以通过原始名称访问。 示例: +在使用`ARRAY JOIN` 时可以为数组指定别名,数组元素可以通过此别名访问,但数组本身则通过原始名称访问。 示例: ``` sql SELECT s, arr, a @@ -107,7 +105,7 @@ ARRAY JOIN arr AS a; └───────┴─────────┴───┘ ``` -使用别名,您可以执行 `ARRAY JOIN` 与外部阵列。 例如: +可以使用别名与外部数组执行 `ARRAY JOIN` 。 例如: ``` sql SELECT s, arr_external @@ -129,7 +127,7 @@ ARRAY JOIN [1, 2, 3] AS arr_external; └─────────────┴──────────────┘ ``` -多个数组可以在逗号分隔 `ARRAY JOIN` 条款 在这种情况下, `JOIN` 与它们同时执行(直接和,而不是笛卡尔积)。 请注意,所有数组必须具有相同的大小。 示例: +在 `ARRAY JOIN` 中,多个数组可以用逗号分隔, 在这例子中 `JOIN` 与它们同时执行(直接sum,而不是笛卡尔积)。 请注意,所有数组必须具有相同的大小。 示例: ``` sql SELECT s, arr, a, num, mapped @@ -242,7 +240,7 @@ ARRAY JOIN `nest.x`; └───────┴────────┴────────────┘ ``` -可以将别名用于嵌套数据结构,以便选择 `JOIN` 结果或源数组。 示例: +可以将别名用于嵌套数据结构,以便选择 `JOIN` 结果或源数组。 例如: ``` sql SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y` @@ -260,7 +258,7 @@ ARRAY JOIN nest AS n; └───────┴─────┴─────┴─────────┴────────────┘ ``` -使用的例子 [arrayEnumerate](../../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) 功能: +使用功能 [arrayEnumerate](../../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) 的例子: ``` sql SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y`, num @@ -278,6 +276,6 @@ ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num; └───────┴─────┴─────┴─────────┴────────────┴─────┘ ``` -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} 运行时优化查询执行顺序 `ARRAY JOIN`. 虽然 `ARRAY JOIN` 必须始终之前指定 [WHERE](../../../sql-reference/statements/select/where.md)/[PREWHERE](../../../sql-reference/statements/select/prewhere.md) 子句中的查询,从技术上讲,它们可以以任何顺序执行,除非结果 `ARRAY JOIN` 用于过滤。 处理顺序由查询优化器控制。 diff --git a/docs/zh/sql-reference/statements/select/distinct.md b/docs/zh/sql-reference/statements/select/distinct.md index ea430e8602f..270bbc1e996 100644 --- a/docs/zh/sql-reference/statements/select/distinct.md +++ b/docs/zh/sql-reference/statements/select/distinct.md @@ -1,32 +1,30 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: DISTINCT --- # DISTINCT子句 {#select-distinct} -如果 `SELECT DISTINCT` 如果指定,则查询结果中只保留唯一行。 因此,在结果中所有完全匹配的行集合中,只有一行将保留。 +如果 `SELECT DISTINCT` 被声明,则查询结果中只保留唯一行。 因此,在结果中所有完全匹配的行集合中,只有一行被保留。 ## 空处理 {#null-processing} -`DISTINCT` 适用于 [NULL](../../../sql-reference/syntax.md#null-literal) 就好像 `NULL` 是一个特定的值,并且 `NULL==NULL`. 换句话说,在 `DISTINCT` 结果,不同的组合 `NULL` 仅发生一次。 它不同于 `NULL` 在大多数其他上下文中进行处理。 +`DISTINCT` 适用于 [NULL](../../../sql-reference/syntax.md#null-literal) 就好像 `NULL` 是一个特定的值,并且 `NULL==NULL`. 换句话说,在 `DISTINCT` 结果,不同的组合 `NULL` 仅发生一次。 它不同于 `NULL` 在大多数其他情况中的处理方式。 ## 替代办法 {#alternatives} -通过应用可以获得相同的结果 [GROUP BY](../../../sql-reference/statements/select/group-by.md) 在同一组值指定为 `SELECT` 子句,而不使用任何聚合函数。 但有几个区别 `GROUP BY` 方法: +通过应用可以获得相同的结果 [GROUP BY](../../../sql-reference/statements/select/group-by.md) 在同一组值指定为 `SELECT` 子句,并且不使用任何聚合函数。 但与 `GROUP BY` 有几个不同的地方: -- `DISTINCT` 可以一起应用 `GROUP BY`. -- 当 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 省略和 [LIMIT](../../../sql-reference/statements/select/limit.md) 定义时,查询在读取所需数量的不同行后立即停止运行。 +- `DISTINCT` 可以与 `GROUP BY` 一起使用. +- 当 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 被省略并且 [LIMIT](../../../sql-reference/statements/select/limit.md) 被定义时,在读取所需数量的不同行后立即停止运行。 - 数据块在处理时输出,而无需等待整个查询完成运行。 ## 限制 {#limitations} -`DISTINCT` 如果不支持 `SELECT` 具有至少一个数组列。 +`DISTINCT` 不支持当 `SELECT` 包含有数组的列。 -## 例 {#examples} +## 例子 {#examples} -ClickHouse支持使用 `DISTINCT` 和 `ORDER BY` 一个查询中不同列的子句。 该 `DISTINCT` 子句之前执行 `ORDER BY` 条款 +ClickHouse支持使用 `DISTINCT` 和 `ORDER BY` 在一个查询中的不同的列。 `DISTINCT` 子句在 `ORDER BY` 子句前被执行。 示例表: @@ -39,7 +37,7 @@ ClickHouse支持使用 `DISTINCT` 和 `ORDER BY` 一个查询中不同列的子 └───┴───┘ ``` -当与选择数据 `SELECT DISTINCT a FROM t1 ORDER BY b ASC` 查询,我们得到以下结果: +当执行 `SELECT DISTINCT a FROM t1 ORDER BY b ASC` 来查询数据,我们得到以下结果: ``` text ┌─a─┐ @@ -59,6 +57,6 @@ ClickHouse支持使用 `DISTINCT` 和 `ORDER BY` 一个查询中不同列的子 └───┘ ``` -行 `2, 4` 分拣前被切割。 +行 `2, 4` 排序前被切割。 -在编程查询时考虑这种实现特异性。 +在编程查询时考虑这种实现特性。 diff --git a/docs/zh/sql-reference/statements/select/format.md b/docs/zh/sql-reference/statements/select/format.md index 014aec3b72e..2346499c67b 100644 --- a/docs/zh/sql-reference/statements/select/format.md +++ b/docs/zh/sql-reference/statements/select/format.md @@ -1,19 +1,17 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: FORMAT --- -# 格式子句 {#format-clause} +# 格式化子句 {#format-clause} -ClickHouse支持广泛的 [序列化格式](../../../interfaces/formats.md) 可用于查询结果等。 有多种方法可以选择以下格式 `SELECT` 输出,其中之一是指定 `FORMAT format` 在查询结束时以任何特定格式获取结果数据。 +ClickHouse支持广泛的 [序列化格式](../../../interfaces/formats.md) 可用于查询结果等。 有多种方法可以选择格式化 `SELECT` 的输出,其中之一是指定 `FORMAT format` 在查询结束时以任何特定格式获取结果集。 -特定的格式可以用于方便使用,与其他系统集成或性能增益。 +特定的格式方便使用,与其他系统集成或增强性能。 ## 默认格式 {#default-format} -如果 `FORMAT` 省略子句,使用默认格式,这取决于用于访问ClickHouse服务器的设置和接口。 为 [HTTP接口](../../../interfaces/http.md) 和 [命令行客户端](../../../interfaces/cli.md) 在批处理模式下,默认格式为 `TabSeparated`. 对于交互模式下的命令行客户端,默认格式为 `PrettyCompact` (它生成紧凑的人类可读表)。 +如果 `FORMAT` 被省略则使用默认格式,这取决于用于访问ClickHouse服务器的设置和接口。 为 [HTTP接口](../../../interfaces/http.md) 和 [命令行客户端](../../../interfaces/cli.md) 在批处理模式下,默认格式为 `TabSeparated`. 对于交互模式下的命令行客户端,默认格式为 `PrettyCompact` (它生成紧凑的人类可读表)。 -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} -使用命令行客户端时,数据始终以内部高效格式通过网络传递 (`Native`). 客户端独立解释 `FORMAT` 查询子句并格式化数据本身(从而减轻网络和服务器的额外负载)。 +使用命令行客户端时,数据始终以内部高效格式通过网络传递 (`Native`). 客户端独立解释 `FORMAT` 查询子句并格式化数据本身(以减轻网络和服务器的额外负担)。 diff --git a/docs/zh/sql-reference/statements/select/from.md b/docs/zh/sql-reference/statements/select/from.md index 86ba0959e16..a8b49febab5 100644 --- a/docs/zh/sql-reference/statements/select/from.md +++ b/docs/zh/sql-reference/statements/select/from.md @@ -1,31 +1,29 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: FROM --- -# FROM条款 {#select-from} +# FROM子句 {#select-from} -该 `FROM` 子句指定从中读取数据的源: +`FROM` 子句指定从以下数据源中读取数据: - [表](../../../engines/table-engines/index.md) - [子查询](../../../sql-reference/statements/select/index.md) {## TODO: better link ##} - [表函数](../../../sql-reference/table-functions/index.md#table-functions) -[JOIN](../../../sql-reference/statements/select/join.md) 和 [ARRAY JOIN](../../../sql-reference/statements/select/array-join.md) 子句也可以用来扩展的功能 `FROM` 条款 +[JOIN](../../../sql-reference/statements/select/join.md) 和 [ARRAY JOIN](../../../sql-reference/statements/select/array-join.md) 子句也可以用来扩展 `FROM` 的功能 -子查询是另一个 `SELECT` 可以在括号内指定的查询 `FROM` 条款 +子查询是另一个 `SELECT` 可以指定在 `FROM` 后的括号内的查询。 -`FROM` 子句可以包含多个数据源,用逗号分隔,这相当于执行 [CROSS JOIN](../../../sql-reference/statements/select/join.md) 在他们身上 +`FROM` 子句可以包含多个数据源,用逗号分隔,这相当于在他们身上执行 [CROSS JOIN](../../../sql-reference/statements/select/join.md) -## 最终修饰符 {#select-from-final} +## FINAL 修饰符 {#select-from-final} -当 `FINAL` 如果指定,ClickHouse会在返回结果之前完全合并数据,从而执行给定表引擎合并期间发生的所有数据转换。 +当 `FINAL` 被指定,ClickHouse会在返回结果之前完全合并数据,从而执行给定表引擎合并期间发生的所有数据转换。 -它适用于从使用 [MergeTree](../../../engines/table-engines/mergetree-family/mergetree.md)-发动机系列(除了 `GraphiteMergeTree`). 还支持: +它适用于从使用 [MergeTree](../../../engines/table-engines/mergetree-family/mergetree.md)-引擎族(除了 `GraphiteMergeTree`). 还支持: -- [复制](../../../engines/table-engines/mergetree-family/replication.md) 版本 `MergeTree` 引擎 -- [查看](../../../engines/table-engines/special/view.md), [缓冲区](../../../engines/table-engines/special/buffer.md), [分布](../../../engines/table-engines/special/distributed.md),和 [MaterializedView](../../../engines/table-engines/special/materializedview.md) 在其他引擎上运行的引擎,只要它们是在创建 `MergeTree`-发动机表。 +- [Replicated](../../../engines/table-engines/mergetree-family/replication.md) 版本 `MergeTree` 引擎 +- [View](../../../engines/table-engines/special/view.md), [Buffer](../../../engines/table-engines/special/buffer.md), [Distributed](../../../engines/table-engines/special/distributed.md),和 [MaterializedView](../../../engines/table-engines/special/materializedview.md) 在其他引擎上运行的引擎,只要是它们底层是 `MergeTree`-引擎表即可。 ### 缺点 {#drawbacks} @@ -36,10 +34,10 @@ toc_title: FROM **在大多数情况下,避免使用 `FINAL`.** 常见的方法是使用假设后台进程的不同查询 `MergeTree` 引擎还没有发生,并通过应用聚合(例如,丢弃重复项)来处理它。 {## TODO: examples ##} -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} -如果 `FROM` 子句被省略,数据将从读取 `system.one` 桌子 -该 `system.one` 表只包含一行(此表满足与其他Dbms中找到的双表相同的目的)。 +如果 `FROM` 子句被省略,数据将从读取 `system.one` 表。 +该 `system.one` 表只包含一行(此表满足与其他 DBMS 中的 DUAL 表有相同的作用)。 若要执行查询,将从相应的表中提取查询中列出的所有列。 外部查询不需要的任何列都将从子查询中抛出。 -如果查询未列出任何列(例如, `SELECT count() FROM t`),无论如何都会从表中提取一些列(最小的列是首选),以便计算行数。 +如果查询未列出任何列(例如, `SELECT count() FROM t`),无论如何都会从表中提取一些列(首选是最小的列),以便计算行数。 diff --git a/docs/zh/sql-reference/statements/select/group-by.md b/docs/zh/sql-reference/statements/select/group-by.md index 082fec94498..ecb2f4683fe 100644 --- a/docs/zh/sql-reference/statements/select/group-by.md +++ b/docs/zh/sql-reference/statements/select/group-by.md @@ -1,27 +1,25 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: GROUP BY --- # GROUP BY子句 {#select-group-by-clause} -`GROUP BY` 子句切换 `SELECT` 查询转换为聚合模式,其工作原理如下: +`GROUP BY` 子句将 `SELECT` 查询结果转换为聚合模式,其工作原理如下: -- `GROUP BY` 子句包含表达式列表(或单个表达式,其被认为是长度为1的列表)。 这份名单充当 “grouping key”,而每个单独的表达式将被称为 “key expressions”. -- 在所有的表达式 [SELECT](../../../sql-reference/statements/select/index.md), [HAVING](../../../sql-reference/statements/select/having.md),和 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 条款 **必须** 基于键表达式进行计算 **或** 上 [聚合函数](../../../sql-reference/aggregate-functions/index.md) 在非键表达式(包括纯列)上。 换句话说,从表中选择的每个列必须用于键表达式或聚合函数内,但不能同时使用。 +- `GROUP BY` 子句包含表达式列表(或单个表达式 -- 可以认为是长度为1的列表)。 这份名单充当 “grouping key”,而每个单独的表达式将被称为 “key expressions”. +- 在所有的表达式在 [SELECT](../../../sql-reference/statements/select/index.md), [HAVING](../../../sql-reference/statements/select/having.md),和 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 子句中 **必须** 基于键表达式进行计算 **或** 上 [聚合函数](../../../sql-reference/aggregate-functions/index.md) 在非键表达式(包括纯列)上。 换句话说,从表中选择的每个列必须用于键表达式或聚合函数内,但不能同时使用。 - 聚合结果 `SELECT` 查询将包含尽可能多的行,因为有唯一值 “grouping key” 在源表中。 通常这会显着减少行数,通常是数量级,但不一定:如果所有行数保持不变 “grouping key” 值是不同的。 !!! note "注" - 还有一种额外的方法可以在表上运行聚合。 如果查询仅在聚合函数中包含表列,则 `GROUP BY clause` 可以省略,并且通过一个空的键集合来假定聚合。 这样的查询总是只返回一行。 + 还有一种额外的方法可以在表上运行聚合。 如果查询仅在聚合函数中包含表列,则 `GROUP BY` 可以省略,并且通过一个空的键集合来假定聚合。 这样的查询总是只返回一行。 ## 空处理 {#null-processing} -对于分组,ClickHouse解释 [NULL](../../../sql-reference/syntax.md#null-literal) 作为一个值,并且 `NULL==NULL`. 它不同于 `NULL` 在大多数其他上下文中进行处理。 +对于分组,ClickHouse解释 [NULL](../../../sql-reference/syntax.md#null-literal) 作为一个值,并且 `NULL==NULL`. 它不同于 `NULL` 在大多数其他上下文中的处理方式。 这里有一个例子来说明这意味着什么。 -假设你有这张桌子: +假设你有一张表: ``` text ┌─x─┬────y─┐ @@ -47,20 +45,20 @@ toc_title: GROUP BY 如果你通过几个键 `GROUP BY`,结果会给你选择的所有组合,就好像 `NULL` 是一个特定的值。 -## 使用总计修饰符 {#with-totals-modifier} +## WITH TOTAL 修饰符 {#with-totals-modifier} -如果 `WITH TOTALS` 指定修饰符,将计算另一行。 此行将具有包含默认值(零或空行)的关键列,以及包含跨所有行计算值的聚合函数列( “total” 值)。 +如果 `WITH TOTALS` 被指定,将计算另一行。 此行将具有包含默认值(零或空行)的关键列,以及包含跨所有行计算值的聚合函数列( “total” 值)。 这个额外的行仅产生于 `JSON*`, `TabSeparated*`,和 `Pretty*` 格式,与其他行分开: -- 在 `JSON*` 格式,这一行是作为一个单独的输出 ‘totals’ 场。 +- 在 `JSON*` 格式,这一行是作为一个单独的输出 ‘totals’ 字段。 - 在 `TabSeparated*` 格式,该行位于主结果之后,前面有一个空行(在其他数据之后)。 - 在 `Pretty*` 格式时,该行在主结果之后作为单独的表输出。 - 在其他格式中,它不可用。 `WITH TOTALS` 可以以不同的方式运行时 [HAVING](../../../sql-reference/statements/select/having.md) 是存在的。 该行为取决于 `totals_mode` 设置。 -### 配置合计处理 {#configuring-totals-processing} +### 配置总和处理 {#configuring-totals-processing} 默认情况下, `totals_mode = 'before_having'`. 在这种情况下, ‘totals’ 是跨所有行计算,包括那些不通过具有和 `max_rows_to_group_by`. @@ -78,7 +76,7 @@ toc_title: GROUP BY 您可以使用 `WITH TOTALS` 在子查询中,包括在子查询 [JOIN](../../../sql-reference/statements/select/join.md) 子句(在这种情况下,将各自的总值合并)。 -## 例 {#examples} +## 例子 {#examples} 示例: @@ -90,7 +88,7 @@ SELECT FROM hits ``` -但是,与标准SQL相比,如果表没有任何行(根本没有任何行,或者在使用WHERE to filter之后没有任何行),则返回一个空结果,而不是来自包含聚合函数初始值的行之 +但是,与标准SQL相比,如果表没有任何行(根本没有任何行,或者使用 WHERE 过滤之后没有任何行),则返回一个空结果,而不是来自包含聚合函数初始值的行。 相对于MySQL(并且符合标准SQL),您无法获取不在键或聚合函数(常量表达式除外)中的某些列的某些值。 要解决此问题,您可以使用 ‘any’ 聚合函数(获取第一个遇到的值)或 ‘min/max’. @@ -111,9 +109,9 @@ GROUP BY domain 不能将常量指定为聚合函数的参数。 示例: `sum(1)`. 相反,你可以摆脱常数。 示例: `count()`. -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} -聚合是面向列的DBMS最重要的功能之一,因此它的实现是ClickHouse中最优化的部分之一。 默认情况下,聚合使用哈希表在内存中完成。 它有40+的专业化是自动选择取决于 “grouping key” 数据类型。 +聚合是面向列的 DBMS 最重要的功能之一,因此它的实现是ClickHouse中最优化的部分之一。 默认情况下,聚合使用哈希表在内存中完成。 它有 40+ 的特殊化自动选择取决于 “grouping key” 数据类型。 ### 在外部存储器中分组 {#select-group-by-in-external-memory} @@ -122,12 +120,12 @@ GROUP BY domain 使用时 `max_bytes_before_external_group_by`,我们建议您设置 `max_memory_usage` 大约两倍高。 这是必要的,因为聚合有两个阶段:读取数据和形成中间数据(1)和合并中间数据(2)。 将数据转储到文件系统只能在阶段1中发生。 如果未转储临时数据,则阶段2可能需要与阶段1相同的内存量。 -例如,如果 [max\_memory\_usage](../../../operations/settings/settings.md#settings_max_memory_usage) 设置为10000000000,你想使用外部聚合,这是有意义的设置 `max_bytes_before_external_group_by` 到10000000000,和 `max_memory_usage` 到200亿。 当触发外部聚合(如果至少有一个临时数据转储)时,RAM的最大消耗仅略高于 `max_bytes_before_external_group_by`. +例如,如果 [max\_memory\_usage](../../../operations/settings/settings.md#settings_max_memory_usage) 设置为10000000000,你想使用外部聚合,这是有意义的设置 `max_bytes_before_external_group_by` 到10000000000,和 `max_memory_usage` 到20000000000。 当触发外部聚合(如果至少有一个临时数据转储)时,RAM的最大消耗仅略高于 `max_bytes_before_external_group_by`. 通过分布式查询处理,在远程服务器上执行外部聚合。 为了使请求者服务器只使用少量的RAM,设置 `distributed_aggregation_memory_efficient` 到1。 当合并数据刷新到磁盘时,以及当合并来自远程服务器的结果时, `distributed_aggregation_memory_efficient` 设置被启用,消耗高达 `1/256 * the_number_of_threads` 从RAM的总量。 -当启用外部聚合时,如果有小于 `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). +当启用外部聚合时,如果数据量小于 `max_bytes_before_external_group_by` (例如数据没有被 flushed), 查询执行速度和不在外部聚合的速度一样快. 如果临时数据被flushed到外部存储, 执行的速度会慢几倍 (大概是三倍). 如果你有一个 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 用一个 [LIMIT](../../../sql-reference/statements/select/limit.md) 后 `GROUP BY`,然后使用的RAM的量取决于数据的量 `LIMIT`,不是在整个表。 但如果 `ORDER BY` 没有 `LIMIT`,不要忘记启用外部排序 (`max_bytes_before_external_sort`). diff --git a/docs/zh/sql-reference/statements/select/having.md b/docs/zh/sql-reference/statements/select/having.md index d5c5b96a280..de9b5b45637 100644 --- a/docs/zh/sql-reference/statements/select/having.md +++ b/docs/zh/sql-reference/statements/select/having.md @@ -1,15 +1,13 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: HAVING --- -# 有条款 {#having-clause} +# HAVING 子句 {#having-clause} -允许过滤由以下方式生成的聚合结果 [GROUP BY](../../../sql-reference/statements/select/group-by.md). 它类似于 [WHERE](../../../sql-reference/statements/select/where.md) 条款,但不同的是 `WHERE` 在聚合之前执行,而 `HAVING` 之后进行。 +允许过滤由 [GROUP BY](../../../sql-reference/statements/select/group-by.md) 生成的聚合结果. 它类似于 [WHERE](../../../sql-reference/statements/select/where.md) ,但不同的是 `WHERE` 在聚合之前执行,而 `HAVING` 之后进行。 -可以从以下引用聚合结果 `SELECT` 中的条款 `HAVING` 子句由他们的化名。 或者, `HAVING` 子句可以筛选查询结果中未返回的其他聚合的结果。 +可以从 `SELECT` 生成的聚合结果中通过他们的别名来执行 `HAVING` 子句。 或者 `HAVING` 子句可以筛选查询结果中未返回的其他聚合的结果。 ## 限制 {#limitations} -`HAVING` 如果不执行聚合,则无法使用。 使用 `WHERE` 相反。 +`HAVING` 如果不执行聚合则无法使用。 使用 `WHERE` 则相反。 diff --git a/docs/zh/sql-reference/statements/select/index.md b/docs/zh/sql-reference/statements/select/index.md index c246f37481c..cdfd64ff190 100644 --- a/docs/zh/sql-reference/statements/select/index.md +++ b/docs/zh/sql-reference/statements/select/index.md @@ -1,15 +1,13 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 title: SELECT Query toc_folder_title: SELECT toc_priority: 33 -toc_title: "\u6982\u8FF0" +toc_title: 综述 --- # 选择查询 {#select-queries-syntax} -`SELECT` 查询执行数据检索。 默认情况下,请求的数据返回给客户端,同时与 [INSERT INTO](../../../sql-reference/statements/insert-into.md) 它可以被转发到不同的表。 +`SELECT` 查询执行数据检索。 默认情况下,请求的数据返回给客户端,同时结合 [INSERT INTO](../../../sql-reference/statements/insert-into.md) 可以被转发到不同的表。 ## 语法 {#syntax} @@ -32,45 +30,45 @@ SELECT [DISTINCT] expr_list [FORMAT format] ``` -所有子句都是可选的,但紧接在后面的必需表达式列表除外 `SELECT` 这是更详细的复盖 [下面](#select-clause). +所有子句都是可选的,但紧接在 `SELECT` 后面的必需表达式列表除外,更详细的请看 [下面](#select-clause). -每个可选子句的具体内容在单独的部分中进行了介绍,这些部分按与执行顺序相同的顺序列出: +每个可选子句的具体内容在单独的部分中进行介绍,这些部分按与执行顺序相同的顺序列出: -- [WITH条款](../../../sql-reference/statements/select/with.md) -- [FROM条款](../../../sql-reference/statements/select/from.md) -- [示例子句](../../../sql-reference/statements/select/sample.md) -- [JOIN子句](../../../sql-reference/statements/select/join.md) -- [PREWHERE条款](../../../sql-reference/statements/select/prewhere.md) -- [WHERE条款](../../../sql-reference/statements/select/where.md) -- [GROUP BY子句](../../../sql-reference/statements/select/group-by.md) -- [限制条款](../../../sql-reference/statements/select/limit-by.md) -- [有条款](../../../sql-reference/statements/select/having.md) -- [SELECT子句](#select-clause) -- [DISTINCT子句](../../../sql-reference/statements/select/distinct.md) -- [限制条款](../../../sql-reference/statements/select/limit.md) -- [UNION ALL条款](../../../sql-reference/statements/select/union-all.md) -- [INTO OUTFILE条款](../../../sql-reference/statements/select/into-outfile.md) -- [格式子句](../../../sql-reference/statements/select/format.md) +- [WITH 子句](../../../sql-reference/statements/select/with.md) +- [FROM 子句](../../../sql-reference/statements/select/from.md) +- [SAMPLE 子句](../../../sql-reference/statements/select/sample.md) +- [JOIN 子句](../../../sql-reference/statements/select/join.md) +- [PREWHERE 子句](../../../sql-reference/statements/select/prewhere.md) +- [WHERE 子句](../../../sql-reference/statements/select/where.md) +- [GROUP BY 子句](../../../sql-reference/statements/select/group-by.md) +- [LIMIT BY 子句](../../../sql-reference/statements/select/limit-by.md) +- [HAVING 子句](../../../sql-reference/statements/select/having.md) +- [SELECT 子句](#select-clause) +- [DISTINCT 子句](../../../sql-reference/statements/select/distinct.md) +- [LIMIT 子句](../../../sql-reference/statements/select/limit.md) +- [UNION ALL 子句](../../../sql-reference/statements/select/union-all.md) +- [INTO OUTFILE 子句](../../../sql-reference/statements/select/into-outfile.md) +- [FORMAT 子句](../../../sql-reference/statements/select/format.md) -## SELECT子句 {#select-clause} +## SELECT 子句 {#select-clause} -[表达式](../../../sql-reference/syntax.md#syntax-expressions) 在指定 `SELECT` 子句是在上述子句中的所有操作完成后计算的。 这些表达式的工作方式就好像它们应用于结果中的单独行一样。 如果在表达式 `SELECT` 子句包含聚合函数,然后ClickHouse处理过程中用作其参数的聚合函数和表达式 [GROUP BY](../../../sql-reference/statements/select/group-by.md) 聚合。 +[表达式](../../../sql-reference/syntax.md#syntax-expressions) 指定 `SELECT` 子句是在上述子句中的所有操作完成后计算的。 这些表达式的工作方式就好像它们应用于结果中的单独行一样。 如果表达式 `SELECT` 子句包含聚合函数,然后ClickHouse将使用 [GROUP BY](../../../sql-reference/statements/select/group-by.md) 聚合参数应用在聚合函数和表达式上。 -如果要在结果中包含所有列,请使用星号 (`*`)符号。 例如, `SELECT * FROM ...`. +如果在结果中包含所有列,请使用星号 (`*`)符号。 例如, `SELECT * FROM ...`. -将结果中的某些列与 [re2](https://en.wikipedia.org/wiki/RE2_(software)) 正则表达式,您可以使用 `COLUMNS` 表达。 +将结果中的某些列与 [re2](https://en.wikipedia.org/wiki/RE2_(software)) 正则表达式匹配,可以使用 `COLUMNS` 表达。 ``` sql COLUMNS('regexp') ``` -例如,考虑表: +例如表: ``` sql CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog ``` -以下查询从包含以下内容的所有列中选择数据 `a` 在他们的名字符号。 +以下查询所有列名包含 `a` 。 ``` sql SELECT COLUMNS('a') FROM col_names @@ -84,7 +82,7 @@ SELECT COLUMNS('a') FROM col_names 所选列不按字母顺序返回。 -您可以使用多个 `COLUMNS` 查询中的表达式并将函数应用于它们。 +您可以使用多个 `COLUMNS` 表达式并将函数应用于它们。 例如: @@ -98,7 +96,7 @@ SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names └────┴────┴────┴────────────────┘ ``` -由返回的每一列 `COLUMNS` 表达式作为单独的参数传递给函数。 如果函数支持其他参数,您也可以将其他参数传递给函数。 使用函数时要小心。 如果函数不支持您传递给它的参数数,ClickHouse将引发异常。 +返回的每一列 `COLUMNS` 表达式作为单独的参数传递给函数。 如果函数支持其他参数,您也可以将其他参数传递给函数。 使用函数时要小心,如果函数不支持传递给它的参数,ClickHouse将抛出异常。 例如: @@ -111,41 +109,41 @@ Received exception from server (version 19.14.1): Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. ``` -在这个例子中, `COLUMNS('a')` 返回两列: `aa` 和 `ab`. `COLUMNS('c')` 返回 `bc` 列。 该 `+` 运算符不能应用于3个参数,因此ClickHouse引发一个带有相关消息的异常。 +该例子中, `COLUMNS('a')` 返回两列: `aa` 和 `ab`. `COLUMNS('c')` 返回 `bc` 列。 该 `+` 运算符不能应用于3个参数,因此ClickHouse抛出一个带有相关消息的异常。 -匹配的列 `COLUMNS` 表达式可以具有不同的数据类型。 如果 `COLUMNS` 不匹配任何列,并且是唯一的表达式 `SELECT`,ClickHouse抛出异常。 +匹配的列 `COLUMNS` 表达式可以具有不同的数据类型。 如果 `COLUMNS` 不匹配任何列,并且是在 `SELECT` 唯一的表达式,ClickHouse则抛出异常。 ### 星号 {#asterisk} -您可以在查询的任何部分而不是表达式中添加星号。 分析查询时,星号将展开为所有表列的列表(不包括 `MATERIALIZED` 和 `ALIAS` 列)。 只有少数情况下使用星号是合理的: +您可以在查询的任何部分使用星号替代表达式。进行查询分析、时,星号将展开为所有表的列(不包括 `MATERIALIZED` 和 `ALIAS` 列)。 只有少数情况下使用星号是合理的: -- 创建表转储时。 +- 创建转储表时。 - 对于只包含几列的表,例如系统表。 -- 获取有关表中哪些列的信息。 在这种情况下,设置 `LIMIT 1`. 但最好使用 `DESC TABLE` 查询。 -- 当对少量柱进行强过滤时,使用 `PREWHERE`. +- 获取表中列的信息。 在这种情况下,设置 `LIMIT 1`. 但最好使用 `DESC TABLE` 查询。 +- 当对少量列使用 `PREWHERE` 进行强过滤时。 - 在子查询中(因为外部查询不需要的列从子查询中排除)。 在所有其他情况下,我们不建议使用星号,因为它只给你一个列DBMS的缺点,而不是优点。 换句话说,不建议使用星号。 ### 极端值 {#extreme-values} -除了结果之外,还可以获取结果列的最小值和最大值。 要做到这一点,设置 **极端** 设置为1。 最小值和最大值是针对数字类型、日期和带有时间的日期计算的。 对于其他列,默认值为输出。 +除结果之外,还可以获取结果列的最小值和最大值。 要做到这一点,设置 **extremes** 设置为1。 最小值和最大值是针对数字类型、日期和带有时间的日期计算的。 对于其他类型列,输出默认值。 -An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`,和 `Pretty*` [格式](../../../interfaces/formats.md),与其他行分开。 它们不是其他格式的输出。 +分别的额外计算两行 – 最小值和最大值。 这额外的两行采用输出格式为 `JSON*`, `TabSeparated*`,和 `Pretty*` [formats](../../../interfaces/formats.md),与其他行分开。 它们不以其他格式输出。 -在 `JSON*` 格式时,极端值在一个单独的输出 ‘extremes’ 场。 在 `TabSeparated*` 格式中,该行来的主要结果之后,和之后 ‘totals’ 如果存在。 它前面有一个空行(在其他数据之后)。 在 `Pretty*` 格式中,该行被输出为一个单独的表之后的主结果,和之后 `totals` 如果存在。 +为 `JSON*` 格式时,极端值单独的输出在 ‘extremes’ 字段。 为 `TabSeparated*` 格式时,此行来的主要结果集后,然后显示 ‘totals’ 字段。 它前面有一个空行(在其他数据之后)。 在 `Pretty*` 格式时,该行在主结果之后输出为一个单独的表,然后显示 ‘totals’ 字段。 -极值计算之前的行 `LIMIT`,但之后 `LIMIT BY`. 但是,使用时 `LIMIT offset, size`,之前的行 `offset` 都包含在 `extremes`. 在流请求中,结果还可能包括少量通过的行 `LIMIT`. +极端值在 `LIMIT` 之前被计算,但在 `LIMIT BY` 之后被计算. 然而,使用 `LIMIT offset, size`, `offset` 之前的行都包含在 `extremes`. 在流请求中,结果还可能包括少量通过 `LIMIT` 过滤的行. -### 注 {#notes} +### 备注 {#notes} -您可以使用同义词 (`AS` 别名)在查询的任何部分。 +您可以在查询的任何部分使用同义词 (`AS` 别名)。 -该 `GROUP BY` 和 `ORDER BY` 子句不支持位置参数。 这与MySQL相矛盾,但符合标准SQL。 例如, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). + `GROUP BY` 和 `ORDER BY` 子句不支持位置参数。 这与MySQL相矛盾,但符合标准SQL。 例如, `GROUP BY 1, 2` 将被理解为根据常量分组 (i.e. aggregation of all rows into one). -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} -如果查询省略 `DISTINCT`, `GROUP BY` 和 `ORDER BY` 条款和 `IN` 和 `JOIN` 子查询,查询将被完全流处理,使用O(1)量的RAM。 否则,如果未指定适当的限制,则查询可能会消耗大量RAM: +如果查询省略 `DISTINCT`, `GROUP BY` , `ORDER BY` , `IN` , `JOIN` 子查询,查询将被完全流处理,使用O(1)量的RAM。 若未指定适当的限制,则查询可能会消耗大量RAM: - `max_memory_usage` - `max_rows_to_group_by` diff --git a/docs/zh/sql-reference/statements/select/into-outfile.md b/docs/zh/sql-reference/statements/select/into-outfile.md index f1eb3e55b89..06ba2329d71 100644 --- a/docs/zh/sql-reference/statements/select/into-outfile.md +++ b/docs/zh/sql-reference/statements/select/into-outfile.md @@ -1,15 +1,13 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: INTO OUTFILE --- -# INTO OUTFILE条款 {#into-outfile-clause} +# INTO OUTFILE 子句 {#into-outfile-clause} -添加 `INTO OUTFILE filename` 子句(其中filename是字符串文字) `SELECT query` 将其输出重定向到客户端上的指定文件。 +添加 `INTO OUTFILE filename` 子句(其中filename是字符串) `SELECT query` 将其输出重定向到客户端上的指定文件。 -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} -- 此功能是在可用 [命令行客户端](../../../interfaces/cli.md) 和 [ツ环板-ョツ嘉ッツ偲](../../../operations/utilities/clickhouse-local.md). 因此,通过发送查询 [HTTP接口](../../../interfaces/http.md) 都会失败 +- 此功能是在可用 [命令行客户端](../../../interfaces/cli.md) 和 [clickhouse-local](../../../operations/utilities/clickhouse-local.md). 因此通过 [HTTP接口](../../../interfaces/http.md) 发送查询将会失败。 - 如果具有相同文件名的文件已经存在,则查询将失败。 - 默认值 [输出格式](../../../interfaces/formats.md) 是 `TabSeparated` (就像在命令行客户端批处理模式中一样)。 diff --git a/docs/zh/sql-reference/statements/select/join.md b/docs/zh/sql-reference/statements/select/join.md index 355ed0e617c..48395933665 100644 --- a/docs/zh/sql-reference/statements/select/join.md +++ b/docs/zh/sql-reference/statements/select/join.md @@ -1,6 +1,4 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: JOIN --- @@ -29,7 +27,7 @@ FROM - `FULL OUTER JOIN`,除了匹配的行之外,还会返回两个表中的非匹配行。 - `CROSS JOIN`,产生整个表的笛卡尔积, “join keys” 是 **不** 指定。 -`JOIN` 没有指定类型暗示 `INNER`. 关键字 `OUTER` 可以安全地省略。 替代语法 `CROSS JOIN` 在指定多个表 [FROM条款](../../../sql-reference/statements/select/from.md) 用逗号分隔。 +`JOIN` 没有指定类型暗指 `INNER`. 关键字 `OUTER` 可以安全地省略。 替代语法 `CROSS JOIN` 在指定多个表 [FROM](../../../sql-reference/statements/select/from.md) 用逗号分隔。 ClickHouse中提供的其他联接类型: @@ -53,7 +51,7 @@ ClickHouse中提供的其他联接类型: - 必须包含有序序列。 - 可以是以下类型之一: [Int*,UInt*](../../../sql-reference/data-types/int-uint.md), [浮动\*](../../../sql-reference/data-types/float.md), [日期](../../../sql-reference/data-types/date.md), [日期时间](../../../sql-reference/data-types/datetime.md), [十进制\*](../../../sql-reference/data-types/decimal.md). -- 不能是唯一的列 `JOIN` 条款 +- 不能是唯一的列 `JOIN` 语法 `ASOF JOIN ... ON`: @@ -150,7 +148,7 @@ USING (equi_column1, ... equi_columnN, asof_column) 当任何这些限制达到,ClickHouse作为 [join\_overflow\_mode](../../../operations/settings/query-complexity.md#settings-join_overflow_mode) 设置指示。 -## 例 {#examples} +## 例子 {#examples} 示例: diff --git a/docs/zh/sql-reference/statements/select/limit-by.md b/docs/zh/sql-reference/statements/select/limit-by.md index ae2bd491817..f5ed5b1bf98 100644 --- a/docs/zh/sql-reference/statements/select/limit-by.md +++ b/docs/zh/sql-reference/statements/select/limit-by.md @@ -1,12 +1,10 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: LIMIT BY --- -# 限制条款 {#limit-by-clause} +# LIMIT BY子句 {#limit-by-clause} -与查询 `LIMIT n BY expressions` 子句选择第一个 `n` 每个不同值的行 `expressions`. 的关键 `LIMIT BY` 可以包含任意数量的 [表达式](../../../sql-reference/syntax.md#syntax-expressions). +与查询 `LIMIT n BY expressions` 子句选择第一个 `n` 每个不同值的行 `expressions`. `LIMIT BY` 可以包含任意数量的 [表达式](../../../sql-reference/syntax.md#syntax-expressions). ClickHouse支持以下语法变体: @@ -20,7 +18,7 @@ ClickHouse支持以下语法变体: ## 例 {#examples} -样品表: +样例表: ``` sql CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; diff --git a/docs/zh/sql-reference/statements/select/limit.md b/docs/zh/sql-reference/statements/select/limit.md index 4d02df88600..b079248deca 100644 --- a/docs/zh/sql-reference/statements/select/limit.md +++ b/docs/zh/sql-reference/statements/select/limit.md @@ -1,15 +1,62 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: LIMIT --- -# 限制条款 {#limit-clause} +# LIMIT {#limit-clause} -`LIMIT m` 允许选择第一个 `m` 结果中的行。 +`LIMIT m` 允许选择结果中起始的 `m` 行。 -`LIMIT n, m` 允许选择 `m` 跳过第一个结果后的行 `n` 行。 该 `LIMIT m OFFSET n` 语法是等效的。 +`LIMIT n, m` 允许选择个 `m` 从跳过第一个结果后的行 `n` 行。 与 `LIMIT m OFFSET n` 语法是等效的。 `n` 和 `m` 必须是非负整数。 如果没有 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 子句显式排序结果,结果的行选择可能是任意的和非确定性的。 + +## LIMIT … WITH TIES 修饰符 {#limit-with-ties} + +如果为 `LIMIT n[,m]` 设置了 `WITH TIES` ,并且声明了 `ORDER BY expr_list`, you will get in result first `n` or `n,m` rows and all rows with same `ORDER BY` fields values equal to row at position `n` for `LIMIT n` and `m` for `LIMIT n,m`. + +此修饰符可以与: [ORDER BY … WITH FILL modifier](../../../sql-reference/statements/select/order-by.md#orderby-with-fill) 组合使用. + +例如以下查询: + +``` sql +SELECT * FROM ( + SELECT number%50 AS n FROM numbers(100) +) ORDER BY n LIMIT 0,5 +``` + +返回 + +``` text +┌─n─┐ +│ 0 │ +│ 0 │ +│ 1 │ +│ 1 │ +│ 2 │ +└───┘ +``` + +单子执行了 `WITH TIES` 修饰符后 + +``` sql +SELECT * FROM ( + SELECT number%50 AS n FROM numbers(100) +) ORDER BY n LIMIT 0,5 WITH TIES +``` + +则返回了以下的数据行 + +``` text +┌─n─┐ +│ 0 │ +│ 0 │ +│ 1 │ +│ 1 │ +│ 2 │ +│ 2 │ +└───┘ +``` + +cause row number 6 have same value “2” for field `n` as row number 5 diff --git a/docs/zh/sql-reference/statements/select/order-by.md b/docs/zh/sql-reference/statements/select/order-by.md index e853a788075..a67911bdf27 100644 --- a/docs/zh/sql-reference/statements/select/order-by.md +++ b/docs/zh/sql-reference/statements/select/order-by.md @@ -1,12 +1,10 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: ORDER BY --- -# 按条款订购 {#select-order-by} +# ORDER BY {#select-order-by} -该 `ORDER BY` 子句包含一个表达式列表,每个表达式都可以用 `DESC` (降序)或 `ASC` (升序)修饰符确定排序方向。 如果未指定方向, `ASC` 假设,所以它通常被省略。 排序方向适用于单个表达式,而不适用于整个列表。 示例: `ORDER BY Visits DESC, SearchPhrase` +`ORDER BY` 子句包含一个表达式列表,每个表达式都可以用 `DESC` (降序)或 `ASC` (升序)修饰符确定排序方向。 如果未指定方向, 默认是 `ASC` ,所以它通常被省略。 排序方向适用于单个表达式,而不适用于整个列表。 示例: `ORDER BY Visits DESC, SearchPhrase` 对于排序表达式列表具有相同值的行以任意顺序输出,也可以是非确定性的(每次都不同)。 如果省略ORDER BY子句,则行的顺序也是未定义的,并且可能也是非确定性的。 @@ -62,12 +60,145 @@ toc_title: ORDER BY 我们只建议使用 `COLLATE` 对于少量行的最终排序,因为排序与 `COLLATE` 比正常的按字节排序效率低。 -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} 更少的RAM使用,如果一个足够小 [LIMIT](../../../sql-reference/statements/select/limit.md) 除了指定 `ORDER BY`. 否则,所花费的内存量与用于排序的数据量成正比。 对于分布式查询处理,如果 [GROUP BY](../../../sql-reference/statements/select/group-by.md) 省略排序,在远程服务器上部分完成排序,并将结果合并到请求者服务器上。 这意味着对于分布式排序,要排序的数据量可以大于单个服务器上的内存量。 如果没有足够的RAM,则可以在外部存储器中执行排序(在磁盘上创建临时文件)。 使用设置 `max_bytes_before_external_sort` 为此目的。 如果将其设置为0(默认值),则禁用外部排序。 如果启用,则当要排序的数据量达到指定的字节数时,将对收集的数据进行排序并转储到临时文件中。 读取所有数据后,将合并所有已排序的文件并输出结果。 文件被写入到 `/var/lib/clickhouse/tmp/` 目录中的配置(默认情况下,但你可以使用 `tmp_path` 参数来更改此设置)。 -运行查询可能占用的内存比 `max_bytes_before_external_sort`. 因此,此设置的值必须大大小于 `max_memory_usage`. 例如,如果您的服务器有128GB的RAM,并且您需要运行单个查询,请设置 `max_memory_usage` 到100GB,和 `max_bytes_before_external_sort` 至80GB。 +运行查询可能占用的内存比 `max_bytes_before_external_sort` 大. 因此,此设置的值必须大大小于 `max_memory_usage`. 例如,如果您的服务器有128GB的RAM,并且您需要运行单个查询,请设置 `max_memory_usage` 到100GB,和 `max_bytes_before_external_sort` 至80GB。 外部排序的工作效率远远低于在RAM中进行排序。 + +## ORDER BY Expr WITH FILL Modifier {#orderby-with-fill} + +此修饰符可以与 [LIMIT … WITH TIES modifier](../../../sql-reference/statements/select/limit.md#limit-with-ties) 进行组合使用. + +可以在`ORDER BY expr`之后用可选的`FROM expr`,`TO expr`和`STEP expr`参数来设置`WITH FILL`修饰符。 +所有`expr`列的缺失值将被顺序填充,而其他列将被填充为默认值。 + +使用以下语法填充多列,在ORDER BY部分的每个字段名称后添加带有可选参数的WITH FILL修饰符。 + +``` sql +ORDER BY expr [WITH FILL] [FROM const_expr] [TO const_expr] [STEP const_numeric_expr], ... exprN [WITH FILL] [FROM expr] [TO expr] [STEP numeric_expr] +``` + +`WITH FILL` 仅适用于具有数字(所有类型的浮点,小数,整数)或日期/日期时间类型的字段。 +当未定义 `FROM const_expr` 填充顺序时,则使用 `ORDER BY` 中的最小 `expr` 字段值。 +如果未定义 `TO const_expr` 填充顺序,则使用 `ORDER BY` 中的最大`expr`字段值。 +当定义了 `STEP const_numeric_expr` 时,对于数字类型,`const_numeric_expr` 将 `as is` 解释为 `days` 作为日期类型,将 `seconds` 解释为DateTime类型。 +如果省略了 `STEP const_numeric_expr`,则填充顺序使用 `1.0` 表示数字类型,`1 day`表示日期类型,`1 second` 表示日期时间类型。 + +例如下面的查询: + +``` sql +SELECT n, source FROM ( + SELECT toFloat32(number % 10) AS n, 'original' AS source + FROM numbers(10) WHERE number % 3 = 1 +) ORDER BY n +``` + +返回 + +``` text +┌─n─┬─source───┐ +│ 1 │ original │ +│ 4 │ original │ +│ 7 │ original │ +└───┴──────────┘ +``` + +但是如果配置了 `WITH FILL` 修饰符 + +``` sql +SELECT n, source FROM ( + SELECT toFloat32(number % 10) AS n, 'original' AS source + FROM numbers(10) WHERE number % 3 = 1 +) ORDER BY n WITH FILL FROM 0 TO 5.51 STEP 0.5 +``` + +返回 + +``` text +┌───n─┬─source───┐ +│ 0 │ │ +│ 0.5 │ │ +│ 1 │ original │ +│ 1.5 │ │ +│ 2 │ │ +│ 2.5 │ │ +│ 3 │ │ +│ 3.5 │ │ +│ 4 │ original │ +│ 4.5 │ │ +│ 5 │ │ +│ 5.5 │ │ +│ 7 │ original │ +└─────┴──────────┘ +``` + +For the case when we have multiple fields `ORDER BY field2 WITH FILL, field1 WITH FILL` order of filling will follow the order of fields in `ORDER BY` clause. +对于我们有多个字段 `ORDER BY field2 WITH FILL, field1 WITH FILL ` 的情况,填充顺序将遵循` ORDER BY`子句中字段的顺序。 + +示例: + +``` sql +SELECT + toDate((number * 10) * 86400) AS d1, + toDate(number * 86400) AS d2, + 'original' AS source +FROM numbers(10) +WHERE (number % 3) = 1 +ORDER BY + d2 WITH FILL, + d1 WITH FILL STEP 5; +``` + +返回 + +``` text +┌───d1───────┬───d2───────┬─source───┐ +│ 1970-01-11 │ 1970-01-02 │ original │ +│ 1970-01-01 │ 1970-01-03 │ │ +│ 1970-01-01 │ 1970-01-04 │ │ +│ 1970-02-10 │ 1970-01-05 │ original │ +│ 1970-01-01 │ 1970-01-06 │ │ +│ 1970-01-01 │ 1970-01-07 │ │ +│ 1970-03-12 │ 1970-01-08 │ original │ +└────────────┴────────────┴──────────┘ +``` + +字段 `d1` 没有填充并使用默认值,因为我们没有 `d2` 值的重复值,并且无法正确计算 `d1` 的顺序。 +以下查询中`ORDER BY` 中的字段将被更改 + +``` sql +SELECT + toDate((number * 10) * 86400) AS d1, + toDate(number * 86400) AS d2, + 'original' AS source +FROM numbers(10) +WHERE (number % 3) = 1 +ORDER BY + d1 WITH FILL STEP 5, + d2 WITH FILL; +``` + +返回 + +``` text +┌───d1───────┬───d2───────┬─source───┐ +│ 1970-01-11 │ 1970-01-02 │ original │ +│ 1970-01-16 │ 1970-01-01 │ │ +│ 1970-01-21 │ 1970-01-01 │ │ +│ 1970-01-26 │ 1970-01-01 │ │ +│ 1970-01-31 │ 1970-01-01 │ │ +│ 1970-02-05 │ 1970-01-01 │ │ +│ 1970-02-10 │ 1970-01-05 │ original │ +│ 1970-02-15 │ 1970-01-01 │ │ +│ 1970-02-20 │ 1970-01-01 │ │ +│ 1970-02-25 │ 1970-01-01 │ │ +│ 1970-03-02 │ 1970-01-01 │ │ +│ 1970-03-07 │ 1970-01-01 │ │ +│ 1970-03-12 │ 1970-01-08 │ original │ +└────────────┴────────────┴──────────┘ +``` diff --git a/docs/zh/sql-reference/statements/select/prewhere.md b/docs/zh/sql-reference/statements/select/prewhere.md index ec6607d4ecc..e2b2d911577 100644 --- a/docs/zh/sql-reference/statements/select/prewhere.md +++ b/docs/zh/sql-reference/statements/select/prewhere.md @@ -1,18 +1,16 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: PREWHERE --- -# PREWHERE条款 {#prewhere-clause} +# PREWHERE 子句 {#prewhere-clause} -Prewhere是更有效地应用过滤的优化。 默认情况下,即使在 `PREWHERE` 子句未显式指定。 它的工作原理是自动移动的一部分 [WHERE](../../../sql-reference/statements/select/where.md) 条件到prewhere阶段。 的作用 `PREWHERE` 子句只是控制这个优化,如果你认为你知道如何做得比默认情况下更好。 +Prewhere是更有效地进行过滤的优化。 默认情况下,即使在 `PREWHERE` 子句未显式指定。 它也会自动移动 [WHERE](../../../sql-reference/statements/select/where.md) 条件到prewhere阶段。 `PREWHERE` 子句只是控制这个优化,如果你认为你知道如何做得比默认情况下更好才去控制它。 使用prewhere优化,首先只读取执行prewhere表达式所需的列。 然后读取运行其余查询所需的其他列,但只读取prewhere表达式所在的那些块 “true” 至少对于一些行。 如果有很多块,其中prewhere表达式是 “false” 对于所有行和prewhere需要比查询的其他部分更少的列,这通常允许从磁盘读取更少的数据以执行查询。 ## 手动控制Prewhere {#controlling-prewhere-manually} -该条款具有相同的含义 `WHERE` 条款 区别在于从表中读取数据。 当手动控制 `PREWHERE` 对于查询中的少数列使用的过滤条件,但这些过滤条件提供了强大的数据过滤。 这减少了要读取的数据量。 +该子句具有与 `WHERE` 相同的含义,区别在于从表中读取数据。 当手动控制 `PREWHERE` 对于查询中的少数列使用的过滤条件,但这些过滤条件提供了强大的数据过滤。 这减少了要读取的数据量。 查询可以同时指定 `PREWHERE` 和 `WHERE`. 在这种情况下, `PREWHERE` 先于 `WHERE`. @@ -20,4 +18,4 @@ Prewhere是更有效地应用过滤的优化。 默认情况下,即使在 `PRE ## 限制 {#limitations} -`PREWHERE` 只有从表支持 `*MergeTree` 家人 +`PREWHERE` 只有支持 `*MergeTree` 族系列引擎的表。 diff --git a/docs/zh/sql-reference/statements/select/sample.md b/docs/zh/sql-reference/statements/select/sample.md index 9b760601959..a2cff2200c3 100644 --- a/docs/zh/sql-reference/statements/select/sample.md +++ b/docs/zh/sql-reference/statements/select/sample.md @@ -1,37 +1,35 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: SAMPLE --- -# 示例子句 {#select-sample-clause} +# 采样子句 {#select-sample-clause} -该 `SAMPLE` 子句允许近似 `SELECT` 查询处理。 +该 `SAMPLE` 子句允许近似于 `SELECT` 查询处理。 启用数据采样时,不会对所有数据执行查询,而只对特定部分数据(样本)执行查询。 例如,如果您需要计算所有访问的统计信息,只需对所有访问的1/10分数执行查询,然后将结果乘以10即可。 近似查询处理在以下情况下可能很有用: -- 当你有严格的时间requirements(如\<100ms),但你不能证明额外的硬件资源来满足他们的成本。 +- 当你有严格的时间需求(如\<100ms),但你不能通过额外的硬件资源来满足他们的成本。 - 当您的原始数据不准确时,所以近似不会明显降低质量。 - 业务需求的目标是近似结果(为了成本效益,或者向高级用户推销确切结果)。 !!! note "注" - 您只能使用采样中的表 [MergeTree](../../../engines/table-engines/mergetree-family/mergetree.md) 家庭,并且只有在表创建过程中指定了采样表达式(请参阅 [MergeTree引擎](../../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table)). + 您只能使用采样中的表 [MergeTree](../../../engines/table-engines/mergetree-family/mergetree.md) 族,并且只有在表创建过程中指定了采样表达式(请参阅 [MergeTree引擎](../../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table)). 下面列出了数据采样的功能: - 数据采样是一种确定性机制。 同样的结果 `SELECT .. SAMPLE` 查询始终是相同的。 -- 对于不同的表,采样工作始终如一。 对于具有单个采样键的表,具有相同系数的采样总是选择相同的可能数据子集。 例如,用户Id的示例采用来自不同表的所有可能的用户Id的相同子集的行。 这意味着您可以在子查询中使用示例 [IN](../../../sql-reference/operators/in.md) 条款 此外,您可以使用 [JOIN](../../../sql-reference/statements/select/join.md) 条款 +- 对于不同的表,采样工作始终如一。 对于具有单个采样键的表,具有相同系数的采样总是选择相同的可能数据子集。 例如,用户Id的示例采用来自不同表的所有可能的用户Id的相同子集的行。 这意味着您可以在子查询中使用采样 [IN](../../../sql-reference/operators/in.md) 此外,您可以使用 [JOIN](../../../sql-reference/statements/select/join.md) 。 - 采样允许从磁盘读取更少的数据。 请注意,您必须正确指定采样键。 有关详细信息,请参阅 [创建MergeTree表](../../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table). 为 `SAMPLE` 子句支持以下语法: | SAMPLE Clause Syntax | 产品描述 | |----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `SAMPLE k` | 这里 `k` 是从0到1的数字。
查询执行于 `k` 数据的分数。 例如, `SAMPLE 0.1` 对10%的数据运行查询。 [碌莽禄more拢more](#select-sample-k) | -| `SAMPLE n` | 这里 `n` 是足够大的整数。
该查询是在至少一个样本上执行的 `n` 行(但不超过这个)。 例如, `SAMPLE 10000000` 在至少10,000,000行上运行查询。 [碌莽禄more拢more](#select-sample-n) | -| `SAMPLE k OFFSET m` | 这里 `k` 和 `m` 是从0到1的数字。
查询在以下示例上执行 `k` 数据的分数。 用于采样的数据由以下偏移 `m` 分数。 [碌莽禄more拢more](#select-sample-offset) | +| `SAMPLE k` | 这里 `k` 是从0到1的数字。
查询执行于 `k` 数据的分数。 例如, `SAMPLE 0.1` 对10%的数据运行查询。 [Read more](#select-sample-k) | +| `SAMPLE n` | 这里 `n` 是足够大的整数。
该查询是在至少一个样本上执行的 `n` 行(但不超过这个)。 例如, `SAMPLE 10000000` 在至少10,000,000行上运行查询。 [Read more](#select-sample-n) | +| `SAMPLE k OFFSET m` | 这里 `k` 和 `m` 是从0到1的数字。
查询在以下示例上执行 `k` 数据的分数。 用于采样的数据由以下偏移 `m` 分数。 [Read more](#select-sample-offset) | ## SAMPLE K {#select-sample-k} diff --git a/docs/zh/sql-reference/statements/select/union-all.md b/docs/zh/sql-reference/statements/select/union-all.md index a04996bc0a6..d32ae896f55 100644 --- a/docs/zh/sql-reference/statements/select/union-all.md +++ b/docs/zh/sql-reference/statements/select/union-all.md @@ -1,12 +1,10 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: UNION ALL --- -# UNION ALL条款 {#union-all-clause} +# UNION ALL子句 {#union-all-clause} -您可以使用 `UNION ALL` 结合任意数量的 `SELECT` 通过扩展其结果进行查询。 示例: +你可以使用 `UNION ALL` 结合任意数量的 `SELECT` 来扩展其结果。 示例: ``` sql SELECT CounterID, 1 AS table, toInt64(count()) AS c @@ -25,12 +23,12 @@ SELECT CounterID, 2 AS table, sum(Sign) AS c 对联合执行类型转换。 例如,如果合并的两个查询具有相同的字段与非-`Nullable` 和 `Nullable` 从兼容类型的类型,由此产生的 `UNION ALL` 有一个 `Nullable` 类型字段。 -属于以下部分的查询 `UNION ALL` 不能用圆括号括起来。 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 和 [LIMIT](../../../sql-reference/statements/select/limit.md) 应用于单独的查询,而不是最终结果。 如果您需要将转换应用于最终结果,则可以将所有查询 `UNION ALL` 在子查询中 [FROM](../../../sql-reference/statements/select/from.md) 条款 +属于以下部分的查询 `UNION ALL` 不能用圆括号括起来。 [ORDER BY](../../../sql-reference/statements/select/order-by.md) 和 [LIMIT](../../../sql-reference/statements/select/limit.md) 应用于单独的查询,而不是最终结果。 如果您需要将转换应用于最终结果,则可以将所有查询 `UNION ALL` 在子查询中 [FROM](../../../sql-reference/statements/select/from.md) 子句。 ## 限制 {#limitations} -只有 `UNION ALL` 支持。 定期的 `UNION` (`UNION DISTINCT`)不支持。 如果你需要 `UNION DISTINCT`,你可以写 `SELECT DISTINCT` 从包含 `UNION ALL`. +只有 `UNION ALL` 支持。 `UNION` (`UNION DISTINCT`)不支持。 如果你需要 `UNION DISTINCT`,你可以写 `SELECT DISTINCT` 子查询中包含 `UNION ALL`. -## 实施细节 {#implementation-details} +## 实现细节 {#implementation-details} -属于以下部分的查询 `UNION ALL` 可以同时运行,并且它们的结果可以混合在一起。 +属于 `UNION ALL` 的查询可以同时运行,并且它们的结果可以混合在一起。 diff --git a/docs/zh/sql-reference/statements/select/where.md b/docs/zh/sql-reference/statements/select/where.md index eb1da0d1027..6168dd7fbf9 100644 --- a/docs/zh/sql-reference/statements/select/where.md +++ b/docs/zh/sql-reference/statements/select/where.md @@ -1,16 +1,14 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: WHERE --- -# WHERE条款 {#select-where} +# WHERE {#select-where} -`WHERE` 子句允许过滤来自 [FROM](../../../sql-reference/statements/select/from.md) 的条款 `SELECT`. +`WHERE` 子句允许过滤从 [FROM](../../../sql-reference/statements/select/from.md) 子句 `SELECT`. 如果有一个 `WHERE` 子句,它必须包含一个表达式与 `UInt8` 类型。 这通常是一个带有比较和逻辑运算符的表达式。 此表达式计算结果为0的行将从进一步的转换或结果中解释出来。 -`WHERE` 如果基础表引擎支持,则根据使用索引和分区修剪的能力评估expression。 +`WHERE` 如果基础表引擎支持,则根据使用索引和分区修剪的能力评估表达式。 !!! note "注" - 有一个叫做过滤优化 [去哪里](../../../sql-reference/statements/select/prewhere.md). + 有一个叫做过滤优化 [prewhere](../../../sql-reference/statements/select/prewhere.md) 的东西. diff --git a/docs/zh/sql-reference/statements/select/with.md b/docs/zh/sql-reference/statements/select/with.md index 224cd4790bb..bfa43f1c61a 100644 --- a/docs/zh/sql-reference/statements/select/with.md +++ b/docs/zh/sql-reference/statements/select/with.md @@ -1,10 +1,8 @@ --- -machine_translated: true -machine_translated_rev: 5decc73b5dc60054f19087d3690c4eb99446a6c3 toc_title: WITH --- -# WITH条款 {#with-clause} +# WITH子句 {#with-clause} 本节提供对公共表表达式的支持 ([CTE](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)),所以结果 `WITH` 子句可以在其余部分中使用 `SELECT` 查询。 diff --git a/docs/zh/sql-reference/syntax.md b/docs/zh/sql-reference/syntax.md index a2ce1b5bac3..78cbd5660ac 100644 --- a/docs/zh/sql-reference/syntax.md +++ b/docs/zh/sql-reference/syntax.md @@ -89,15 +89,12 @@ CH只支持用单引号包含的字母。特殊字符可通过反斜杠进行转 在字符串中,你至少需要对 `'` 和 `\` 进行转义。单引号可以使用单引号转义,例如 `'It\'s'` 和 `'It''s'` 是相同的。 ### 括号 {#compound} + 数组都是使用方括号进行构造 `[1, 2, 3]`,元组则使用圆括号 `(1, 'Hello, world!', 2)` - 从技术上来讲,这些都不是字符串,而是包含创建数组和元组运算符的表达式。 - 创建一个数组必须至少包含一个元素,创建一个元组至少包含2个元素 - 当元组出现在 `SELECT` 查询的 `IN` 部分时,是一种例外情形。查询结果可以包含元组,但是元组类型不能保存到数据库中(除非表采用 [内存表](../engines/table-engines/special/memory.md)引擎) - ### NULL值 {#null-literal} 代表不存在的值 diff --git a/programs/client/Client.cpp b/programs/client/Client.cpp index 90f9d0595df..e3a9b68dc47 100644 --- a/programs/client/Client.cpp +++ b/programs/client/Client.cpp @@ -1640,7 +1640,8 @@ private: return false; default: - throw Exception("Unknown packet from server", ErrorCodes::UNKNOWN_PACKET_FROM_SERVER); + throw Exception(ErrorCodes::UNKNOWN_PACKET_FROM_SERVER, "Unknown packet {} from server {}", + packet.type, connection->getDescription()); } } diff --git a/programs/client/Suggest.cpp b/programs/client/Suggest.cpp index 713aa82bb3e..738697817c3 100644 --- a/programs/client/Suggest.cpp +++ b/programs/client/Suggest.cpp @@ -156,7 +156,8 @@ void Suggest::fetch(Connection & connection, const ConnectionTimeouts & timeouts return; default: - throw Exception("Unknown packet from server", ErrorCodes::UNKNOWN_PACKET_FROM_SERVER); + throw Exception(ErrorCodes::UNKNOWN_PACKET_FROM_SERVER, "Unknown packet {} from server {}", + packet.type, connection.getDescription()); } } } diff --git a/programs/install/Install.cpp b/programs/install/Install.cpp index 8e6365ac5d5..7038401229a 100644 --- a/programs/install/Install.cpp +++ b/programs/install/Install.cpp @@ -621,6 +621,22 @@ namespace fs::remove(pid_file); } } + else + { + /// Create a directory for pid file. + /// It's created by "install" but we also support cases when ClickHouse is already installed different way. + fs::path pid_path = pid_file; + pid_path.remove_filename(); + fs::create_directories(pid_path); + /// All users are allowed to read pid file (for clickhouse status command). + fs::permissions(pid_path, fs::perms::owner_all | fs::perms::group_read | fs::perms::others_read, fs::perm_options::replace); + + { + std::string command = fmt::format("chown --recursive {} '{}'", user, pid_path.string()); + fmt::print(" {}\n", command); + executeScript(command); + } + } std::string command = fmt::format("{} --config-file {} --pid-file {} --daemon", executable.string(), config.string(), pid_file.string()); @@ -655,6 +671,28 @@ namespace if (try_num == num_tries) { fmt::print("Cannot start server. You can execute {} without --daemon option to run manually.\n", command); + + fs::path log_path; + + { + ConfigProcessor processor(config.string(), /* throw_on_bad_incl = */ false, /* log_to_console = */ false); + ConfigurationPtr configuration(new Poco::Util::XMLConfiguration(processor.processConfig())); + + if (configuration->has("logger.log")) + log_path = fs::path(configuration->getString("logger.log")).remove_filename(); + } + + if (log_path.empty()) + { + fmt::print("Cannot obtain path to logs (logger.log) from config file {}.\n", config.string()); + } + else + { + fs::path stderr_path = log_path; + stderr_path.replace_filename("stderr.log"); + fmt::print("Look for logs at {} and for {}.\n", log_path.string(), stderr_path.string()); + } + return 3; } diff --git a/programs/server/Server.cpp b/programs/server/Server.cpp index fdefd217e61..3a975325851 100644 --- a/programs/server/Server.cpp +++ b/programs/server/Server.cpp @@ -128,7 +128,6 @@ namespace ErrorCodes extern const int FAILED_TO_GETPWUID; extern const int MISMATCHING_USERS_FOR_PROCESS_AND_DATA; extern const int NETWORK_ERROR; - extern const int UNKNOWN_ELEMENT_IN_CONFIG; } @@ -215,30 +214,6 @@ void Server::defineOptions(Poco::Util::OptionSet & options) } -/// Check that there is no user-level settings at the top level in config. -/// This is a common source of mistake (user don't know where to write user-level setting). -void checkForUserSettingsAtTopLevel(const Poco::Util::AbstractConfiguration & config, const std::string & path) -{ - if (config.getBool("skip_check_for_incorrect_settings", false)) - return; - - Settings settings; - for (const auto & setting : settings.all()) - { - const auto & name = setting.getName(); - if (config.has(name)) - { - throw Exception(fmt::format("A setting '{}' appeared at top level in config {}." - " But it is user-level setting that should be located in users.xml inside section for specific profile." - " You can add it to if you want to change default value of this setting." - " You can also disable the check - specify 1" - " in the main configuration file.", - name, path), - ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG); - } - } -} - void checkForUsersNotInMainConfig( const Poco::Util::AbstractConfiguration & config, const std::string & config_path, @@ -319,7 +294,7 @@ int Server::main(const std::vector & /*args*/) config().add(loaded_config.configuration.duplicate(), PRIO_DEFAULT, false); } - checkForUserSettingsAtTopLevel(config(), config_path); + Settings::checkNoSettingNamesAtTopLevel(config(), config_path); const auto memory_amount = getMemoryAmount(); @@ -356,7 +331,7 @@ int Server::main(const std::vector & /*args*/) std::string path = getCanonicalPath(config().getString("path", DBMS_DEFAULT_PATH)); std::string default_database = config().getString("default_database", "default"); - /// Check that the process' user id matches the owner of the data. + /// Check that the process user id matches the owner of the data. const auto effective_user_id = geteuid(); struct stat statbuf; if (stat(path.c_str(), &statbuf) == 0 && effective_user_id != statbuf.st_uid) @@ -538,7 +513,7 @@ int Server::main(const std::vector & /*args*/) main_config_zk_changed_event, [&](ConfigurationPtr config) { - checkForUserSettingsAtTopLevel(*config, config_path); + Settings::checkNoSettingNamesAtTopLevel(*config, config_path); // FIXME logging-related things need synchronization -- see the 'Logger * log' saved // in a lot of places. For now, disable updating log configuration without server restart. @@ -559,48 +534,20 @@ int Server::main(const std::vector & /*args*/) }, /* already_loaded = */ true); - /// Initialize users config reloader. - std::string users_config_path = config().getString("users_config", config_path); - /// If path to users' config isn't absolute, try guess its root (current) dir. - /// At first, try to find it in dir of main config, after will use current dir. - if (users_config_path.empty() || users_config_path[0] != '/') - { - std::string config_dir = Poco::Path(config_path).parent().toString(); - if (Poco::File(config_dir + users_config_path).exists()) - users_config_path = config_dir + users_config_path; - } - - if (users_config_path != config_path) - checkForUsersNotInMainConfig(config(), config_path, users_config_path, log); - + auto & access_control = global_context->getAccessControlManager(); if (config().has("custom_settings_prefixes")) - global_context->getAccessControlManager().setCustomSettingsPrefixes(config().getString("custom_settings_prefixes")); + access_control.setCustomSettingsPrefixes(config().getString("custom_settings_prefixes")); - auto users_config_reloader = std::make_unique( - users_config_path, - include_from_path, - config().getString("path", ""), - zkutil::ZooKeeperNodeCache([&] { return global_context->getZooKeeper(); }), - std::make_shared(), - [&](ConfigurationPtr config) - { - global_context->setUsersConfig(config); - checkForUserSettingsAtTopLevel(*config, users_config_path); - }, - /* already_loaded = */ false); + /// Initialize access storages. + access_control.addStoragesFromMainConfig(config(), config_path, [&] { return global_context->getZooKeeper(); }); /// Reload config in SYSTEM RELOAD CONFIG query. global_context->setConfigReloadCallback([&]() { main_config_reloader->reload(); - users_config_reloader->reload(); + access_control.reloadUsersConfigs(); }); - /// Sets a local directory storing information about access control. - std::string access_control_local_path = config().getString("access_control_path", ""); - if (!access_control_local_path.empty()) - global_context->getAccessControlManager().setLocalDirectory(access_control_local_path); - /// Limit on total number of concurrently executed queries. global_context->getProcessList().setMaxSize(config().getInt("max_concurrent_queries", 0)); @@ -1069,7 +1016,7 @@ int Server::main(const std::vector & /*args*/) buildLoggers(config(), logger()); main_config_reloader->start(); - users_config_reloader->start(); + access_control.startPeriodicReloadingUsersConfigs(); if (dns_cache_updater) dns_cache_updater->start(); @@ -1128,7 +1075,6 @@ int Server::main(const std::vector & /*args*/) dns_cache_updater.reset(); main_config_reloader.reset(); - users_config_reloader.reset(); if (current_connections) { diff --git a/src/Access/AccessControlManager.cpp b/src/Access/AccessControlManager.cpp index d8d2a1f32d0..6158be1b603 100644 --- a/src/Access/AccessControlManager.cpp +++ b/src/Access/AccessControlManager.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -21,25 +22,32 @@ namespace DB { namespace ErrorCodes { + extern const int UNKNOWN_ELEMENT_IN_CONFIG; extern const int UNKNOWN_SETTING; } + namespace { - std::vector> createStorages() + void checkForUsersNotInMainConfig( + const Poco::Util::AbstractConfiguration & config, + const std::string & config_path, + const std::string & users_config_path, + Poco::Logger * log) { - std::vector> list; - list.emplace_back(std::make_unique()); - list.emplace_back(std::make_unique()); + if (config.getBool("skip_check_for_incorrect_settings", false)) + return; -#if 0 /// Memory access storage is disabled. - list.emplace_back(std::make_unique()); -#endif - return list; + if (config.has("users") || config.has("profiles") || config.has("quotas")) + { + /// We cannot throw exception here, because we have support for obsolete 'conf.d' directory + /// (that does not correspond to config.d or users.d) but substitute configuration to both of them. + + LOG_ERROR(log, "The , and elements should be located in users config file: {} not in main config {}." + " Also note that you should place configuration changes to the appropriate *.d directory like 'users.d'.", + users_config_path, config_path); + } } - - constexpr size_t DISK_ACCESS_STORAGE_INDEX = 0; - constexpr size_t USERS_CONFIG_ACCESS_STORAGE_INDEX = 1; } @@ -114,7 +122,7 @@ private: AccessControlManager::AccessControlManager() - : MultipleAccessStorage(createStorages()), + : MultipleAccessStorage("user directories"), context_access_cache(std::make_unique(*this)), role_cache(std::make_unique(*this)), row_policy_cache(std::make_unique(*this)), @@ -123,20 +131,191 @@ AccessControlManager::AccessControlManager() external_authenticators(std::make_unique()), custom_settings_prefixes(std::make_unique()) { - /// Allow UsersConfigAccessStorage to check the names of settings which it will read from users.xml. - auto check_setting_name_function = [this](const std::string_view & setting_name) { checkSettingNameIsAllowed(setting_name); }; - auto & users_config_access_storage = dynamic_cast(getStorageByIndex(USERS_CONFIG_ACCESS_STORAGE_INDEX)); - users_config_access_storage.setCheckSettingNameFunction(check_setting_name_function); } AccessControlManager::~AccessControlManager() = default; -void AccessControlManager::setLocalDirectory(const String & directory_path) +void AccessControlManager::setUsersConfig(const Poco::Util::AbstractConfiguration & users_config_) { - auto & disk_access_storage = dynamic_cast(getStorageByIndex(DISK_ACCESS_STORAGE_INDEX)); - disk_access_storage.setDirectory(directory_path); + auto storages = getStoragesPtr(); + for (const auto & storage : *storages) + { + if (auto users_config_storage = typeid_cast>(storage)) + { + users_config_storage->setConfig(users_config_); + return; + } + } + addUsersConfigStorage(users_config_); +} + +void AccessControlManager::addUsersConfigStorage(const Poco::Util::AbstractConfiguration & users_config_) +{ + addUsersConfigStorage(UsersConfigAccessStorage::STORAGE_TYPE, users_config_); +} + +void AccessControlManager::addUsersConfigStorage(const String & storage_name_, const Poco::Util::AbstractConfiguration & users_config_) +{ + auto check_setting_name_function = [this](const std::string_view & setting_name) { checkSettingNameIsAllowed(setting_name); }; + auto new_storage = std::make_shared(storage_name_, check_setting_name_function); + new_storage->setConfig(users_config_); + addStorage(new_storage); +} + +void AccessControlManager::addUsersConfigStorage( + const String & users_config_path_, + const String & include_from_path_, + const String & preprocessed_dir_, + const zkutil::GetZooKeeper & get_zookeeper_function_) +{ + addUsersConfigStorage( + UsersConfigAccessStorage::STORAGE_TYPE, users_config_path_, include_from_path_, preprocessed_dir_, get_zookeeper_function_); +} + +void AccessControlManager::addUsersConfigStorage( + const String & storage_name_, + const String & users_config_path_, + const String & include_from_path_, + const String & preprocessed_dir_, + const zkutil::GetZooKeeper & get_zookeeper_function_) +{ + auto check_setting_name_function = [this](const std::string_view & setting_name) { checkSettingNameIsAllowed(setting_name); }; + auto new_storage = std::make_shared(storage_name_, check_setting_name_function); + new_storage->load(users_config_path_, include_from_path_, preprocessed_dir_, get_zookeeper_function_); + addStorage(new_storage); +} + +void AccessControlManager::reloadUsersConfigs() +{ + auto storages = getStoragesPtr(); + for (const auto & storage : *storages) + { + if (auto users_config_storage = typeid_cast>(storage)) + users_config_storage->reload(); + } +} + +void AccessControlManager::startPeriodicReloadingUsersConfigs() +{ + auto storages = getStoragesPtr(); + for (const auto & storage : *storages) + { + if (auto users_config_storage = typeid_cast>(storage)) + users_config_storage->startPeriodicReloading(); + } +} + + +void AccessControlManager::addDiskStorage(const String & directory_, bool readonly_) +{ + addStorage(std::make_shared(directory_, readonly_)); +} + +void AccessControlManager::addDiskStorage(const String & storage_name_, const String & directory_, bool readonly_) +{ + addStorage(std::make_shared(storage_name_, directory_, readonly_)); +} + + +void AccessControlManager::addMemoryStorage(const String & storage_name_) +{ + addStorage(std::make_shared(storage_name_)); +} + + +void AccessControlManager::addStoragesFromUserDirectoriesConfig( + const Poco::Util::AbstractConfiguration & config, + const String & key, + const String & config_dir, + const String & dbms_dir, + const String & include_from_path, + const zkutil::GetZooKeeper & get_zookeeper_function) +{ + Strings keys_in_user_directories; + config.keys(key, keys_in_user_directories); + + for (const String & key_in_user_directories : keys_in_user_directories) + { + String prefix = key + "." + key_in_user_directories; + + String type = key_in_user_directories; + if (size_t bracket_pos = type.find('['); bracket_pos != String::npos) + type.resize(bracket_pos); + if ((type == "users_xml") || (type == "users_config")) + type = UsersConfigAccessStorage::STORAGE_TYPE; + else if ((type == "local") || (type == "local_directory")) + type = DiskAccessStorage::STORAGE_TYPE; + + String name = config.getString(prefix + ".name", type); + + if (type == MemoryAccessStorage::STORAGE_TYPE) + { + addMemoryStorage(name); + } + else if (type == UsersConfigAccessStorage::STORAGE_TYPE) + { + String path = config.getString(prefix + ".path"); + if (std::filesystem::path{path}.is_relative() && std::filesystem::exists(config_dir + path)) + path = config_dir + path; + addUsersConfigStorage(name, path, include_from_path, dbms_dir, get_zookeeper_function); + } + else if (type == DiskAccessStorage::STORAGE_TYPE) + { + String path = config.getString(prefix + ".path"); + bool readonly = config.getBool(prefix + ".readonly", false); + addDiskStorage(name, path, readonly); + } + else + throw Exception("Unknown storage type '" + type + "' at " + prefix + " in config", ErrorCodes::UNKNOWN_ELEMENT_IN_CONFIG); + } +} + + +void AccessControlManager::addStoragesFromMainConfig( + const Poco::Util::AbstractConfiguration & config, + const String & config_path, + const zkutil::GetZooKeeper & get_zookeeper_function) +{ + String config_dir = std::filesystem::path{config_path}.remove_filename().string(); + String dbms_dir = config.getString("path", DBMS_DEFAULT_PATH); + String include_from_path = config.getString("include_from", "/etc/metrika.xml"); + + if (config.has("user_directories")) + { + if (config.has("users_config")) + LOG_WARNING(getLogger(), " is specified, the path from won't be used: " + config.getString("users_config")); + if (config.has("access_control_path")) + LOG_WARNING(getLogger(), " is specified, the path from won't be used: " + config.getString("access_control_path")); + + addStoragesFromUserDirectoriesConfig( + config, + "user_directories", + config_dir, + dbms_dir, + include_from_path, + get_zookeeper_function); + } + else + { + /// If path to users' config isn't absolute, try guess its root (current) dir. + /// At first, try to find it in dir of main config, after will use current dir. + String users_config_path = config.getString("users_config", ""); + if (users_config_path.empty()) + users_config_path = config_path; + else if (std::filesystem::path{users_config_path}.is_relative() && std::filesystem::exists(config_dir + users_config_path)) + users_config_path = config_dir + users_config_path; + + if (users_config_path != config_path) + checkForUsersNotInMainConfig(config, config_path, users_config_path, getLogger()); + + addUsersConfigStorage(users_config_path, include_from_path, dbms_dir, get_zookeeper_function); + + String disk_storage_dir = config.getString("access_control_path", ""); + if (!disk_storage_dir.empty()) + addDiskStorage(disk_storage_dir); + } } @@ -146,13 +325,6 @@ void AccessControlManager::setExternalAuthenticatorsConfig(const Poco::Util::Abs } -void AccessControlManager::setUsersConfig(const Poco::Util::AbstractConfiguration & users_config) -{ - auto & users_config_access_storage = dynamic_cast(getStorageByIndex(USERS_CONFIG_ACCESS_STORAGE_INDEX)); - users_config_access_storage.setConfiguration(users_config); -} - - void AccessControlManager::setDefaultProfileName(const String & default_profile_name) { settings_profiles_cache->setDefaultProfileName(default_profile_name); diff --git a/src/Access/AccessControlManager.h b/src/Access/AccessControlManager.h index 443e8fc34b6..ad9fb48d263 100644 --- a/src/Access/AccessControlManager.h +++ b/src/Access/AccessControlManager.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -48,9 +49,54 @@ public: AccessControlManager(); ~AccessControlManager(); - void setLocalDirectory(const String & directory); - void setExternalAuthenticatorsConfig(const Poco::Util::AbstractConfiguration & config); - void setUsersConfig(const Poco::Util::AbstractConfiguration & users_config); + /// Parses access entities from a configuration loaded from users.xml. + /// This function add UsersConfigAccessStorage if it wasn't added before. + void setUsersConfig(const Poco::Util::AbstractConfiguration & users_config_); + + /// Adds UsersConfigAccessStorage. + void addUsersConfigStorage(const Poco::Util::AbstractConfiguration & users_config_); + + void addUsersConfigStorage(const String & storage_name_, + const Poco::Util::AbstractConfiguration & users_config_); + + void addUsersConfigStorage(const String & users_config_path_, + const String & include_from_path_, + const String & preprocessed_dir_, + const zkutil::GetZooKeeper & get_zookeeper_function_ = {}); + + void addUsersConfigStorage(const String & storage_name_, + const String & users_config_path_, + const String & include_from_path_, + const String & preprocessed_dir_, + const zkutil::GetZooKeeper & get_zookeeper_function_ = {}); + + void reloadUsersConfigs(); + void startPeriodicReloadingUsersConfigs(); + + /// Loads access entities from the directory on the local disk. + /// Use that directory to keep created users/roles/etc. + void addDiskStorage(const String & directory_, bool readonly_ = false); + void addDiskStorage(const String & storage_name_, const String & directory_, bool readonly_ = false); + + /// Adds MemoryAccessStorage which keeps access entities in memory. + void addMemoryStorage(); + void addMemoryStorage(const String & storage_name_); + + /// Adds storages from config. + void addStoragesFromUserDirectoriesConfig(const Poco::Util::AbstractConfiguration & config, + const String & key, + const String & config_dir, + const String & dbms_dir, + const String & include_from_path, + const zkutil::GetZooKeeper & get_zookeeper_function); + + /// Adds storages from the main config. + void addStoragesFromMainConfig(const Poco::Util::AbstractConfiguration & config, + const String & config_path, + const zkutil::GetZooKeeper & get_zookeeper_function); + + /// Sets the default profile's name. + /// The default profile's settings are always applied before any other profile's. void setDefaultProfileName(const String & default_profile_name); /// Sets prefixes which should be used for custom settings. @@ -60,6 +106,8 @@ public: bool isSettingNameAllowed(const std::string_view & name) const; void checkSettingNameIsAllowed(const std::string_view & name) const; + void setExternalAuthenticatorsConfig(const Poco::Util::AbstractConfiguration & config); + std::shared_ptr getContextAccess( const UUID & user_id, const boost::container::flat_set & current_roles, @@ -96,8 +144,10 @@ public: const ExternalAuthenticators & getExternalAuthenticators() const; -private: class ContextAccessCache; +private: + class ContextAccessCache; class CustomSettingsPrefixes; + std::unique_ptr context_access_cache; std::unique_ptr role_cache; std::unique_ptr row_policy_cache; diff --git a/src/Access/DiskAccessStorage.cpp b/src/Access/DiskAccessStorage.cpp index 25740f012ac..fc80859885d 100644 --- a/src/Access/DiskAccessStorage.cpp +++ b/src/Access/DiskAccessStorage.cpp @@ -47,7 +47,6 @@ namespace ErrorCodes extern const int DIRECTORY_DOESNT_EXIST; extern const int FILE_DOESNT_EXIST; extern const int INCORRECT_ACCESS_ENTITY_DEFINITION; - extern const int LOGICAL_ERROR; } @@ -86,7 +85,7 @@ namespace /// Reads a file containing ATTACH queries and then parses it to build an access entity. - AccessEntityPtr readEntityFile(const std::filesystem::path & file_path) + AccessEntityPtr readEntityFile(const String & file_path) { /// Read the file. ReadBufferFromFile in{file_path}; @@ -119,42 +118,42 @@ namespace if (auto * create_user_query = query->as()) { if (res) - throw Exception("Two access entities in one file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("Two access entities in one file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); res = user = std::make_unique(); InterpreterCreateUserQuery::updateUserFromQuery(*user, *create_user_query); } else if (auto * create_role_query = query->as()) { if (res) - throw Exception("Two access entities in one file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("Two access entities in one file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); res = role = std::make_unique(); InterpreterCreateRoleQuery::updateRoleFromQuery(*role, *create_role_query); } else if (auto * create_policy_query = query->as()) { if (res) - throw Exception("Two access entities in one file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("Two access entities in one file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); res = policy = std::make_unique(); InterpreterCreateRowPolicyQuery::updateRowPolicyFromQuery(*policy, *create_policy_query); } else if (auto * create_quota_query = query->as()) { if (res) - throw Exception("Two access entities are attached in the same file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("Two access entities are attached in the same file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); res = quota = std::make_unique(); InterpreterCreateQuotaQuery::updateQuotaFromQuery(*quota, *create_quota_query); } else if (auto * create_profile_query = query->as()) { if (res) - throw Exception("Two access entities are attached in the same file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("Two access entities are attached in the same file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); res = profile = std::make_unique(); InterpreterCreateSettingsProfileQuery::updateSettingsProfileFromQuery(*profile, *create_profile_query); } else if (auto * grant_query = query->as()) { if (!user && !role) - throw Exception("A user or role should be attached before grant in file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("A user or role should be attached before grant in file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); if (user) InterpreterGrantQuery::updateUserFromQuery(*user, *grant_query); else @@ -165,13 +164,13 @@ namespace } if (!res) - throw Exception("No access entities attached in file " + file_path.string(), ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); + throw Exception("No access entities attached in file " + file_path, ErrorCodes::INCORRECT_ACCESS_ENTITY_DEFINITION); return res; } - AccessEntityPtr tryReadEntityFile(const std::filesystem::path & file_path, Poco::Logger & log) + AccessEntityPtr tryReadEntityFile(const String & file_path, Poco::Logger & log) { try { @@ -179,14 +178,14 @@ namespace } catch (...) { - tryLogCurrentException(&log, "Could not parse " + file_path.string()); + tryLogCurrentException(&log, "Could not parse " + file_path); return nullptr; } } /// Writes ATTACH queries for building a specified access entity to a file. - void writeEntityFile(const std::filesystem::path & file_path, const IAccessEntity & entity) + void writeEntityFile(const String & file_path, const IAccessEntity & entity) { /// Build list of ATTACH queries. ASTs queries; @@ -220,14 +219,14 @@ namespace /// Calculates the path to a file named .sql for saving an access entity. - std::filesystem::path getEntityFilePath(const String & directory_path, const UUID & id) + String getEntityFilePath(const String & directory_path, const UUID & id) { - return std::filesystem::path(directory_path).append(toString(id)).replace_extension(".sql"); + return directory_path + toString(id) + ".sql"; } /// Reads a map of name of access entity to UUID for access entities of some type from a file. - std::vector> readListFile(const std::filesystem::path & file_path) + std::vector> readListFile(const String & file_path) { ReadBufferFromFile in(file_path); @@ -250,7 +249,7 @@ namespace /// Writes a map of name of access entity to UUID for access entities of some type to a file. - void writeListFile(const std::filesystem::path & file_path, const std::vector> & id_name_pairs) + void writeListFile(const String & file_path, const std::vector> & id_name_pairs) { WriteBufferFromFile out(file_path); writeVarUInt(id_name_pairs.size(), out); @@ -263,20 +262,19 @@ namespace /// Calculates the path for storing a map of name of access entity to UUID for access entities of some type. - std::filesystem::path getListFilePath(const String & directory_path, EntityType type) + String getListFilePath(const String & directory_path, EntityType type) { String file_name = EntityTypeInfo::get(type).plural_raw_name; boost::to_lower(file_name); - file_name += ".list"; - return std::filesystem::path(directory_path).append(file_name); + return directory_path + file_name + ".list"; } /// Calculates the path to a temporary file which existence means that list files are corrupted /// and need to be rebuild. - std::filesystem::path getNeedRebuildListsMarkFilePath(const String & directory_path) + String getNeedRebuildListsMarkFilePath(const String & directory_path) { - return std::filesystem::path(directory_path).append("need_rebuild_lists.mark"); + return directory_path + "need_rebuild_lists.mark"; } @@ -295,39 +293,18 @@ namespace } -DiskAccessStorage::DiskAccessStorage() - : IAccessStorage("disk") +DiskAccessStorage::DiskAccessStorage(const String & directory_path_, bool readonly_) + : DiskAccessStorage(STORAGE_TYPE, directory_path_, readonly_) { } -DiskAccessStorage::~DiskAccessStorage() -{ - stopListsWritingThread(); - writeLists(); -} - - -void DiskAccessStorage::setDirectory(const String & directory_path_) -{ - Notifications notifications; - SCOPE_EXIT({ notify(notifications); }); - - std::lock_guard lock{mutex}; - initialize(directory_path_, notifications); -} - - -void DiskAccessStorage::initialize(const String & directory_path_, Notifications & notifications) +DiskAccessStorage::DiskAccessStorage(const String & storage_name_, const String & directory_path_, bool readonly_) + : IAccessStorage(storage_name_) { auto canonical_directory_path = std::filesystem::weakly_canonical(directory_path_); - - if (initialized) - { - if (directory_path == canonical_directory_path) - return; - throw Exception("Storage " + getStorageName() + " already initialized with another directory", ErrorCodes::LOGICAL_ERROR); - } + if (canonical_directory_path.has_filename()) + canonical_directory_path += std::filesystem::path::preferred_separator; std::error_code create_dir_error_code; std::filesystem::create_directories(canonical_directory_path, create_dir_error_code); @@ -336,7 +313,7 @@ void DiskAccessStorage::initialize(const String & directory_path_, Notifications throw Exception("Couldn't create directory " + canonical_directory_path.string() + " reason: '" + create_dir_error_code.message() + "'", ErrorCodes::DIRECTORY_DOESNT_EXIST); directory_path = canonical_directory_path; - initialized = true; + readonly = readonly_; bool should_rebuild_lists = std::filesystem::exists(getNeedRebuildListsMarkFilePath(directory_path)); if (!should_rebuild_lists) @@ -350,9 +327,13 @@ void DiskAccessStorage::initialize(const String & directory_path_, Notifications rebuildLists(); writeLists(); } +} - for (const auto & [id, entry] : entries_by_id) - prepareNotifications(id, entry, false, notifications); + +DiskAccessStorage::~DiskAccessStorage() +{ + stopListsWritingThread(); + writeLists(); } @@ -375,7 +356,7 @@ bool DiskAccessStorage::readLists() auto file_path = getListFilePath(directory_path, type); if (!std::filesystem::exists(file_path)) { - LOG_WARNING(getLogger(), "File {} doesn't exist", file_path.string()); + LOG_WARNING(getLogger(), "File {} doesn't exist", file_path); ok = false; break; } @@ -393,7 +374,7 @@ bool DiskAccessStorage::readLists() } catch (...) { - tryLogCurrentException(getLogger(), "Could not read " + file_path.string()); + tryLogCurrentException(getLogger(), "Could not read " + file_path); ok = false; break; } @@ -428,7 +409,7 @@ bool DiskAccessStorage::writeLists() } catch (...) { - tryLogCurrentException(getLogger(), "Could not write " + file_path.string()); + tryLogCurrentException(getLogger(), "Could not write " + file_path); failed_to_write_lists = true; types_of_lists_to_write.clear(); return false; @@ -598,7 +579,7 @@ String DiskAccessStorage::readNameImpl(const UUID & id) const bool DiskAccessStorage::canInsertImpl(const AccessEntityPtr &) const { - return initialized; + return !readonly; } @@ -609,7 +590,7 @@ UUID DiskAccessStorage::insertImpl(const AccessEntityPtr & new_entity, bool repl UUID id = generateRandomID(); std::lock_guard lock{mutex}; - insertNoLock(generateRandomID(), new_entity, replace_if_exists, notifications); + insertNoLock(id, new_entity, replace_if_exists, notifications); return id; } @@ -618,11 +599,9 @@ void DiskAccessStorage::insertNoLock(const UUID & id, const AccessEntityPtr & ne { const String & name = new_entity->getName(); EntityType type = new_entity->getType(); - if (!initialized) - throw Exception( - "Cannot insert " + new_entity->outputTypeAndName() + " to storage [" + getStorageName() - + "] because the output directory is not set", - ErrorCodes::LOGICAL_ERROR); + + if (readonly) + throwReadonlyCannotInsert(type, name); /// Check that we can insert. auto it_by_id = entries_by_id.find(id); @@ -675,6 +654,9 @@ void DiskAccessStorage::removeNoLock(const UUID & id, Notifications & notificati Entry & entry = it->second; EntityType type = entry.type; + if (readonly) + throwReadonlyCannotRemove(type, entry.name); + scheduleWriteLists(type); deleteAccessEntityOnDisk(id); @@ -703,6 +685,8 @@ void DiskAccessStorage::updateNoLock(const UUID & id, const UpdateFunc & update_ throwNotFound(id); Entry & entry = it->second; + if (readonly) + throwReadonlyCannotUpdate(entry.type, entry.name); if (!entry.entity) entry.entity = readAccessEntityFromDisk(id); auto old_entity = entry.entity; @@ -757,7 +741,7 @@ void DiskAccessStorage::deleteAccessEntityOnDisk(const UUID & id) const { auto file_path = getEntityFilePath(directory_path, id); if (!std::filesystem::remove(file_path)) - throw Exception("Couldn't delete " + file_path.string(), ErrorCodes::FILE_DOESNT_EXIST); + throw Exception("Couldn't delete " + file_path, ErrorCodes::FILE_DOESNT_EXIST); } diff --git a/src/Access/DiskAccessStorage.h b/src/Access/DiskAccessStorage.h index 79a11195318..11eb1c3b1ad 100644 --- a/src/Access/DiskAccessStorage.h +++ b/src/Access/DiskAccessStorage.h @@ -11,10 +11,15 @@ namespace DB class DiskAccessStorage : public IAccessStorage { public: - DiskAccessStorage(); + static constexpr char STORAGE_TYPE[] = "local directory"; + + DiskAccessStorage(const String & storage_name_, const String & directory_path_, bool readonly_ = false); + DiskAccessStorage(const String & directory_path_, bool readonly_ = false); ~DiskAccessStorage() override; - void setDirectory(const String & directory_path_); + const char * getStorageType() const override { return STORAGE_TYPE; } + String getStoragePath() const override { return directory_path; } + bool isStorageReadOnly() const override { return readonly; } private: std::optional findImpl(EntityType type, const String & name) const override; @@ -31,7 +36,6 @@ private: bool hasSubscriptionImpl(const UUID & id) const override; bool hasSubscriptionImpl(EntityType type) const override; - void initialize(const String & directory_path_, Notifications & notifications); void clear(); bool readLists(); bool writeLists(); @@ -63,7 +67,7 @@ private: void prepareNotifications(const UUID & id, const Entry & entry, bool remove, Notifications & notifications) const; String directory_path; - bool initialized = false; + bool readonly; std::unordered_map entries_by_id; std::unordered_map entries_by_name_and_type[static_cast(EntityType::MAX)]; boost::container::flat_set types_of_lists_to_write; diff --git a/src/Access/IAccessStorage.cpp b/src/Access/IAccessStorage.cpp index ffedfb038a4..874ae612034 100644 --- a/src/Access/IAccessStorage.cpp +++ b/src/Access/IAccessStorage.cpp @@ -432,14 +432,14 @@ Poco::Logger * IAccessStorage::getLogger() const void IAccessStorage::throwNotFound(const UUID & id) const { - throw Exception(outputID(id) + " not found in [" + getStorageName() + "]", ErrorCodes::ACCESS_ENTITY_NOT_FOUND); + throw Exception(outputID(id) + " not found in " + getStorageName(), ErrorCodes::ACCESS_ENTITY_NOT_FOUND); } void IAccessStorage::throwNotFound(EntityType type, const String & name) const { int error_code = EntityTypeInfo::get(type).not_found_error_code; - throw Exception("There is no " + outputEntityTypeAndName(type, name) + " in [" + getStorageName() + "]", error_code); + throw Exception("There is no " + outputEntityTypeAndName(type, name) + " in " + getStorageName(), error_code); } @@ -455,7 +455,7 @@ void IAccessStorage::throwIDCollisionCannotInsert(const UUID & id, EntityType ty { throw Exception( outputEntityTypeAndName(type, name) + ": cannot insert because the " + outputID(id) + " is already used by " - + outputEntityTypeAndName(existing_type, existing_name) + " in [" + getStorageName() + "]", + + outputEntityTypeAndName(existing_type, existing_name) + " in " + getStorageName(), ErrorCodes::ACCESS_ENTITY_ALREADY_EXISTS); } @@ -463,8 +463,8 @@ void IAccessStorage::throwIDCollisionCannotInsert(const UUID & id, EntityType ty void IAccessStorage::throwNameCollisionCannotInsert(EntityType type, const String & name) const { throw Exception( - outputEntityTypeAndName(type, name) + ": cannot insert because " + outputEntityTypeAndName(type, name) + " already exists in [" - + getStorageName() + "]", + outputEntityTypeAndName(type, name) + ": cannot insert because " + outputEntityTypeAndName(type, name) + " already exists in " + + getStorageName(), ErrorCodes::ACCESS_ENTITY_ALREADY_EXISTS); } @@ -473,7 +473,7 @@ void IAccessStorage::throwNameCollisionCannotRename(EntityType type, const Strin { throw Exception( outputEntityTypeAndName(type, old_name) + ": cannot rename to " + backQuote(new_name) + " because " - + outputEntityTypeAndName(type, new_name) + " already exists in [" + getStorageName() + "]", + + outputEntityTypeAndName(type, new_name) + " already exists in " + getStorageName(), ErrorCodes::ACCESS_ENTITY_ALREADY_EXISTS); } @@ -481,7 +481,7 @@ void IAccessStorage::throwNameCollisionCannotRename(EntityType type, const Strin void IAccessStorage::throwReadonlyCannotInsert(EntityType type, const String & name) const { throw Exception( - "Cannot insert " + outputEntityTypeAndName(type, name) + " to [" + getStorageName() + "] because this storage is readonly", + "Cannot insert " + outputEntityTypeAndName(type, name) + " to " + getStorageName() + " because this storage is readonly", ErrorCodes::ACCESS_STORAGE_READONLY); } @@ -489,7 +489,7 @@ void IAccessStorage::throwReadonlyCannotInsert(EntityType type, const String & n void IAccessStorage::throwReadonlyCannotUpdate(EntityType type, const String & name) const { throw Exception( - "Cannot update " + outputEntityTypeAndName(type, name) + " in [" + getStorageName() + "] because this storage is readonly", + "Cannot update " + outputEntityTypeAndName(type, name) + " in " + getStorageName() + " because this storage is readonly", ErrorCodes::ACCESS_STORAGE_READONLY); } @@ -497,7 +497,7 @@ void IAccessStorage::throwReadonlyCannotUpdate(EntityType type, const String & n void IAccessStorage::throwReadonlyCannotRemove(EntityType type, const String & name) const { throw Exception( - "Cannot remove " + outputEntityTypeAndName(type, name) + " from [" + getStorageName() + "] because this storage is readonly", + "Cannot remove " + outputEntityTypeAndName(type, name) + " from " + getStorageName() + " because this storage is readonly", ErrorCodes::ACCESS_STORAGE_READONLY); } } diff --git a/src/Access/IAccessStorage.h b/src/Access/IAccessStorage.h index 76c87d948a0..7851f8c9b6b 100644 --- a/src/Access/IAccessStorage.h +++ b/src/Access/IAccessStorage.h @@ -24,6 +24,9 @@ public: /// Returns the name of this storage. const String & getStorageName() const { return storage_name; } + virtual const char * getStorageType() const = 0; + virtual String getStoragePath() const { return {}; } + virtual bool isStorageReadOnly() const { return false; } using EntityType = IAccessEntity::Type; using EntityTypeInfo = IAccessEntity::TypeInfo; diff --git a/src/Access/MemoryAccessStorage.cpp b/src/Access/MemoryAccessStorage.cpp index 720b82796b7..114c8eb8bee 100644 --- a/src/Access/MemoryAccessStorage.cpp +++ b/src/Access/MemoryAccessStorage.cpp @@ -171,6 +171,7 @@ void MemoryAccessStorage::updateNoLock(const UUID & id, const UpdateFunc & updat if (it2 != entries_by_name.end()) throwNameCollisionCannotRename(old_entity->getType(), old_entity->getName(), new_entity->getName()); + entries_by_name.erase(old_entity->getName()); entries_by_name[new_entity->getName()] = &entry; } diff --git a/src/Access/MemoryAccessStorage.h b/src/Access/MemoryAccessStorage.h index a2fdd0d0044..92439342168 100644 --- a/src/Access/MemoryAccessStorage.h +++ b/src/Access/MemoryAccessStorage.h @@ -13,7 +13,11 @@ namespace DB class MemoryAccessStorage : public IAccessStorage { public: - MemoryAccessStorage(const String & storage_name_ = "memory"); + static constexpr char STORAGE_TYPE[] = "memory"; + + MemoryAccessStorage(const String & storage_name_ = STORAGE_TYPE); + + const char * getStorageType() const override { return STORAGE_TYPE; } /// Sets all entities at once. void setAll(const std::vector & all_entities); diff --git a/src/Access/MultipleAccessStorage.cpp b/src/Access/MultipleAccessStorage.cpp index 9b80c16e487..bf711b54d54 100644 --- a/src/Access/MultipleAccessStorage.cpp +++ b/src/Access/MultipleAccessStorage.cpp @@ -1,89 +1,116 @@ #include #include -#include +#include +#include +#include +#include namespace DB { namespace ErrorCodes { - extern const int ACCESS_ENTITY_FOUND_DUPLICATES; extern const int ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND; + extern const int ACCESS_ENTITY_ALREADY_EXISTS; } - -namespace -{ - template - String joinStorageNames(const std::vector & storages) - { - String result; - for (const auto & storage : storages) - { - if (!result.empty()) - result += ", "; - result += storage->getStorageName(); - } - return result; - } -} +using Storage = IAccessStorage; +using StoragePtr = std::shared_ptr; +using ConstStoragePtr = std::shared_ptr; +using Storages = std::vector; -MultipleAccessStorage::MultipleAccessStorage( - std::vector> nested_storages_) - : IAccessStorage(joinStorageNames(nested_storages_)) - , nested_storages(std::move(nested_storages_)) +MultipleAccessStorage::MultipleAccessStorage(const String & storage_name_) + : IAccessStorage(storage_name_) + , nested_storages(std::make_shared()) , ids_cache(512 /* cache size */) { } -std::vector MultipleAccessStorage::findMultiple(EntityType type, const String & name) const +void MultipleAccessStorage::setStorages(const std::vector & storages) { - std::vector ids; - for (const auto & nested_storage : nested_storages) - { - auto id = nested_storage->find(type, name); - if (id) - { - std::lock_guard lock{ids_cache_mutex}; - ids_cache.set(*id, std::make_shared(nested_storage.get())); - ids.push_back(*id); - } - } - return ids; + std::unique_lock lock{mutex}; + nested_storages = std::make_shared(storages); + ids_cache.reset(); + updateSubscriptionsToNestedStorages(lock); +} + +void MultipleAccessStorage::addStorage(const StoragePtr & new_storage) +{ + std::unique_lock lock{mutex}; + if (boost::range::find(*nested_storages, new_storage) != nested_storages->end()) + return; + auto new_storages = std::make_shared(*nested_storages); + new_storages->push_back(new_storage); + nested_storages = new_storages; + updateSubscriptionsToNestedStorages(lock); +} + +void MultipleAccessStorage::removeStorage(const StoragePtr & storage_to_remove) +{ + std::unique_lock lock{mutex}; + auto it = boost::range::find(*nested_storages, storage_to_remove); + if (it == nested_storages->end()) + return; + size_t index = it - nested_storages->begin(); + auto new_storages = std::make_shared(*nested_storages); + new_storages->erase(new_storages->begin() + index); + nested_storages = new_storages; + ids_cache.reset(); + updateSubscriptionsToNestedStorages(lock); +} + +std::vector MultipleAccessStorage::getStorages() +{ + return *getStoragesPtr(); +} + +std::vector MultipleAccessStorage::getStorages() const +{ + auto storages = getStoragesInternal(); + std::vector res; + res.reserve(storages->size()); + boost::range::copy(*storages, std::back_inserter(res)); + return res; +} + +std::shared_ptr MultipleAccessStorage::getStoragesPtr() +{ + return getStoragesInternal(); +} + +std::shared_ptr MultipleAccessStorage::getStoragesInternal() const +{ + std::lock_guard lock{mutex}; + return nested_storages; } std::optional MultipleAccessStorage::findImpl(EntityType type, const String & name) const { - auto ids = findMultiple(type, name); - if (ids.empty()) - return {}; - if (ids.size() == 1) - return ids[0]; - - std::vector storages_with_duplicates; - for (const auto & id : ids) + auto storages = getStoragesInternal(); + for (const auto & storage : *storages) { - const auto * storage = findStorage(id); - if (storage) - storages_with_duplicates.push_back(storage); + auto id = storage->find(type, name); + if (id) + { + std::lock_guard lock{mutex}; + ids_cache.set(*id, storage); + return id; + } } - - throw Exception( - "Found " + outputEntityTypeAndName(type, name) + " in " + std::to_string(ids.size()) - + " storages [" + joinStorageNames(storages_with_duplicates) + "]", - ErrorCodes::ACCESS_ENTITY_FOUND_DUPLICATES); + return {}; } std::vector MultipleAccessStorage::findAllImpl(EntityType type) const { std::vector all_ids; - for (const auto & nested_storage : nested_storages) + auto storages = getStoragesInternal(); + for (const auto & storage : *storages) { - auto ids = nested_storage->findAll(type); + auto ids = storage->findAll(type); all_ids.insert(all_ids.end(), std::make_move_iterator(ids.begin()), std::make_move_iterator(ids.end())); } return all_ids; @@ -96,26 +123,24 @@ bool MultipleAccessStorage::existsImpl(const UUID & id) const } -IAccessStorage * MultipleAccessStorage::findStorage(const UUID & id) +StoragePtr MultipleAccessStorage::findStorage(const UUID & id) { + StoragePtr from_cache; { - std::lock_guard lock{ids_cache_mutex}; - auto from_cache = ids_cache.get(id); - if (from_cache) - { - auto * storage = *from_cache; - if (storage->exists(id)) - return storage; - } + std::lock_guard lock{mutex}; + from_cache = ids_cache.get(id); } + if (from_cache && from_cache->exists(id)) + return from_cache; - for (const auto & nested_storage : nested_storages) + auto storages = getStoragesInternal(); + for (const auto & storage : *storages) { - if (nested_storage->exists(id)) + if (storage->exists(id)) { - std::lock_guard lock{ids_cache_mutex}; - ids_cache.set(id, std::make_shared(nested_storage.get())); - return nested_storage.get(); + std::lock_guard lock{mutex}; + ids_cache.set(id, storage); + return storage; } } @@ -123,52 +148,44 @@ IAccessStorage * MultipleAccessStorage::findStorage(const UUID & id) } -const IAccessStorage * MultipleAccessStorage::findStorage(const UUID & id) const +ConstStoragePtr MultipleAccessStorage::findStorage(const UUID & id) const { return const_cast(this)->findStorage(id); } -IAccessStorage & MultipleAccessStorage::getStorage(const UUID & id) +StoragePtr MultipleAccessStorage::getStorage(const UUID & id) { - auto * storage = findStorage(id); + auto storage = findStorage(id); if (storage) - return *storage; + return storage; throwNotFound(id); } -const IAccessStorage & MultipleAccessStorage::getStorage(const UUID & id) const +ConstStoragePtr MultipleAccessStorage::getStorage(const UUID & id) const { return const_cast(this)->getStorage(id); } -void MultipleAccessStorage::addStorage(std::unique_ptr nested_storage) -{ - /// Note that IStorage::storage_name is not changed. It is ok as this method - /// is considered as a temporary solution allowing third-party Arcadia applications - /// using CH as a library to register their own access storages. Do not remove - /// this method without providing any alternative :) - nested_storages.emplace_back(std::move(nested_storage)); -} - AccessEntityPtr MultipleAccessStorage::readImpl(const UUID & id) const { - return getStorage(id).read(id); + return getStorage(id)->read(id); } String MultipleAccessStorage::readNameImpl(const UUID & id) const { - return getStorage(id).readName(id); + return getStorage(id)->readName(id); } bool MultipleAccessStorage::canInsertImpl(const AccessEntityPtr & entity) const { - for (const auto & nested_storage : nested_storages) + auto storages = getStoragesInternal(); + for (const auto & storage : *storages) { - if (nested_storage->canInsert(entity)) + if (storage->canInsert(entity)) return true; } return false; @@ -177,74 +194,202 @@ bool MultipleAccessStorage::canInsertImpl(const AccessEntityPtr & entity) const UUID MultipleAccessStorage::insertImpl(const AccessEntityPtr & entity, bool replace_if_exists) { - IAccessStorage * nested_storage_for_insertion = nullptr; - for (const auto & nested_storage : nested_storages) + auto storages = getStoragesInternal(); + + std::shared_ptr storage_for_insertion; + for (const auto & storage : *storages) { - if (nested_storage->canInsert(entity)) + if (storage->canInsert(entity) || + storage->find(entity->getType(), entity->getName())) { - nested_storage_for_insertion = nested_storage.get(); + storage_for_insertion = storage; break; } } - if (!nested_storage_for_insertion) + if (!storage_for_insertion) throw Exception("Not found a storage to insert " + entity->outputTypeAndName(), ErrorCodes::ACCESS_STORAGE_FOR_INSERTION_NOT_FOUND); - auto id = replace_if_exists ? nested_storage_for_insertion->insertOrReplace(entity) : nested_storage_for_insertion->insert(entity); - std::lock_guard lock{ids_cache_mutex}; - ids_cache.set(id, std::make_shared(nested_storage_for_insertion)); + auto id = replace_if_exists ? storage_for_insertion->insertOrReplace(entity) : storage_for_insertion->insert(entity); + std::lock_guard lock{mutex}; + ids_cache.set(id, storage_for_insertion); return id; } void MultipleAccessStorage::removeImpl(const UUID & id) { - getStorage(id).remove(id); + getStorage(id)->remove(id); } void MultipleAccessStorage::updateImpl(const UUID & id, const UpdateFunc & update_func) { - getStorage(id).update(id, update_func); + auto storage_for_updating = getStorage(id); + + /// If the updating involves renaming check that the renamed entity will be accessible by name. + auto storages = getStoragesInternal(); + if ((storages->size() > 1) && (storages->front() != storage_for_updating)) + { + auto old_entity = storage_for_updating->read(id); + auto new_entity = update_func(old_entity); + if (new_entity->getName() != old_entity->getName()) + { + for (const auto & storage : *storages) + { + if (storage == storage_for_updating) + break; + if (storage->find(new_entity->getType(), new_entity->getName())) + { + throw Exception( + old_entity->outputTypeAndName() + ": cannot rename to " + backQuote(new_entity->getName()) + " because " + + new_entity->outputTypeAndName() + " already exists in " + storage->getStorageName(), + ErrorCodes::ACCESS_ENTITY_ALREADY_EXISTS); + } + } + } + } + + storage_for_updating->update(id, update_func); } ext::scope_guard MultipleAccessStorage::subscribeForChangesImpl(const UUID & id, const OnChangedHandler & handler) const { - const auto * storage = findStorage(id); + auto storage = findStorage(id); if (!storage) return {}; return storage->subscribeForChanges(id, handler); } -ext::scope_guard MultipleAccessStorage::subscribeForChangesImpl(EntityType type, const OnChangedHandler & handler) const -{ - ext::scope_guard subscriptions; - for (const auto & nested_storage : nested_storages) - subscriptions.join(nested_storage->subscribeForChanges(type, handler)); - return subscriptions; -} - - bool MultipleAccessStorage::hasSubscriptionImpl(const UUID & id) const { - for (const auto & nested_storage : nested_storages) + auto storages = getStoragesInternal(); + for (const auto & storage : *storages) { - if (nested_storage->hasSubscription(id)) + if (storage->hasSubscription(id)) return true; } return false; } +ext::scope_guard MultipleAccessStorage::subscribeForChangesImpl(EntityType type, const OnChangedHandler & handler) const +{ + std::unique_lock lock{mutex}; + auto & handlers = handlers_by_type[static_cast(type)]; + handlers.push_back(handler); + auto handler_it = std::prev(handlers.end()); + if (handlers.size() == 1) + updateSubscriptionsToNestedStorages(lock); + + return [this, type, handler_it] + { + std::unique_lock lock2{mutex}; + auto & handlers2 = handlers_by_type[static_cast(type)]; + handlers2.erase(handler_it); + if (handlers2.empty()) + updateSubscriptionsToNestedStorages(lock2); + }; +} + + bool MultipleAccessStorage::hasSubscriptionImpl(EntityType type) const { - for (const auto & nested_storage : nested_storages) + std::lock_guard lock{mutex}; + const auto & handlers = handlers_by_type[static_cast(type)]; + return !handlers.empty(); +} + + +/// Updates subscriptions to nested storages. +/// We need the subscriptions to the nested storages if someone has subscribed to us. +/// If any of the nested storages is changed we call our subscribers. +void MultipleAccessStorage::updateSubscriptionsToNestedStorages(std::unique_lock & lock) const +{ + /// lock is already locked. + + std::vector> added_subscriptions[static_cast(EntityType::MAX)]; + std::vector removed_subscriptions; + + for (auto type : ext::range(EntityType::MAX)) { - if (nested_storage->hasSubscription(type)) - return true; + auto & handlers = handlers_by_type[static_cast(type)]; + auto & subscriptions = subscriptions_to_nested_storages[static_cast(type)]; + if (handlers.empty()) + { + /// None has subscribed to us, we need no subscriptions to the nested storages. + for (auto & subscription : subscriptions | boost::adaptors::map_values) + removed_subscriptions.push_back(std::move(subscription)); + subscriptions.clear(); + } + else + { + /// Someone has subscribed to us, now we need to have a subscription to each nested storage. + for (auto it = subscriptions.begin(); it != subscriptions.end();) + { + const auto & storage = it->first; + auto & subscription = it->second; + if (boost::range::find(*nested_storages, storage) == nested_storages->end()) + { + removed_subscriptions.push_back(std::move(subscription)); + it = subscriptions.erase(it); + } + else + ++it; + } + + for (const auto & storage : *nested_storages) + { + if (!subscriptions.count(storage)) + added_subscriptions[static_cast(type)].push_back({storage, nullptr}); + } + } } - return false; + + /// Unlock the mutex temporarily because it's much better to subscribe to the nested storages + /// with the mutex unlocked. + lock.unlock(); + removed_subscriptions.clear(); + + for (auto type : ext::range(EntityType::MAX)) + { + if (!added_subscriptions[static_cast(type)].empty()) + { + auto on_changed = [this, type](const UUID & id, const AccessEntityPtr & entity) + { + Notifications notifications; + SCOPE_EXIT({ notify(notifications); }); + std::lock_guard lock2{mutex}; + for (const auto & handler : handlers_by_type[static_cast(type)]) + notifications.push_back({handler, id, entity}); + }; + for (auto & [storage, subscription] : added_subscriptions[static_cast(type)]) + subscription = storage->subscribeForChanges(type, on_changed); + } + } + + /// Lock the mutex again to store added subscriptions to the nested storages. + lock.lock(); + for (auto type : ext::range(EntityType::MAX)) + { + if (!added_subscriptions[static_cast(type)].empty()) + { + auto & subscriptions = subscriptions_to_nested_storages[static_cast(type)]; + for (auto & [storage, subscription] : added_subscriptions[static_cast(type)]) + { + if (!subscriptions.count(storage) && (boost::range::find(*nested_storages, storage) != nested_storages->end()) + && !handlers_by_type[static_cast(type)].empty()) + { + subscriptions.emplace(std::move(storage), std::move(subscription)); + } + } + } + } + + lock.unlock(); + added_subscriptions->clear(); } + } diff --git a/src/Access/MultipleAccessStorage.h b/src/Access/MultipleAccessStorage.h index 06fb3d45c05..5d01894621f 100644 --- a/src/Access/MultipleAccessStorage.h +++ b/src/Access/MultipleAccessStorage.h @@ -11,24 +11,27 @@ namespace DB class MultipleAccessStorage : public IAccessStorage { public: + static constexpr char STORAGE_TYPE[] = "multiple"; + using Storage = IAccessStorage; + using StoragePtr = std::shared_ptr; + using ConstStoragePtr = std::shared_ptr; - MultipleAccessStorage(std::vector> nested_storages_); + MultipleAccessStorage(const String & storage_name_ = STORAGE_TYPE); - std::vector findMultiple(EntityType type, const String & name) const; + const char * getStorageType() const override { return STORAGE_TYPE; } - template - std::vector findMultiple(const String & name) const { return findMultiple(EntityType::TYPE, name); } + void setStorages(const std::vector & storages); + void addStorage(const StoragePtr & new_storage); + void removeStorage(const StoragePtr & storage_to_remove); + std::vector getStorages(); + std::vector getStorages() const; + std::shared_ptr> getStoragesPtr(); - const Storage * findStorage(const UUID & id) const; - Storage * findStorage(const UUID & id); - const Storage & getStorage(const UUID & id) const; - Storage & getStorage(const UUID & id); - - void addStorage(std::unique_ptr nested_storage); - - Storage & getStorageByIndex(size_t i) { return *(nested_storages[i]); } - const Storage & getStorageByIndex(size_t i) const { return *(nested_storages[i]); } + ConstStoragePtr findStorage(const UUID & id) const; + StoragePtr findStorage(const UUID & id); + ConstStoragePtr getStorage(const UUID & id) const; + StoragePtr getStorage(const UUID & id); protected: std::optional findImpl(EntityType type, const String & name) const override; @@ -46,9 +49,15 @@ protected: bool hasSubscriptionImpl(EntityType type) const override; private: - std::vector> nested_storages; - mutable LRUCache ids_cache; - mutable std::mutex ids_cache_mutex; + using Storages = std::vector; + std::shared_ptr getStoragesInternal() const; + void updateSubscriptionsToNestedStorages(std::unique_lock & lock) const; + + std::shared_ptr nested_storages; + mutable LRUCache ids_cache; + mutable std::list handlers_by_type[static_cast(EntityType::MAX)]; + mutable std::unordered_map subscriptions_to_nested_storages[static_cast(EntityType::MAX)]; + mutable std::mutex mutex; }; } diff --git a/src/Access/UsersConfigAccessStorage.cpp b/src/Access/UsersConfigAccessStorage.cpp index f891144654c..e4921ffe677 100644 --- a/src/Access/UsersConfigAccessStorage.cpp +++ b/src/Access/UsersConfigAccessStorage.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -13,6 +14,7 @@ #include #include #include +#include namespace DB @@ -467,19 +469,35 @@ namespace } -UsersConfigAccessStorage::UsersConfigAccessStorage() : IAccessStorage("users.xml") +UsersConfigAccessStorage::UsersConfigAccessStorage(const CheckSettingNameFunction & check_setting_name_function_) + : UsersConfigAccessStorage(STORAGE_TYPE, check_setting_name_function_) { } - -void UsersConfigAccessStorage::setCheckSettingNameFunction( - const std::function & check_setting_name_function_) +UsersConfigAccessStorage::UsersConfigAccessStorage(const String & storage_name_, const CheckSettingNameFunction & check_setting_name_function_) + : IAccessStorage(storage_name_), check_setting_name_function(check_setting_name_function_) { - check_setting_name_function = check_setting_name_function_; +} + +UsersConfigAccessStorage::~UsersConfigAccessStorage() = default; + + +String UsersConfigAccessStorage::getStoragePath() const +{ + std::lock_guard lock{load_mutex}; + return path; } -void UsersConfigAccessStorage::setConfiguration(const Poco::Util::AbstractConfiguration & config) +void UsersConfigAccessStorage::setConfig(const Poco::Util::AbstractConfiguration & config) +{ + std::lock_guard lock{load_mutex}; + path.clear(); + config_reloader.reset(); + parseFromConfig(config); +} + +void UsersConfigAccessStorage::parseFromConfig(const Poco::Util::AbstractConfiguration & config) { std::vector> all_entities; for (const auto & entity : parseUsers(config, getLogger())) @@ -493,6 +511,42 @@ void UsersConfigAccessStorage::setConfiguration(const Poco::Util::AbstractConfig memory_storage.setAll(all_entities); } +void UsersConfigAccessStorage::load( + const String & users_config_path, + const String & include_from_path, + const String & preprocessed_dir, + const zkutil::GetZooKeeper & get_zookeeper_function) +{ + std::lock_guard lock{load_mutex}; + path = std::filesystem::path{users_config_path}.lexically_normal(); + config_reloader.reset(); + config_reloader = std::make_unique( + users_config_path, + include_from_path, + preprocessed_dir, + zkutil::ZooKeeperNodeCache(get_zookeeper_function), + std::make_shared(), + [&](Poco::AutoPtr new_config) + { + parseFromConfig(*new_config); + Settings::checkNoSettingNamesAtTopLevel(*new_config, users_config_path); + }, + /* already_loaded = */ false); +} + +void UsersConfigAccessStorage::reload() +{ + std::lock_guard lock{load_mutex}; + if (config_reloader) + config_reloader->reload(); +} + +void UsersConfigAccessStorage::startPeriodicReloading() +{ + std::lock_guard lock{load_mutex}; + if (config_reloader) + config_reloader->start(); +} std::optional UsersConfigAccessStorage::findImpl(EntityType type, const String & name) const { diff --git a/src/Access/UsersConfigAccessStorage.h b/src/Access/UsersConfigAccessStorage.h index 374562b1f12..020dfe8f24b 100644 --- a/src/Access/UsersConfigAccessStorage.h +++ b/src/Access/UsersConfigAccessStorage.h @@ -1,29 +1,46 @@ #pragma once #include +#include -namespace Poco +namespace Poco::Util { - namespace Util - { - class AbstractConfiguration; - } + class AbstractConfiguration; } namespace DB { +class ConfigReloader; + /// Implementation of IAccessStorage which loads all from users.xml periodically. class UsersConfigAccessStorage : public IAccessStorage { public: - UsersConfigAccessStorage(); + static constexpr char STORAGE_TYPE[] = "users.xml"; + using CheckSettingNameFunction = std::function; - void setCheckSettingNameFunction(const std::function & check_setting_name_function_); - void setConfiguration(const Poco::Util::AbstractConfiguration & config); + UsersConfigAccessStorage(const String & storage_name_ = STORAGE_TYPE, const CheckSettingNameFunction & check_setting_name_function_ = {}); + UsersConfigAccessStorage(const CheckSettingNameFunction & check_setting_name_function_); + ~UsersConfigAccessStorage() override; + + const char * getStorageType() const override { return STORAGE_TYPE; } + String getStoragePath() const override; + bool isStorageReadOnly() const override { return true; } + + void setConfig(const Poco::Util::AbstractConfiguration & config); + + void load(const String & users_config_path, + const String & include_from_path = {}, + const String & preprocessed_dir = {}, + const zkutil::GetZooKeeper & get_zookeeper_function = {}); + void reload(); + void startPeriodicReloading(); private: + void parseFromConfig(const Poco::Util::AbstractConfiguration & config); + std::optional findImpl(EntityType type, const String & name) const override; std::vector findAllImpl(EntityType type) const override; bool existsImpl(const UUID & id) const override; @@ -39,6 +56,10 @@ private: bool hasSubscriptionImpl(EntityType type) const override; MemoryAccessStorage memory_storage; - std::function check_setting_name_function; + CheckSettingNameFunction check_setting_name_function; + + String path; + std::unique_ptr config_reloader; + mutable std::mutex load_mutex; }; } diff --git a/src/AggregateFunctions/AggregateFunctionAvg.cpp b/src/AggregateFunctions/AggregateFunctionAvg.cpp index 28f771c0b24..3764fd67ff5 100644 --- a/src/AggregateFunctions/AggregateFunctionAvg.cpp +++ b/src/AggregateFunctions/AggregateFunctionAvg.cpp @@ -17,7 +17,10 @@ namespace template struct Avg { - using FieldType = std::conditional_t, Decimal128, NearestFieldType>; + using FieldType = std::conditional_t, + std::conditional_t, Decimal256, Decimal128>, + NearestFieldType>; + // using FieldType = std::conditional_t, Decimal128, NearestFieldType>; using Function = AggregateFunctionAvg>; }; diff --git a/src/AggregateFunctions/AggregateFunctionAvg.h b/src/AggregateFunctions/AggregateFunctionAvg.h index f7bc228bcdd..944d9cbfaf5 100644 --- a/src/AggregateFunctions/AggregateFunctionAvg.h +++ b/src/AggregateFunctions/AggregateFunctionAvg.h @@ -22,19 +22,28 @@ struct AggregateFunctionAvgData using NumeratorType = T; using DenominatorType = Denominator; - T numerator = 0; - Denominator denominator = 0; + T numerator{0}; + Denominator denominator{0}; template ResultT NO_SANITIZE_UNDEFINED result() const { if constexpr (std::is_floating_point_v) if constexpr (std::numeric_limits::is_iec559) - return static_cast(numerator) / denominator; /// allow division by zero + { + if constexpr (is_big_int_v) + return static_cast(numerator) / static_cast(denominator); + else + return static_cast(numerator) / denominator; /// allow division by zero + } - if (denominator == 0) + if (denominator == static_cast(0)) return static_cast(0); - return static_cast(numerator / denominator); + + if constexpr (std::is_same_v) + return static_cast(numerator / static_cast(denominator)); + else + return static_cast(numerator / denominator); } }; diff --git a/src/AggregateFunctions/AggregateFunctionAvgWeighted.cpp b/src/AggregateFunctions/AggregateFunctionAvgWeighted.cpp index 94fde173528..6722a94cdc6 100644 --- a/src/AggregateFunctions/AggregateFunctionAvgWeighted.cpp +++ b/src/AggregateFunctions/AggregateFunctionAvgWeighted.cpp @@ -17,7 +17,10 @@ namespace template struct AvgWeighted { - using FieldType = std::conditional_t, Decimal128, NearestFieldType>; + using FieldType = std::conditional_t, + std::conditional_t, Decimal256, Decimal128>, + NearestFieldType>; + // using FieldType = std::conditional_t, Decimal128, NearestFieldType>; using Function = AggregateFunctionAvgWeighted>; }; diff --git a/src/AggregateFunctions/AggregateFunctionGroupArray.h b/src/AggregateFunctions/AggregateFunctionGroupArray.h index f3d31eb599b..83e096c797b 100644 --- a/src/AggregateFunctions/AggregateFunctionGroupArray.h +++ b/src/AggregateFunctions/AggregateFunctionGroupArray.h @@ -295,7 +295,12 @@ public: if (size) { typename ColumnVector::Container & data_to = assert_cast &>(arr_to.getData()).getData(); - data_to.insert(this->data(place).value.begin(), this->data(place).value.end()); + if constexpr (is_big_int_v) + // is data_to empty? we should probaly use std::vector::insert then + for (auto it = this->data(place).value.begin(); it != this->data(place).value.end(); it++) + data_to.push_back(*it); + else + data_to.insert(this->data(place).value.begin(), this->data(place).value.end()); } } diff --git a/src/AggregateFunctions/AggregateFunctionGroupArrayMoving.cpp b/src/AggregateFunctions/AggregateFunctionGroupArrayMoving.cpp index 6a0397837a5..cb62035f539 100644 --- a/src/AggregateFunctions/AggregateFunctionGroupArrayMoving.cpp +++ b/src/AggregateFunctions/AggregateFunctionGroupArrayMoving.cpp @@ -37,12 +37,12 @@ struct MovingAvg template using MovingSumTemplate = typename MovingSum::Function; template using MovingAvgTemplate = typename MovingAvg::Function; -template