diff --git a/dbms/src/AggregateFunctions/AggregateFunctionQuantileTiming.h b/dbms/src/AggregateFunctions/AggregateFunctionQuantileTiming.h index 33ba575da41..bcf9273b2c9 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionQuantileTiming.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionQuantileTiming.h @@ -18,7 +18,7 @@ #include #include -#include +#include namespace DB diff --git a/dbms/src/AggregateFunctions/AggregateFunctionSequenceMatch.h b/dbms/src/AggregateFunctions/AggregateFunctionSequenceMatch.h index bb1c1a8b103..8bae08b0fde 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionSequenceMatch.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionSequenceMatch.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Analyzers/AnalyzeArrayJoins.h b/dbms/src/Analyzers/AnalyzeArrayJoins.h index bb1a359fdc6..4bc9c3fb72b 100644 --- a/dbms/src/Analyzers/AnalyzeArrayJoins.h +++ b/dbms/src/Analyzers/AnalyzeArrayJoins.h @@ -23,6 +23,8 @@ struct CollectTables; * SELECT array FROM t ARRAY JOIN array array -> array * SELECT nested.elem FROM t ARRAY JOIN nested nested -> nested * SELECT elem FROM t ARRAY JOIN [1, 2, 3] AS elem elem -> [1, 2, 3] + * + * Does not analyze arrayJoin functions. */ struct AnalyzeArrayJoins { diff --git a/dbms/src/Analyzers/tests/analyze_columns.cpp b/dbms/src/Analyzers/tests/analyze_columns.cpp index bc23b6ec9b4..e40c8efcb75 100644 --- a/dbms/src/Analyzers/tests/analyze_columns.cpp +++ b/dbms/src/Analyzers/tests/analyze_columns.cpp @@ -36,7 +36,7 @@ try auto system_database = std::make_shared("system"); context.addDatabase("system", system_database); system_database->attachTable("one", StorageSystemOne::create("one")); - system_database->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); context.setCurrentDatabase("system"); AnalyzeLambdas analyze_lambdas; diff --git a/dbms/src/Analyzers/tests/analyze_result_of_query.cpp b/dbms/src/Analyzers/tests/analyze_result_of_query.cpp index 03fc25c7376..26ed402ce1b 100644 --- a/dbms/src/Analyzers/tests/analyze_result_of_query.cpp +++ b/dbms/src/Analyzers/tests/analyze_result_of_query.cpp @@ -32,8 +32,8 @@ try auto system_database = std::make_shared("system"); context.addDatabase("system", system_database); context.setCurrentDatabase("system"); - system_database->attachTable("one", StorageSystemOne::create("one")); - system_database->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system_database->attachTable("one", StorageSystemOne::create("one")); + system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); AnalyzeResultOfQuery analyzer; analyzer.process(ast, context); diff --git a/dbms/src/Analyzers/tests/collect_tables.cpp b/dbms/src/Analyzers/tests/collect_tables.cpp index 2b4c9378105..0175fdc656b 100644 --- a/dbms/src/Analyzers/tests/collect_tables.cpp +++ b/dbms/src/Analyzers/tests/collect_tables.cpp @@ -33,8 +33,8 @@ try auto system_database = std::make_shared("system"); context.addDatabase("system", system_database); context.setCurrentDatabase("system"); - system_database->attachTable("one", StorageSystemOne::create("one")); - system_database->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system_database->attachTable("one", StorageSystemOne::create("one")); + system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); CollectAliases collect_aliases; collect_aliases.process(ast); diff --git a/dbms/src/Analyzers/tests/optimize_group_order_limit_by.cpp b/dbms/src/Analyzers/tests/optimize_group_order_limit_by.cpp index db8ea5e81ee..27d64b00711 100644 --- a/dbms/src/Analyzers/tests/optimize_group_order_limit_by.cpp +++ b/dbms/src/Analyzers/tests/optimize_group_order_limit_by.cpp @@ -38,8 +38,8 @@ try auto system_database = std::make_shared("system"); context.addDatabase("system", system_database); - system_database->attachTable("one", StorageSystemOne::create("one")); - system_database->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system_database->attachTable("one", StorageSystemOne::create("one")); + system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); context.setCurrentDatabase("system"); AnalyzeLambdas analyze_lambdas; diff --git a/dbms/src/Analyzers/tests/type_and_constant_inference.cpp b/dbms/src/Analyzers/tests/type_and_constant_inference.cpp index a1cd1035c54..4e4ad7a87e9 100644 --- a/dbms/src/Analyzers/tests/type_and_constant_inference.cpp +++ b/dbms/src/Analyzers/tests/type_and_constant_inference.cpp @@ -39,8 +39,8 @@ try auto system_database = std::make_shared("system"); context.addDatabase("system", system_database); - system_database->attachTable("one", StorageSystemOne::create("one")); - system_database->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system_database->attachTable("one", StorageSystemOne::create("one")); + system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); context.setCurrentDatabase("system"); AnalyzeLambdas analyze_lambdas; diff --git a/dbms/src/Columns/ColumnConst.cpp b/dbms/src/Columns/ColumnConst.cpp index 71851d109ef..341140be115 100644 --- a/dbms/src/Columns/ColumnConst.cpp +++ b/dbms/src/Columns/ColumnConst.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace DB diff --git a/dbms/src/Columns/ColumnTuple.cpp b/dbms/src/Columns/ColumnTuple.cpp index 74a9803df89..40dddf233c8 100644 --- a/dbms/src/Columns/ColumnTuple.cpp +++ b/dbms/src/Columns/ColumnTuple.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include namespace DB diff --git a/dbms/src/Columns/ColumnVector.cpp b/dbms/src/Columns/ColumnVector.cpp index f47856d35a6..21f89514daf 100644 --- a/dbms/src/Columns/ColumnVector.cpp +++ b/dbms/src/Columns/ColumnVector.cpp @@ -11,7 +11,7 @@ #include -#include +#include #if __SSE2__ #include diff --git a/dbms/src/Common/ArrayCache.h b/dbms/src/Common/ArrayCache.h index 82a5cc162c1..d65450aa4eb 100644 --- a/dbms/src/Common/ArrayCache.h +++ b/dbms/src/Common/ArrayCache.h @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Common/ExternalTable.h b/dbms/src/Common/ExternalTable.h index 257431a5d15..9d7ce88e3b6 100644 --- a/dbms/src/Common/ExternalTable.h +++ b/dbms/src/Common/ExternalTable.h @@ -198,6 +198,7 @@ public: /// Create table NamesAndTypesListPtr columns = std::make_shared(sample_block.getColumnsList()); StoragePtr storage = StorageMemory::create(data.second, columns); + storage->startup(); context.addExternalTable(data.second, storage); BlockOutputStreamPtr output = storage->write(ASTPtr(), context.getSettingsRef()); diff --git a/dbms/src/Common/PoolWithFailoverBase.h b/dbms/src/Common/PoolWithFailoverBase.h index 6f035537098..43a2d728c4d 100644 --- a/dbms/src/Common/PoolWithFailoverBase.h +++ b/dbms/src/Common/PoolWithFailoverBase.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Common/RadixSort.h b/dbms/src/Common/RadixSort.h index ee844fa83a8..e22fdd01c2b 100644 --- a/dbms/src/Common/RadixSort.h +++ b/dbms/src/Common/RadixSort.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include diff --git a/dbms/src/Common/SimpleCache.h b/dbms/src/Common/SimpleCache.h index 4de92baa9f5..67602c00d02 100644 --- a/dbms/src/Common/SimpleCache.h +++ b/dbms/src/Common/SimpleCache.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include /** The simplest cache for a free function. diff --git a/dbms/src/Common/SmallObjectPool.h b/dbms/src/Common/SmallObjectPool.h index e53a9234ae2..5291a1965d0 100644 --- a/dbms/src/Common/SmallObjectPool.h +++ b/dbms/src/Common/SmallObjectPool.h @@ -2,9 +2,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include diff --git a/dbms/src/Common/StringSearcher.h b/dbms/src/Common/StringSearcher.h index ba1947f515c..4ba297fb430 100644 --- a/dbms/src/Common/StringSearcher.h +++ b/dbms/src/Common/StringSearcher.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include diff --git a/dbms/src/Common/Volnitsky.h b/dbms/src/Common/Volnitsky.h index e1fda9f0bb0..e8de2618dc6 100644 --- a/dbms/src/Common/Volnitsky.h +++ b/dbms/src/Common/Volnitsky.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Common/tests/arena_with_free_lists.cpp b/dbms/src/Common/tests/arena_with_free_lists.cpp index 5341be486f7..a086b868fa0 100644 --- a/dbms/src/Common/tests/arena_with_free_lists.cpp +++ b/dbms/src/Common/tests/arena_with_free_lists.cpp @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include #include diff --git a/dbms/src/Common/tests/radix_sort.cpp b/dbms/src/Common/tests/radix_sort.cpp index 20005474104..eaf4a02b0dc 100644 --- a/dbms/src/Common/tests/radix_sort.cpp +++ b/dbms/src/Common/tests/radix_sort.cpp @@ -1,7 +1,7 @@ #if !defined(__APPLE__) && !defined(__FreeBSD__) #include #endif -#include +#include #include #include #include diff --git a/dbms/src/DataStreams/MaterializingBlockOutputStream.cpp b/dbms/src/DataStreams/MaterializingBlockOutputStream.cpp index 419f5285a41..f58f52d02b1 100644 --- a/dbms/src/DataStreams/MaterializingBlockOutputStream.cpp +++ b/dbms/src/DataStreams/MaterializingBlockOutputStream.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include namespace DB diff --git a/dbms/src/DataStreams/tests/expression_stream.cpp b/dbms/src/DataStreams/tests/expression_stream.cpp index 8677a1b866a..80ddc4bde73 100644 --- a/dbms/src/DataStreams/tests/expression_stream.cpp +++ b/dbms/src/DataStreams/tests/expression_stream.cpp @@ -42,7 +42,7 @@ try chain.finalize(); ExpressionActionsPtr expression = chain.getLastActions(); - StoragePtr table = StorageSystemNumbers::create("Numbers"); + StoragePtr table = StorageSystemNumbers::create("numbers", false); Names column_names; column_names.push_back("number"); diff --git a/dbms/src/DataStreams/tests/filter_stream.cpp b/dbms/src/DataStreams/tests/filter_stream.cpp index a6fb7722c4f..413ebfc249f 100644 --- a/dbms/src/DataStreams/tests/filter_stream.cpp +++ b/dbms/src/DataStreams/tests/filter_stream.cpp @@ -48,7 +48,7 @@ try chain.finalize(); ExpressionActionsPtr expression = chain.getLastActions(); - StoragePtr table = StorageSystemNumbers::create("Numbers"); + StoragePtr table = StorageSystemNumbers::create("numbers", false); Names column_names; column_names.push_back("number"); diff --git a/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp b/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp index 71ab21b59c3..85d931ebdde 100644 --- a/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp +++ b/dbms/src/DataStreams/tests/filter_stream_hitlog.cpp @@ -35,62 +35,62 @@ int main(int argc, char ** argv) { NamesAndTypesList names_and_types_list { - {"WatchID", std::make_shared()}, - {"JavaEnable", std::make_shared()}, - {"Title", std::make_shared()}, - {"EventTime", std::make_shared()}, - {"CounterID", std::make_shared()}, - {"ClientIP", std::make_shared()}, - {"RegionID", std::make_shared()}, - {"UniqID", std::make_shared()}, - {"CounterClass", std::make_shared()}, - {"OS", std::make_shared()}, - {"UserAgent", std::make_shared()}, - {"URL", std::make_shared()}, - {"Referer", std::make_shared()}, - {"ResolutionWidth", std::make_shared()}, - {"ResolutionHeight", std::make_shared()}, - {"ResolutionDepth", std::make_shared()}, - {"FlashMajor", std::make_shared()}, - {"FlashMinor", std::make_shared()}, - {"FlashMinor2", std::make_shared()}, - {"NetMajor", std::make_shared()}, - {"NetMinor", std::make_shared()}, - {"UserAgentMajor", std::make_shared()}, - {"UserAgentMinor", std::make_shared(2)}, - {"CookieEnable", std::make_shared()}, - {"JavascriptEnable", std::make_shared()}, - {"IsMobile", std::make_shared()}, - {"MobilePhone", std::make_shared()}, - {"MobilePhoneModel", std::make_shared()}, - {"Params", std::make_shared()}, - {"IPNetworkID", std::make_shared()}, - {"TraficSourceID", std::make_shared()}, - {"SearchEngineID", std::make_shared()}, - {"SearchPhrase", std::make_shared()}, - {"AdvEngineID", std::make_shared()}, - {"IsArtifical", std::make_shared()}, - {"WindowClientWidth", std::make_shared()}, - {"WindowClientHeight", std::make_shared()}, - {"ClientTimeZone", std::make_shared()}, - {"ClientEventTime", std::make_shared()}, - {"SilverlightVersion1", std::make_shared()}, - {"SilverlightVersion2", std::make_shared()}, - {"SilverlightVersion3", std::make_shared()}, - {"SilverlightVersion4", std::make_shared()}, - {"PageCharset", std::make_shared()}, - {"CodeVersion", std::make_shared()}, - {"IsLink", std::make_shared()}, - {"IsDownload", std::make_shared()}, - {"IsNotBounce", std::make_shared()}, - {"FUniqID", std::make_shared()}, - {"OriginalURL", std::make_shared()}, - {"HID", std::make_shared()}, - {"IsOldCounter", std::make_shared()}, - {"IsEvent", std::make_shared()}, - {"IsParameter", std::make_shared()}, - {"DontCountHits", std::make_shared()}, - {"WithHash", std::make_shared()}, + {"WatchID", std::make_shared()}, + {"JavaEnable", std::make_shared()}, + {"Title", std::make_shared()}, + {"EventTime", std::make_shared()}, + {"CounterID", std::make_shared()}, + {"ClientIP", std::make_shared()}, + {"RegionID", std::make_shared()}, + {"UniqID", std::make_shared()}, + {"CounterClass", std::make_shared()}, + {"OS", std::make_shared()}, + {"UserAgent", std::make_shared()}, + {"URL", std::make_shared()}, + {"Referer", std::make_shared()}, + {"ResolutionWidth", std::make_shared()}, + {"ResolutionHeight", std::make_shared()}, + {"ResolutionDepth", std::make_shared()}, + {"FlashMajor", std::make_shared()}, + {"FlashMinor", std::make_shared()}, + {"FlashMinor2", std::make_shared()}, + {"NetMajor", std::make_shared()}, + {"NetMinor", std::make_shared()}, + {"UserAgentMajor", std::make_shared()}, + {"UserAgentMinor", std::make_shared(2)}, + {"CookieEnable", std::make_shared()}, + {"JavascriptEnable", std::make_shared()}, + {"IsMobile", std::make_shared()}, + {"MobilePhone", std::make_shared()}, + {"MobilePhoneModel", std::make_shared()}, + {"Params", std::make_shared()}, + {"IPNetworkID", std::make_shared()}, + {"TraficSourceID", std::make_shared()}, + {"SearchEngineID", std::make_shared()}, + {"SearchPhrase", std::make_shared()}, + {"AdvEngineID", std::make_shared()}, + {"IsArtifical", std::make_shared()}, + {"WindowClientWidth", std::make_shared()}, + {"WindowClientHeight", std::make_shared()}, + {"ClientTimeZone", std::make_shared()}, + {"ClientEventTime", std::make_shared()}, + {"SilverlightVersion1", std::make_shared()}, + {"SilverlightVersion2", std::make_shared()}, + {"SilverlightVersion3", std::make_shared()}, + {"SilverlightVersion4", std::make_shared()}, + {"PageCharset", std::make_shared()}, + {"CodeVersion", std::make_shared()}, + {"IsLink", std::make_shared()}, + {"IsDownload", std::make_shared()}, + {"IsNotBounce", std::make_shared()}, + {"FUniqID", std::make_shared()}, + {"OriginalURL", std::make_shared()}, + {"HID", std::make_shared()}, + {"IsOldCounter", std::make_shared()}, + {"IsEvent", std::make_shared()}, + {"IsParameter", std::make_shared()}, + {"DontCountHits", std::make_shared()}, + {"WithHash", std::make_shared()}, }; Context context; @@ -105,7 +105,9 @@ int main(int argc, char ** argv) /// create an object of an existing hit log table - StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list)); + StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list), + NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, DEFAULT_MAX_COMPRESS_BLOCK_SIZE); + table->startup(); /// read from it, apply the expression, filter, and write in tsv form to the console diff --git a/dbms/src/DataStreams/tests/fork_streams.cpp b/dbms/src/DataStreams/tests/fork_streams.cpp index 0ac19455b61..f0fd7a40826 100644 --- a/dbms/src/DataStreams/tests/fork_streams.cpp +++ b/dbms/src/DataStreams/tests/fork_streams.cpp @@ -65,7 +65,7 @@ try chain.finalize(); ExpressionActionsPtr expression = chain.getLastActions(); - StoragePtr table = StorageSystemNumbers::create("Numbers"); + StoragePtr table = StorageSystemNumbers::create("numbers", false); Names column_names; column_names.push_back("number"); diff --git a/dbms/src/DataStreams/tests/native_streams.cpp b/dbms/src/DataStreams/tests/native_streams.cpp index a65eb666bd9..66b04891c80 100644 --- a/dbms/src/DataStreams/tests/native_streams.cpp +++ b/dbms/src/DataStreams/tests/native_streams.cpp @@ -30,62 +30,62 @@ try NamesAndTypesList names_and_types_list { - {"WatchID", std::make_shared()}, - {"JavaEnable", std::make_shared()}, - {"Title", std::make_shared()}, - {"EventTime", std::make_shared()}, - {"CounterID", std::make_shared()}, - {"ClientIP", std::make_shared()}, - {"RegionID", std::make_shared()}, - {"UniqID", std::make_shared()}, - {"CounterClass", std::make_shared()}, - {"OS", std::make_shared()}, - {"UserAgent", std::make_shared()}, - {"URL", std::make_shared()}, - {"Referer", std::make_shared()}, - {"ResolutionWidth", std::make_shared()}, - {"ResolutionHeight", std::make_shared()}, - {"ResolutionDepth", std::make_shared()}, - {"FlashMajor", std::make_shared()}, - {"FlashMinor", std::make_shared()}, - {"FlashMinor2", std::make_shared()}, - {"NetMajor", std::make_shared()}, - {"NetMinor", std::make_shared()}, - {"UserAgentMajor", std::make_shared()}, - {"UserAgentMinor", std::make_shared(2)}, - {"CookieEnable", std::make_shared()}, - {"JavascriptEnable", std::make_shared()}, - {"IsMobile", std::make_shared()}, - {"MobilePhone", std::make_shared()}, - {"MobilePhoneModel", std::make_shared()}, - {"Params", std::make_shared()}, - {"IPNetworkID", std::make_shared()}, - {"TraficSourceID", std::make_shared()}, - {"SearchEngineID", std::make_shared()}, - {"SearchPhrase", std::make_shared()}, - {"AdvEngineID", std::make_shared()}, - {"IsArtifical", std::make_shared()}, - {"WindowClientWidth", std::make_shared()}, - {"WindowClientHeight", std::make_shared()}, - {"ClientTimeZone", std::make_shared()}, - {"ClientEventTime", std::make_shared()}, - {"SilverlightVersion1", std::make_shared()}, - {"SilverlightVersion2", std::make_shared()}, - {"SilverlightVersion3", std::make_shared()}, - {"SilverlightVersion4", std::make_shared()}, - {"PageCharset", std::make_shared()}, - {"CodeVersion", std::make_shared()}, - {"IsLink", std::make_shared()}, - {"IsDownload", std::make_shared()}, - {"IsNotBounce", std::make_shared()}, - {"FUniqID", std::make_shared()}, - {"OriginalURL", std::make_shared()}, - {"HID", std::make_shared()}, - {"IsOldCounter", std::make_shared()}, - {"IsEvent", std::make_shared()}, - {"IsParameter", std::make_shared()}, - {"DontCountHits", std::make_shared()}, - {"WithHash", std::make_shared()}, + {"WatchID", std::make_shared()}, + {"JavaEnable", std::make_shared()}, + {"Title", std::make_shared()}, + {"EventTime", std::make_shared()}, + {"CounterID", std::make_shared()}, + {"ClientIP", std::make_shared()}, + {"RegionID", std::make_shared()}, + {"UniqID", std::make_shared()}, + {"CounterClass", std::make_shared()}, + {"OS", std::make_shared()}, + {"UserAgent", std::make_shared()}, + {"URL", std::make_shared()}, + {"Referer", std::make_shared()}, + {"ResolutionWidth", std::make_shared()}, + {"ResolutionHeight", std::make_shared()}, + {"ResolutionDepth", std::make_shared()}, + {"FlashMajor", std::make_shared()}, + {"FlashMinor", std::make_shared()}, + {"FlashMinor2", std::make_shared()}, + {"NetMajor", std::make_shared()}, + {"NetMinor", std::make_shared()}, + {"UserAgentMajor", std::make_shared()}, + {"UserAgentMinor", std::make_shared(2)}, + {"CookieEnable", std::make_shared()}, + {"JavascriptEnable", std::make_shared()}, + {"IsMobile", std::make_shared()}, + {"MobilePhone", std::make_shared()}, + {"MobilePhoneModel", std::make_shared()}, + {"Params", std::make_shared()}, + {"IPNetworkID", std::make_shared()}, + {"TraficSourceID", std::make_shared()}, + {"SearchEngineID", std::make_shared()}, + {"SearchPhrase", std::make_shared()}, + {"AdvEngineID", std::make_shared()}, + {"IsArtifical", std::make_shared()}, + {"WindowClientWidth", std::make_shared()}, + {"WindowClientHeight", std::make_shared()}, + {"ClientTimeZone", std::make_shared()}, + {"ClientEventTime", std::make_shared()}, + {"SilverlightVersion1", std::make_shared()}, + {"SilverlightVersion2", std::make_shared()}, + {"SilverlightVersion3", std::make_shared()}, + {"SilverlightVersion4", std::make_shared()}, + {"PageCharset", std::make_shared()}, + {"CodeVersion", std::make_shared()}, + {"IsLink", std::make_shared()}, + {"IsDownload", std::make_shared()}, + {"IsNotBounce", std::make_shared()}, + {"FUniqID", std::make_shared()}, + {"OriginalURL", std::make_shared()}, + {"HID", std::make_shared()}, + {"IsOldCounter", std::make_shared()}, + {"IsEvent", std::make_shared()}, + {"IsParameter", std::make_shared()}, + {"DontCountHits", std::make_shared()}, + {"WithHash", std::make_shared()}, }; Names column_names; @@ -95,7 +95,9 @@ try /// create an object of an existing hit log table - StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list)); + StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list), + NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, DEFAULT_MAX_COMPRESS_BLOCK_SIZE); + table->startup(); /// read from it if (argc == 2 && 0 == strcmp(argv[1], "read")) diff --git a/dbms/src/DataStreams/tests/sorting_stream.cpp b/dbms/src/DataStreams/tests/sorting_stream.cpp index 483b9770d5a..aee3588ffdc 100644 --- a/dbms/src/DataStreams/tests/sorting_stream.cpp +++ b/dbms/src/DataStreams/tests/sorting_stream.cpp @@ -34,62 +34,62 @@ try { NamesAndTypesList names_and_types_list { - {"WatchID", std::make_shared()}, - {"JavaEnable", std::make_shared()}, - {"Title", std::make_shared()}, - {"EventTime", std::make_shared()}, - {"CounterID", std::make_shared()}, - {"ClientIP", std::make_shared()}, - {"RegionID", std::make_shared()}, - {"UniqID", std::make_shared()}, - {"CounterClass", std::make_shared()}, - {"OS", std::make_shared()}, - {"UserAgent", std::make_shared()}, - {"URL", std::make_shared()}, - {"Referer", std::make_shared()}, - {"ResolutionWidth", std::make_shared()}, - {"ResolutionHeight", std::make_shared()}, - {"ResolutionDepth", std::make_shared()}, - {"FlashMajor", std::make_shared()}, - {"FlashMinor", std::make_shared()}, - {"FlashMinor2", std::make_shared()}, - {"NetMajor", std::make_shared()}, - {"NetMinor", std::make_shared()}, - {"UserAgentMajor", std::make_shared()}, - {"UserAgentMinor", std::make_shared(2)}, - {"CookieEnable", std::make_shared()}, - {"JavascriptEnable", std::make_shared()}, - {"IsMobile", std::make_shared()}, - {"MobilePhone", std::make_shared()}, - {"MobilePhoneModel", std::make_shared()}, - {"Params", std::make_shared()}, - {"IPNetworkID", std::make_shared()}, - {"TraficSourceID", std::make_shared()}, - {"SearchEngineID", std::make_shared()}, - {"SearchPhrase", std::make_shared()}, - {"AdvEngineID", std::make_shared()}, - {"IsArtifical", std::make_shared()}, - {"WindowClientWidth", std::make_shared()}, - {"WindowClientHeight", std::make_shared()}, - {"ClientTimeZone", std::make_shared()}, - {"ClientEventTime", std::make_shared()}, - {"SilverlightVersion1", std::make_shared()}, - {"SilverlightVersion2", std::make_shared()}, - {"SilverlightVersion3", std::make_shared()}, - {"SilverlightVersion4", std::make_shared()}, - {"PageCharset", std::make_shared()}, - {"CodeVersion", std::make_shared()}, - {"IsLink", std::make_shared()}, - {"IsDownload", std::make_shared()}, - {"IsNotBounce", std::make_shared()}, - {"FUniqID", std::make_shared()}, - {"OriginalURL", std::make_shared()}, - {"HID", std::make_shared()}, - {"IsOldCounter", std::make_shared()}, - {"IsEvent", std::make_shared()}, - {"IsParameter", std::make_shared()}, - {"DontCountHits", std::make_shared()}, - {"WithHash", std::make_shared()}, + {"WatchID", std::make_shared()}, + {"JavaEnable", std::make_shared()}, + {"Title", std::make_shared()}, + {"EventTime", std::make_shared()}, + {"CounterID", std::make_shared()}, + {"ClientIP", std::make_shared()}, + {"RegionID", std::make_shared()}, + {"UniqID", std::make_shared()}, + {"CounterClass", std::make_shared()}, + {"OS", std::make_shared()}, + {"UserAgent", std::make_shared()}, + {"URL", std::make_shared()}, + {"Referer", std::make_shared()}, + {"ResolutionWidth", std::make_shared()}, + {"ResolutionHeight", std::make_shared()}, + {"ResolutionDepth", std::make_shared()}, + {"FlashMajor", std::make_shared()}, + {"FlashMinor", std::make_shared()}, + {"FlashMinor2", std::make_shared()}, + {"NetMajor", std::make_shared()}, + {"NetMinor", std::make_shared()}, + {"UserAgentMajor", std::make_shared()}, + {"UserAgentMinor", std::make_shared(2)}, + {"CookieEnable", std::make_shared()}, + {"JavascriptEnable", std::make_shared()}, + {"IsMobile", std::make_shared()}, + {"MobilePhone", std::make_shared()}, + {"MobilePhoneModel", std::make_shared()}, + {"Params", std::make_shared()}, + {"IPNetworkID", std::make_shared()}, + {"TraficSourceID", std::make_shared()}, + {"SearchEngineID", std::make_shared()}, + {"SearchPhrase", std::make_shared()}, + {"AdvEngineID", std::make_shared()}, + {"IsArtifical", std::make_shared()}, + {"WindowClientWidth", std::make_shared()}, + {"WindowClientHeight", std::make_shared()}, + {"ClientTimeZone", std::make_shared()}, + {"ClientEventTime", std::make_shared()}, + {"SilverlightVersion1", std::make_shared()}, + {"SilverlightVersion2", std::make_shared()}, + {"SilverlightVersion3", std::make_shared()}, + {"SilverlightVersion4", std::make_shared()}, + {"PageCharset", std::make_shared()}, + {"CodeVersion", std::make_shared()}, + {"IsLink", std::make_shared()}, + {"IsDownload", std::make_shared()}, + {"IsNotBounce", std::make_shared()}, + {"FUniqID", std::make_shared()}, + {"OriginalURL", std::make_shared()}, + {"HID", std::make_shared()}, + {"IsOldCounter", std::make_shared()}, + {"IsEvent", std::make_shared()}, + {"IsParameter", std::make_shared()}, + {"DontCountHits", std::make_shared()}, + {"WithHash", std::make_shared()}, }; using NamesAndTypesMap = std::map; @@ -107,7 +107,9 @@ try /// create an object of an existing hit log table - StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list)); + StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list), + NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, DEFAULT_MAX_COMPRESS_BLOCK_SIZE); + table->startup(); /// read from it, sort it, and write it in tsv form to the console diff --git a/dbms/src/DataStreams/tests/union_stream.cpp b/dbms/src/DataStreams/tests/union_stream.cpp index c7148ad77bb..0b4b684a397 100644 --- a/dbms/src/DataStreams/tests/union_stream.cpp +++ b/dbms/src/DataStreams/tests/union_stream.cpp @@ -25,7 +25,7 @@ using namespace DB; void test1() { Context context; - StoragePtr table = StorageSystemNumbers::create("numbers"); + StoragePtr table = StorageSystemNumbers::create("numbers", false); Names column_names; column_names.push_back("number"); @@ -55,7 +55,7 @@ void test1() void test2() { Context context; - StoragePtr table = StorageSystemNumbers::create("numbers"); + StoragePtr table = StorageSystemNumbers::create("numbers", false); Names column_names; column_names.push_back("number"); diff --git a/dbms/src/DataTypes/DataTypeArray.cpp b/dbms/src/DataTypes/DataTypeArray.cpp index 354851e767d..7ce4256e100 100644 --- a/dbms/src/DataTypes/DataTypeArray.cpp +++ b/dbms/src/DataTypes/DataTypeArray.cpp @@ -125,16 +125,16 @@ void DataTypeArray::serializeBinaryBulk(const IColumn & column, WriteBuffer & os } -void DataTypeArray::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double avg_value_size_hint) const +void DataTypeArray::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, size_t limit, double) const { ColumnArray & column_array = typeid_cast(column); ColumnArray::Offsets_t & offsets = column_array.getOffsets(); IColumn & nested_column = column_array.getData(); - /// Number of values correlated with `offsets` must be read. + /// Number of values corresponding with `offsets` must be read. size_t last_offset = (offsets.empty() ? 0 : offsets.back()); if (last_offset < nested_column.size()) - throw Exception("Nested column longer than last offset", ErrorCodes::LOGICAL_ERROR); + throw Exception("Nested column is longer than last offset", ErrorCodes::LOGICAL_ERROR); size_t nested_limit = last_offset - nested_column.size(); nested->deserializeBinaryBulk(nested_column, istr, nested_limit, 0); diff --git a/dbms/src/DataTypes/DataTypeFactory.cpp b/dbms/src/DataTypes/DataTypeFactory.cpp index 0630f4907f1..3e69d997cd2 100644 --- a/dbms/src/DataTypes/DataTypeFactory.cpp +++ b/dbms/src/DataTypes/DataTypeFactory.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include namespace DB diff --git a/dbms/src/DataTypes/DataTypeString.cpp b/dbms/src/DataTypes/DataTypeString.cpp index b36366f8737..b6da739316a 100644 --- a/dbms/src/DataTypes/DataTypeString.cpp +++ b/dbms/src/DataTypes/DataTypeString.cpp @@ -184,11 +184,11 @@ void DataTypeString::deserializeBinaryBulk(IColumn & column, ReadBuffer & istr, } else { - /** A small heuristic to evaluate that there are a lot of empty lines in the column. + /** A small heuristic to evaluate that there are a lot of empty strings in the column. * In this case, to save RAM, we will say that the average size of the value is small. */ if (istr.position() + sizeof(UInt32) <= istr.buffer().end() - && unalignedLoad(istr.position()) == 0) /// The first 4 rows are in the buffer and are empty. + && unalignedLoad(istr.position()) == 0) /// The first 4 strings are in the buffer and are empty. { avg_chars_size = 1; } diff --git a/dbms/src/DataTypes/DataTypeTuple.cpp b/dbms/src/DataTypes/DataTypeTuple.cpp index 62610ee6107..839e113a98c 100644 --- a/dbms/src/DataTypes/DataTypeTuple.cpp +++ b/dbms/src/DataTypes/DataTypeTuple.cpp @@ -4,9 +4,9 @@ #include #include -#include -#include -#include +#include +#include +#include namespace DB diff --git a/dbms/src/DataTypes/FieldToDataType.cpp b/dbms/src/DataTypes/FieldToDataType.cpp index 2dcbb13114b..ef6636b3b1c 100644 --- a/dbms/src/DataTypes/FieldToDataType.cpp +++ b/dbms/src/DataTypes/FieldToDataType.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include namespace DB diff --git a/dbms/src/Databases/DatabaseCloud.cpp b/dbms/src/Databases/DatabaseCloud.cpp index 32609eeef2c..c27e44a69df 100644 --- a/dbms/src/Databases/DatabaseCloud.cpp +++ b/dbms/src/Databases/DatabaseCloud.cpp @@ -414,6 +414,8 @@ StoragePtr DatabaseCloud::tryGetTable(const String & table_name) definition, name, data_path, context, false, "in zookeeper node " + zookeeper_path + "/table_definitions/" + hashToHex(table_hash)); + table->startup(); + local_tables_cache.emplace(table_name, table); return table; } diff --git a/dbms/src/Databases/DatabaseOrdinary.cpp b/dbms/src/Databases/DatabaseOrdinary.cpp index d7223319b2d..ea4b66a01cb 100644 --- a/dbms/src/Databases/DatabaseOrdinary.cpp +++ b/dbms/src/Databases/DatabaseOrdinary.cpp @@ -181,6 +181,60 @@ void DatabaseOrdinary::loadTables(Context & context, ThreadPool * thread_pool, b task(); } + if (thread_pool) + thread_pool->wait(); + + /// After all tables was basically initialized, startup them. + startupTables(thread_pool); +} + + +void DatabaseOrdinary::startupTables(ThreadPool * thread_pool) +{ + LOG_INFO(log, "Starting up tables."); + + StopwatchWithLock watch; + std::atomic tables_processed {0}; + size_t total_tables = tables.size(); + + auto task_function = [&](Tables::iterator begin, Tables::iterator end) + { + for (Tables::iterator it = begin; it != end; ++it) + { + if ((++tables_processed) % PRINT_MESSAGE_EACH_N_TABLES == 0 + || watch.lockTestAndRestart(PRINT_MESSAGE_EACH_N_SECONDS)) + { + LOG_INFO(log, std::fixed << std::setprecision(2) << tables_processed * 100.0 / total_tables << "%"); + watch.restart(); + } + + it->second->startup(); + } + }; + + const size_t bunch_size = TABLES_PARALLEL_LOAD_BUNCH_SIZE; + size_t num_bunches = (total_tables + bunch_size - 1) / bunch_size; + + Tables::iterator begin = tables.begin(); + for (size_t i = 0; i < num_bunches; ++i) + { + auto end = begin; + + if (i + 1 == num_bunches) + end = tables.end(); + else + std::advance(end, bunch_size); + + auto task = std::bind(task_function, begin, end); + + if (thread_pool) + thread_pool->schedule(task); + else + task(); + + begin = end; + } + if (thread_pool) thread_pool->wait(); } diff --git a/dbms/src/Databases/DatabaseOrdinary.h b/dbms/src/Databases/DatabaseOrdinary.h index 2e0080769d1..6e04bd57d5d 100644 --- a/dbms/src/Databases/DatabaseOrdinary.h +++ b/dbms/src/Databases/DatabaseOrdinary.h @@ -45,6 +45,9 @@ public: const NamesAndTypesList & alias_columns, const ColumnDefaults & column_defaults, const ASTModifier & engine_modifier) override; + +private: + void startupTables(ThreadPool * thread_pool); }; } diff --git a/dbms/src/Databases/DatabasesCommon.h b/dbms/src/Databases/DatabasesCommon.h index 84cc9828893..e7a0009bb93 100644 --- a/dbms/src/Databases/DatabasesCommon.h +++ b/dbms/src/Databases/DatabasesCommon.h @@ -24,6 +24,7 @@ String getTableDefinitionFromCreateQuery(const ASTPtr & query); /** Create a table by its definition, without using InterpreterCreateQuery. * (InterpreterCreateQuery has more complex functionality, and it can not be used if the database has not been created yet) * Returns the table name and the table itself. + * You must subsequently call IStorage::startup method to use the table. */ std::pair createTableFromDefinition( const String & definition, diff --git a/dbms/src/Dictionaries/CacheDictionary.cpp b/dbms/src/Dictionaries/CacheDictionary.cpp index ad0dc806e02..42c8919a5b6 100644 --- a/dbms/src/Dictionaries/CacheDictionary.cpp +++ b/dbms/src/Dictionaries/CacheDictionary.cpp @@ -8,9 +8,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include namespace ProfileEvents diff --git a/dbms/src/Dictionaries/CacheDictionary.h b/dbms/src/Dictionaries/CacheDictionary.h index 72f24a35976..13bf196fc35 100644 --- a/dbms/src/Dictionaries/CacheDictionary.h +++ b/dbms/src/Dictionaries/CacheDictionary.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/ClickHouseDictionarySource.cpp b/dbms/src/Dictionaries/ClickHouseDictionarySource.cpp index e055e1828bd..9ed2783d0fb 100644 --- a/dbms/src/Dictionaries/ClickHouseDictionarySource.cpp +++ b/dbms/src/Dictionaries/ClickHouseDictionarySource.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include namespace DB diff --git a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp index 1c62b3bdd89..f235be8107b 100644 --- a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp +++ b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include namespace ProfileEvents diff --git a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h index 76f0077cdd4..ad7b3a3e33a 100644 --- a/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h +++ b/dbms/src/Dictionaries/ComplexKeyCacheDictionary.h @@ -9,9 +9,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp index b19bc0c8bd4..ea522f2d743 100644 --- a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp +++ b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include diff --git a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h index e8992b3782b..493897766c4 100644 --- a/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h +++ b/dbms/src/Dictionaries/ComplexKeyHashedDictionary.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/DictionaryStructure.h b/dbms/src/Dictionaries/DictionaryStructure.h index 5e8bf629eb5..cddfc373195 100644 --- a/dbms/src/Dictionaries/DictionaryStructure.h +++ b/dbms/src/Dictionaries/DictionaryStructure.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/ExternalQueryBuilder.cpp b/dbms/src/Dictionaries/ExternalQueryBuilder.cpp index d6dd9bcbd17..94865a55be3 100644 --- a/dbms/src/Dictionaries/ExternalQueryBuilder.cpp +++ b/dbms/src/Dictionaries/ExternalQueryBuilder.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/ExternalResultDescription.cpp b/dbms/src/Dictionaries/ExternalResultDescription.cpp index 2df381770ac..613a4a5dd1f 100644 --- a/dbms/src/Dictionaries/ExternalResultDescription.cpp +++ b/dbms/src/Dictionaries/ExternalResultDescription.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/FlatDictionary.h b/dbms/src/Dictionaries/FlatDictionary.h index 6ca4526dfe0..02162b9dc5b 100644 --- a/dbms/src/Dictionaries/FlatDictionary.h +++ b/dbms/src/Dictionaries/FlatDictionary.h @@ -5,8 +5,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/HashedDictionary.cpp b/dbms/src/Dictionaries/HashedDictionary.cpp index 1ba12c67574..8475a2a9579 100644 --- a/dbms/src/Dictionaries/HashedDictionary.cpp +++ b/dbms/src/Dictionaries/HashedDictionary.cpp @@ -1,4 +1,4 @@ -#include +#include #include diff --git a/dbms/src/Dictionaries/HashedDictionary.h b/dbms/src/Dictionaries/HashedDictionary.h index acc77c080e0..f13a9520c27 100644 --- a/dbms/src/Dictionaries/HashedDictionary.h +++ b/dbms/src/Dictionaries/HashedDictionary.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/MongoDBBlockInputStream.cpp b/dbms/src/Dictionaries/MongoDBBlockInputStream.cpp index 43cc6bb81f5..ae5803249b5 100644 --- a/dbms/src/Dictionaries/MongoDBBlockInputStream.cpp +++ b/dbms/src/Dictionaries/MongoDBBlockInputStream.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include diff --git a/dbms/src/Dictionaries/MongoDBDictionarySource.cpp b/dbms/src/Dictionaries/MongoDBDictionarySource.cpp index 3badb8890a3..7728fcfaf18 100644 --- a/dbms/src/Dictionaries/MongoDBDictionarySource.cpp +++ b/dbms/src/Dictionaries/MongoDBDictionarySource.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include namespace DB diff --git a/dbms/src/Dictionaries/MySQLBlockInputStream.cpp b/dbms/src/Dictionaries/MySQLBlockInputStream.cpp index 9fae0f22328..0172f231a29 100644 --- a/dbms/src/Dictionaries/MySQLBlockInputStream.cpp +++ b/dbms/src/Dictionaries/MySQLBlockInputStream.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include diff --git a/dbms/src/Dictionaries/MySQLDictionarySource.h b/dbms/src/Dictionaries/MySQLDictionarySource.h index df659e8f693..37964557bb8 100644 --- a/dbms/src/Dictionaries/MySQLDictionarySource.h +++ b/dbms/src/Dictionaries/MySQLDictionarySource.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Dictionaries/ODBCBlockInputStream.cpp b/dbms/src/Dictionaries/ODBCBlockInputStream.cpp index 1c2ceca6bc1..ab3941fdad8 100644 --- a/dbms/src/Dictionaries/ODBCBlockInputStream.cpp +++ b/dbms/src/Dictionaries/ODBCBlockInputStream.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include diff --git a/dbms/src/Dictionaries/RangeHashedDictionary.h b/dbms/src/Dictionaries/RangeHashedDictionary.h index 142b2e31782..6f0a503ce41 100644 --- a/dbms/src/Dictionaries/RangeHashedDictionary.h +++ b/dbms/src/Dictionaries/RangeHashedDictionary.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/TrieDictionary.cpp b/dbms/src/Dictionaries/TrieDictionary.cpp index 689e3bc0124..6da424e2d3a 100644 --- a/dbms/src/Dictionaries/TrieDictionary.cpp +++ b/dbms/src/Dictionaries/TrieDictionary.cpp @@ -1,5 +1,5 @@ -#include -#include +#include +#include #include #include #include diff --git a/dbms/src/Dictionaries/TrieDictionary.h b/dbms/src/Dictionaries/TrieDictionary.h index b42bd122ad6..b5e0b44869a 100644 --- a/dbms/src/Dictionaries/TrieDictionary.h +++ b/dbms/src/Dictionaries/TrieDictionary.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Functions/FunctionsArray.h b/dbms/src/Functions/FunctionsArray.h index 1bbba0cad50..a295a8b0ece 100644 --- a/dbms/src/Functions/FunctionsArray.h +++ b/dbms/src/Functions/FunctionsArray.h @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/dbms/src/Functions/FunctionsCharset.cpp b/dbms/src/Functions/FunctionsCharset.cpp index 284581477ab..e0894fbcf50 100644 --- a/dbms/src/Functions/FunctionsCharset.cpp +++ b/dbms/src/Functions/FunctionsCharset.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include diff --git a/dbms/src/Functions/FunctionsCoding.h b/dbms/src/Functions/FunctionsCoding.h index e05741dadc6..fe66887da17 100644 --- a/dbms/src/Functions/FunctionsCoding.h +++ b/dbms/src/Functions/FunctionsCoding.h @@ -17,7 +17,7 @@ #include #include -#include +#include #include diff --git a/dbms/src/Functions/FunctionsConversion.h b/dbms/src/Functions/FunctionsConversion.h index b7a8cae759f..4b0cc6209b7 100644 --- a/dbms/src/Functions/FunctionsConversion.h +++ b/dbms/src/Functions/FunctionsConversion.h @@ -1,8 +1,8 @@ #pragma once -#include -#include -#include +#include +#include +#include #include #include diff --git a/dbms/src/Functions/FunctionsExternalDictionaries.h b/dbms/src/Functions/FunctionsExternalDictionaries.h index 8548d9be5ea..b6bd69ae33c 100644 --- a/dbms/src/Functions/FunctionsExternalDictionaries.h +++ b/dbms/src/Functions/FunctionsExternalDictionaries.h @@ -25,7 +25,7 @@ #include #include -#include +#include namespace DB diff --git a/dbms/src/Functions/FunctionsGeo.h b/dbms/src/Functions/FunctionsGeo.h index aaa76c6b0f9..cb3c03f6b5a 100644 --- a/dbms/src/Functions/FunctionsGeo.h +++ b/dbms/src/Functions/FunctionsGeo.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Functions/FunctionsHashing.h b/dbms/src/Functions/FunctionsHashing.h index dea49170d92..0339503d555 100644 --- a/dbms/src/Functions/FunctionsHashing.h +++ b/dbms/src/Functions/FunctionsHashing.h @@ -25,7 +25,7 @@ #include #include -#include +#include namespace DB diff --git a/dbms/src/Functions/FunctionsMiscellaneous.cpp b/dbms/src/Functions/FunctionsMiscellaneous.cpp index ebef13e405b..bc1d0cf8ffb 100644 --- a/dbms/src/Functions/FunctionsMiscellaneous.cpp +++ b/dbms/src/Functions/FunctionsMiscellaneous.cpp @@ -1,7 +1,7 @@ #include #include -#include +#include #include #include #include diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index 4e2c82b73cd..b22bd8c2aa3 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include #include diff --git a/dbms/src/Interpreters/AggregateDescription.h b/dbms/src/Interpreters/AggregateDescription.h index de770eba50a..dece93c9093 100644 --- a/dbms/src/Interpreters/AggregateDescription.h +++ b/dbms/src/Interpreters/AggregateDescription.h @@ -11,10 +11,10 @@ namespace DB struct AggregateDescription { AggregateFunctionPtr function; - Array parameters; /// Параметры (параметрической) агрегатной функции. + Array parameters; /// Parameters of the (parametric) aggregate function. ColumnNumbers arguments; - Names argument_names; /// Используются, если arguments не заданы. - String column_name; /// Какое имя использовать для столбца со значениями агрегатной функции + Names argument_names; /// used if no `arguments` are specified. + String column_name; /// What name to use for a column with aggregate function values }; using AggregateDescriptions = std::vector; diff --git a/dbms/src/Interpreters/AggregationCommon.h b/dbms/src/Interpreters/AggregationCommon.h index 84b34c0f9ea..a8685f65fd4 100644 --- a/dbms/src/Interpreters/AggregationCommon.h +++ b/dbms/src/Interpreters/AggregationCommon.h @@ -181,7 +181,7 @@ static inline UInt128 ALWAYS_INLINE hash128( for (size_t j = 0; j < keys_size; ++j) { - /// Хэшируем ключ. + /// Hashes the key. keys[j] = key_columns[j]->getDataAtWithTerminatingZero(i); hash.update(keys[j].data, keys[j].size); } @@ -208,18 +208,18 @@ static inline UInt128 ALWAYS_INLINE hash128( } -/// Скопировать ключи в пул. Потом разместить в пуле StringRef-ы на них и вернуть указатель на первый. +/// Copy keys to the pool. Then put into pool StringRefs to them and return the pointer to the first. static inline StringRef * ALWAYS_INLINE placeKeysInPool( size_t i, size_t keys_size, StringRefs & keys, Arena & pool) { for (size_t j = 0; j < keys_size; ++j) { char * place = pool.alloc(keys[j].size); - memcpy(place, keys[j].data, keys[j].size); /// TODO padding в Arena и memcpySmall + memcpy(place, keys[j].data, keys[j].size); /// TODO padding in Arena and memcpySmall keys[j].data = place; } - /// Размещаем в пуле StringRef-ы на только что скопированные ключи. + /// Place the StringRefs on the newly copied keys in the pool. char * res = pool.alloc(keys_size * sizeof(StringRef)); memcpy(res, &keys[0], keys_size * sizeof(StringRef)); @@ -227,7 +227,7 @@ static inline StringRef * ALWAYS_INLINE placeKeysInPool( } -/// Скопировать ключи в пул. Потом разместить в пуле StringRef-ы на них и вернуть указатель на первый. +/// Copy keys to the pool. Then put into pool StringRefs to them and return the pointer to the first. static inline StringRef * ALWAYS_INLINE extractKeysAndPlaceInPool( size_t i, size_t keys_size, const ConstColumnPlainPtrs & key_columns, StringRefs & keys, Arena & pool) { @@ -239,7 +239,7 @@ static inline StringRef * ALWAYS_INLINE extractKeysAndPlaceInPool( keys[j].data = place; } - /// Размещаем в пуле StringRef-ы на только что скопированные ключи. + /// Place the StringRefs on the newly copied keys in the pool. char * res = pool.alloc(keys_size * sizeof(StringRef)); memcpy(res, &keys[0], keys_size * sizeof(StringRef)); @@ -280,14 +280,14 @@ inline StringRef ALWAYS_INLINE extractKeysAndPlaceInPoolContiguous( place += keys[j].size; } - /// Размещаем в пуле StringRef-ы на только что скопированные ключи. + /// Place the StringRefs on the newly copied keys in the pool. memcpy(place, &keys[0], keys_size * sizeof(StringRef)); return {res, sum_keys_size}; } -/** Сериализовать ключи в непрерывный кусок памяти. +/** Serialize keys into a continuous chunk of memory. */ static inline StringRef ALWAYS_INLINE serializeKeysToPoolContiguous( size_t i, size_t keys_size, const ConstColumnPlainPtrs & key_columns, StringRefs & keys, Arena & pool) diff --git a/dbms/src/Interpreters/Aggregator.h b/dbms/src/Interpreters/Aggregator.h index 58a0342d53b..9802cf5ae96 100644 --- a/dbms/src/Interpreters/Aggregator.h +++ b/dbms/src/Interpreters/Aggregator.h @@ -39,23 +39,23 @@ namespace ErrorCodes class IBlockOutputStream; -/** Разные структуры данных, которые могут использоваться для агрегации - * Для эффективности, сами данные для агрегации кладутся в пул. - * Владение данными (состояний агрегатных функций) и пулом - * захватывается позднее - в функции convertToBlocks, объектом ColumnAggregateFunction. +/** Different data structures that can be used for aggregation + * For efficiency, the aggregation data itself is put into the pool. + * Data and pool ownership (states of aggregate functions) + * is acquired later - in `convertToBlocks` function, by the ColumnAggregateFunction object. * - * Большинство структур данных существует в двух вариантах: обычном и двухуровневом (TwoLevel). - * Двухуровневая хэш-таблица работает чуть медленнее при маленьком количестве различных ключей, - * но при большом количестве различных ключей лучше масштабируется, так как позволяет - * распараллелить некоторые операции (слияние, пост-обработку) естественным образом. + * Most data structures exist in two versions: normal and two-level (TwoLevel). + * A two-level hash table works a little slower with a small number of different keys, + * but with a large number of different keys scales better, because it allows + * parallelize some operations (merging, post-processing) in a natural way. * - * Чтобы обеспечить эффективную работу в большом диапазоне условий, - * сначала используются одноуровневые хэш-таблицы, - * а при достижении количеством различных ключей достаточно большого размера, - * они конвертируются в двухуровневые. + * To ensure efficient work over a wide range of conditions, + * first single-level hash tables are used, + * and when the number of different keys is large enough, + * they are converted to two-level ones. * - * PS. Существует много различных подходов к эффективной реализации параллельной и распределённой агрегации, - * лучшим образом подходящих для разных случаев, и этот подход - всего лишь один из них, выбранный по совокупности причин. + * PS. There are many different approaches to the effective implementation of parallel and distributed aggregation, + * best suited for different cases, and this approach is just one of them, chosen for a combination of reasons. */ using AggregatedDataWithoutKey = AggregateDataPtr; @@ -88,8 +88,8 @@ using AggregatedDataWithKeys128Hash64 = HashMap; -/// Для случая, когда есть один числовой ключ. -template /// UInt8/16/32/64 для любых типов соответствующей битности. +/// For the case where there is one numeric key. +template /// UInt8/16/32/64 for any type with corresponding bit width. struct AggregationMethodOneNumber { using Data = TData; @@ -105,51 +105,51 @@ struct AggregationMethodOneNumber template AggregationMethodOneNumber(const Other & other) : data(other.data) {} - /// Для использования одного Method в разных потоках, используйте разные State. + /// To use one `Method` in different threads, use different `State`. struct State { const FieldType * vec; - /** Вызывается в начале обработки каждого блока. - * Устанавливает переменные, необходимые для остальных методов, вызываемых во внутренних циклах. + /** Called at the start of each block processing. + * Sets the variables needed for the other methods called in internal loops. */ void init(ConstColumnPlainPtrs & key_columns) { vec = &static_cast *>(key_columns[0])->getData()[0]; } - /// Достать из ключевых столбцов ключ для вставки в хэш-таблицу. + /// Get the key from the key columns for insertion into the hash table. Key getKey( - const ConstColumnPlainPtrs & key_columns, /// Ключевые столбцы. - size_t keys_size, /// Количество ключевых столбцов. - size_t i, /// Из какой строки блока достать ключ. - const Sizes & key_sizes, /// Если ключи фиксированной длины - их длины. Не используется в методах агрегации по ключам переменной длины. - StringRefs & keys, /// Сюда могут быть записаны ссылки на данные ключей в столбцах. Они могут быть использованы в дальнейшем. + const ConstColumnPlainPtrs & key_columns, /// Key columns. + size_t keys_size, /// Number of key columns. + size_t i, /// From which row of the block, get the key. + const Sizes & key_sizes, /// If the keys of a fixed length - their lengths. It is not used in aggregation methods for variable length keys. + StringRefs & keys, /// Here references to key data in columns can be written. They can be used in the future. Arena & pool) const { return unionCastToUInt64(vec[i]); } }; - /// Из значения в хэш-таблице получить AggregateDataPtr. + /// From the value in the hash table, get AggregateDataPtr. static AggregateDataPtr & getAggregateData(Mapped & value) { return value; } static const AggregateDataPtr & getAggregateData(const Mapped & value) { return value; } - /** Разместить дополнительные данные, если это необходимо, в случае, когда в хэш-таблицу был вставлен новый ключ. + /** Place additional data, if necessary, in case a new key was inserted into the hash table. */ static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, StringRefs & keys, Arena & pool) { } - /** Действие, которое нужно сделать, если ключ не новый. Например, откатить выделение памяти в пуле. + /** The action to be taken if the key is not new. For example, roll back the memory allocation in the pool. */ static void onExistingKey(const Key & key, StringRefs & keys, Arena & pool) {} - /** Не использовать оптимизацию для идущих подряд ключей. + /** Do not use optimization for consecutive keys. */ static const bool no_consecutive_keys_optimization = false; - /** Вставить ключ из хэш-таблицы в столбцы. + /** Insert the key from the hash table into columns. */ static void insertKeyIntoColumns(const typename Data::value_type & value, ColumnPlainPtrs & key_columns, size_t keys_size, const Sizes & key_sizes) { @@ -158,7 +158,7 @@ struct AggregationMethodOneNumber }; -/// Для случая, когда есть один строковый ключ. +/// For the case where there is one string key. template struct AggregationMethodString { @@ -221,7 +221,7 @@ struct AggregationMethodString }; -/// Для случая, когда есть один строковый ключ фиксированной длины. +/// For the case where there is one fixed-length string key. template struct AggregationMethodFixedString { @@ -378,7 +378,7 @@ protected: } -/// Для случая, когда все ключи фиксированной длины, и они помещаются в N (например, 128) бит. +/// For the case where all keys are of fixed length, and they fit in N (for example, 128) bits. template struct AggregationMethodKeysFixed { @@ -487,7 +487,7 @@ struct AggregationMethodKeysFixed }; -/// Агрегирует по конкатенации ключей. (При этом, строки, содержащие нули посередине, могут склеиться.) +/// Aggregates by key concatenation. (In this case, strings containing zeros in the middle can stick together.) template struct AggregationMethodConcat { @@ -534,7 +534,7 @@ struct AggregationMethodConcat pool.rollback(key.size + keys.size() * sizeof(keys[0])); } - /// Если ключ уже был, то он удаляется из пула (затирается), и сравнить с ним следующий ключ уже нельзя. + /// If the key already was, then it is removed from the pool (overwritten), and the next key can not be compared with it. static const bool no_consecutive_keys_optimization = true; static void insertKeyIntoColumns(const typename Data::value_type & value, ColumnPlainPtrs & key_columns, size_t keys_size, const Sizes & key_sizes) @@ -546,14 +546,14 @@ private: /// Insert the values of the specified keys into the corresponding columns. static void insertKeyIntoColumnsImpl(const typename Data::value_type & value, ColumnPlainPtrs & key_columns, size_t keys_size, const Sizes & key_sizes) { - /// См. функцию extractKeysAndPlaceInPoolContiguous. + /// See function extractKeysAndPlaceInPoolContiguous. const StringRef * key_refs = reinterpret_cast(value.first.data + value.first.size); if (unlikely(0 == value.first.size)) { - /** Исправление, если все ключи - пустые массивы. Для них в хэш-таблицу записывается StringRef нулевой длины, но с ненулевым указателем. - * Но при вставке в хэш-таблицу, такой StringRef оказывается равен другому ключу нулевой длины, - * у которого указатель на данные может быть любым мусором и использовать его нельзя. + /** Fix if all keys are empty arrays. For them, a zero-length StringRef is written to the hash table, but with a non-zero pointer. + * But when inserted into a hash table, this StringRef occurs equal to another key of zero length, + * whose data pointer can be any garbage and can not be used. */ for (size_t i = 0; i < keys_size; ++i) key_columns[i]->insertDefault(); @@ -567,11 +567,11 @@ private: }; -/** Агрегирует по конкатенации сериализованных значений ключей. - * Похож на AggregationMethodConcat, но подходит, например, для массивов строк или нескольких массивов. - * Сериализованное значение отличается тем, что позволяет однозначно его десериализовать, имея только позицию, с которой оно начинается. - * То есть, например, для строк, оно содержит сначала сериализованную длину строки, а потом байты. - * Поэтому, при агрегации по нескольким строкам, неоднозначностей не возникает. +/** Aggregates by concatenating serialized key values. + * Similar to AggregationMethodConcat, but it is suitable, for example, for arrays of strings or multiple arrays. + * The serialized value differs in that it uniquely allows to deserialize it, having only the position with which it starts. + * That is, for example, for strings, it contains first the serialized length of the string, and then the bytes. + * Therefore, when aggregating by several strings, there is no ambiguity. */ template struct AggregationMethodSerialized @@ -619,7 +619,7 @@ struct AggregationMethodSerialized pool.rollback(key.size); } - /// Если ключ уже был, то он удаляется из пула (затирается), и сравнить с ним следующий ключ уже нельзя. + /// If the key already was, it is removed from the pool (overwritten), and the next key can not be compared with it. static const bool no_consecutive_keys_optimization = true; static void insertKeyIntoColumns(const typename Data::value_type & value, ColumnPlainPtrs & key_columns, size_t keys_size, const Sizes & key_sizes) @@ -631,7 +631,7 @@ struct AggregationMethodSerialized }; -/// Для остальных случаев. Агрегирует по 128 битному хэшу от ключа. +/// For other cases. Aggregates by 128-bit hash from the key. template struct AggregationMethodHashed { @@ -690,33 +690,33 @@ class Aggregator; struct AggregatedDataVariants : private boost::noncopyable { - /** Работа с состояниями агрегатных функций в пуле устроена следующим (неудобным) образом: - * - при агрегации, состояния создаются в пуле с помощью функции IAggregateFunction::create (внутри - placement new произвольной структуры); - * - они должны быть затем уничтожены с помощью IAggregateFunction::destroy (внутри - вызов деструктора произвольной структуры); - * - если агрегация завершена, то, в функции Aggregator::convertToBlocks, указатели на состояния агрегатных функций - * записываются в ColumnAggregateFunction; ColumnAggregateFunction "захватывает владение" ими, то есть - вызывает destroy в своём деструкторе. - * - если при агрегации, до вызова Aggregator::convertToBlocks вылетело исключение, - * то состояния агрегатных функций всё-равно должны быть уничтожены, - * иначе для сложных состояний (наприемер, AggregateFunctionUniq), будут утечки памяти; - * - чтобы, в этом случае, уничтожить состояния, в деструкторе вызывается метод Aggregator::destroyAggregateStates, - * но только если переменная aggregator (см. ниже) не nullptr; - * - то есть, пока вы не передали владение состояниями агрегатных функций в ColumnAggregateFunction, установите переменную aggregator, - * чтобы при возникновении исключения, состояния были корректно уничтожены. + /** Working with states of aggregate functions in the pool is arranged in the following (inconvenient) way: + * - when aggregating, states are created in the pool using IAggregateFunction::create (inside - `placement new` of arbitrary structure); + * - they must then be destroyed using IAggregateFunction::destroy (inside - calling the destructor of arbitrary structure); + * - if aggregation is complete, then, in the Aggregator::convertToBlocks function, pointers to the states of aggregate functions + * are written to ColumnAggregateFunction; ColumnAggregateFunction "acquires ownership" of them, that is - calls `destroy` in its destructor. + * - if during the aggregation, before call to Aggregator::convertToBlocks, an exception was thrown, + * then the states of aggregate functions must still be destroyed, + * otherwise, for complex states (eg, AggregateFunctionUniq), there will be memory leaks; + * - in this case, to destroy states, the destructor calls Aggregator::destroyAggregateStates method, + * but only if the variable aggregator (see below) is not nullptr; + * - that is, until you transfer ownership of the aggregate function states in the ColumnAggregateFunction, set the variable `aggregator`, + * so that when an exception occurs, the states are correctly destroyed. * - * PS. Это можно исправить, сделав пул, который знает о том, какие состояния агрегатных функций и в каком порядке в него уложены, и умеет сам их уничтожать. - * Но это вряд ли можно просто сделать, так как в этот же пул планируется класть строки переменной длины. - * В этом случае, пул не сможет знать, по каким смещениям хранятся объекты. + * PS. This can be corrected by making a pool that knows about which states of aggregate functions and in which order are put in it, and knows how to destroy them. + * But this can hardly be done simply because it is planned to put variable-length strings into the same pool. + * In this case, the pool will not be able to know with what offsets objects are stored. */ Aggregator * aggregator = nullptr; - size_t keys_size; /// Количество ключей NOTE нужно ли это поле? - Sizes key_sizes; /// Размеры ключей, если ключи фиксированной длины + size_t keys_size; /// Number of keys. NOTE do we need this field? + Sizes key_sizes; /// Dimensions of keys, if keys of fixed length - /// Пулы для состояний агрегатных функций. Владение потом будет передано в ColumnAggregateFunction. + /// Pools for states of aggregate functions. Ownership will be later transferred to ColumnAggregateFunction. Arenas aggregates_pools; - Arena * aggregates_pool; /// Пул, который сейчас используется для аллокации. + Arena * aggregates_pool; /// The pool that is currently used for allocation. - /** Специализация для случая, когда ключи отсутствуют, и для ключей, не попавших в max_rows_to_group_by. + /** Specialization for the case when there are no keys, and for keys not fitted into max_rows_to_group_by. */ AggregatedDataWithoutKey without_key = nullptr; @@ -757,7 +757,7 @@ struct AggregatedDataVariants : private boost::noncopyable std::unique_ptr> nullable_keys128_two_level; std::unique_ptr> nullable_keys256_two_level; - /// В этом и подобных макросах, вариант without_key не учитывается. + /// In this and similar macros, the option without_key is not considered. #define APPLY_FOR_AGGREGATED_VARIANTS(M) \ M(key8, false) \ M(key16, false) \ @@ -827,7 +827,7 @@ struct AggregatedDataVariants : private boost::noncopyable type = type_; } - /// Количество строк (разных ключей). + /// Number of rows (different keys). size_t size() const { switch (type) @@ -845,7 +845,7 @@ struct AggregatedDataVariants : private boost::noncopyable } } - /// Размер без учёта строчки, в которую записываются данные для расчёта TOTALS. + /// The size without taking into account the row in which data is written for the calculation of TOTALS. size_t sizeWithoutOverflowRow() const { switch (type) @@ -959,52 +959,52 @@ struct AggregatedDataVariants : private boost::noncopyable using AggregatedDataVariantsPtr = std::shared_ptr; using ManyAggregatedDataVariants = std::vector; -/** Как считаются "тотальные" значения при наличии WITH TOTALS? - * (Более подробно смотрите в TotalsHavingBlockInputStream.) +/** How are "total" values calculated with WITH TOTALS? + * (For more details, see TotalsHavingBlockInputStream.) * - * В случае отсутствия group_by_overflow_mode = 'any', данные агрегируются как обычно, но состояния агрегатных функций не финализируются. - * Позже, состояния агрегатных функций для всех строк (прошедших через HAVING) мерджатся в одну - это и будет TOTALS. + * In the absence of group_by_overflow_mode = 'any', the data is aggregated as usual, but the states of the aggregate functions are not finalized. + * Later, the aggregate function states for all rows (passed through HAVING) are merged into one - this will be TOTALS. * - * В случае наличия group_by_overflow_mode = 'any', данные агрегируются как обычно, кроме ключей, не поместившихся в max_rows_to_group_by. - * Для этих ключей, данные агрегируются в одну дополнительную строку - далее см. под названиями overflow_row, overflows... - * Позже, состояния агрегатных функций для всех строк (прошедших через HAVING) мерджатся в одну, - * а также к ним прибавляется или не прибавляется (в зависимости от настройки totals_mode) также overflow_row - это и будет TOTALS. + * If there is group_by_overflow_mode = 'any', the data is aggregated as usual, except for the keys that did not fit in max_rows_to_group_by. + * For these keys, the data is aggregated into one additional row - see below under the names `overflow_row`, `overflows`... + * Later, the aggregate function states for all rows (passed through HAVING) are merged into one, + * also overflow_row is added or not added (depending on the totals_mode setting) also - this will be TOTALS. */ -/** Агрегирует источник блоков. +/** Aggregates the source of the blocks. */ class Aggregator { public: struct Params { - /// Что считать. + /// What to count. Names key_names; - ColumnNumbers keys; /// Номера столбцов - вычисляются позже. + ColumnNumbers keys; /// The column numbers are computed later. AggregateDescriptions aggregates; size_t keys_size; size_t aggregates_size; - /// Настройки приближённого вычисления GROUP BY. - const bool overflow_row; /// Нужно ли класть в AggregatedDataVariants::without_key агрегаты для ключей, не попавших в max_rows_to_group_by. + /// The settings of approximate calculation of GROUP BY. + const bool overflow_row; /// Do we need to put into AggregatedDataVariants::without_key aggregates for keys that are not in max_rows_to_group_by. const size_t max_rows_to_group_by; const OverflowMode group_by_overflow_mode; - /// Для динамической компиляции. + /// For dynamic compilation. Compiler * compiler; const UInt32 min_count_to_compile; - /// Настройки двухуровневой агрегации (используется для большого количества ключей). - /** При каком количестве ключей или размере состояния агрегации в байтах, - * начинает использоваться двухуровневая агрегация. Достаточно срабатывания хотя бы одного из порогов. - * 0 - соответствующий порог не задан. + /// Two-level aggregation settings (used for a large number of keys). + /** With how many keys or the size of the aggregation state in bytes, + * two-level aggregation begins to be used. Enough to reach of at least one of the thresholds. + * 0 - the corresponding threshold is not specified. */ const size_t group_by_two_level_threshold; const size_t group_by_two_level_threshold_bytes; - /// Настройки для сброса временных данных в файловую систему (внешняя агрегация). - const size_t max_bytes_before_external_group_by; /// 0 - не использовать внешнюю агрегацию. + /// Settings to flush temporary data to the file system (external aggregation). + const size_t max_bytes_before_external_group_by; /// 0 - do not use external aggregation. const std::string tmp_path; Params( @@ -1024,11 +1024,11 @@ public: keys_size = key_names.size(); } - /// Только параметры, имеющие значение при мердже. + /// Only parameters that matter during merge. Params(const Names & key_names_, const AggregateDescriptions & aggregates_, bool overflow_row_) : Params(key_names_, aggregates_, overflow_row_, 0, OverflowMode::THROW, nullptr, 0, 0, 0, 0, "") {} - /// Вычислить номера столбцов в keys и aggregates. + /// Compute the column numbers in `keys` and `aggregates`. void calculateColumnNumbers(const Block & block); }; @@ -1038,38 +1038,38 @@ public: { } - /// Агрегировать источник. Получить результат в виде одной из структур данных. + /// Aggregate the source. Get the result in the form of one of the data structures. void execute(BlockInputStreamPtr stream, AggregatedDataVariants & result); using AggregateColumns = std::vector; using AggregateColumnsData = std::vector; using AggregateFunctionsPlainPtrs = std::vector; - /// Обработать один блок. Вернуть false, если обработку следует прервать (при group_by_overflow_mode = 'break'). + /// Process one block. Return false if the processing should be aborted (with group_by_overflow_mode = 'break'). bool executeOnBlock(Block & block, AggregatedDataVariants & result, - ConstColumnPlainPtrs & key_columns, AggregateColumns & aggregate_columns, /// Передаются, чтобы не создавать их заново на каждый блок - Sizes & key_sizes, StringRefs & keys, /// - передайте соответствующие объекты, которые изначально пустые. + ConstColumnPlainPtrs & key_columns, AggregateColumns & aggregate_columns, /// Passed to not create them anew for each block + Sizes & key_sizes, StringRefs & keys, /// - pass the corresponding objects that are initially empty. bool & no_more_keys); - /** Преобразовать структуру данных агрегации в блок. - * Если overflow_row = true, то агрегаты для строк, не попавших в max_rows_to_group_by, кладутся в первый блок. + /** Convert the aggregation data structure into a block. + * If overflow_row = true, then aggregates for rows that are not included in max_rows_to_group_by are put in the first block. * - * Если final = false, то в качестве столбцов-агрегатов создаются ColumnAggregateFunction с состоянием вычислений, - * которые могут быть затем объединены с другими состояниями (для распределённой обработки запроса). - * Если final = true, то в качестве столбцов-агрегатов создаются столбцы с готовыми значениями. + * If final = false, then ColumnAggregateFunction is created as the aggregation columns with the state of the calculations, + * which can then be combined with other states (for distributed query processing). + * If final = true, then columns with ready values are created as aggregate columns. */ BlocksList convertToBlocks(AggregatedDataVariants & data_variants, bool final, size_t max_threads) const; - /** Объединить несколько структур данных агрегации и выдать результат в виде потока блоков. + /** Merge several aggregation data structures and output the result as a block stream. */ std::unique_ptr mergeAndConvertToBlocks(ManyAggregatedDataVariants & data_variants, bool final, size_t max_threads) const; - /** Объединить поток частично агрегированных блоков в одну структуру данных. - * (Доагрегировать несколько блоков, которые представляют собой результат независимых агрегаций с удалённых серверов.) + /** Merge the stream of partially aggregated blocks into one data structure. + * (Pre-aggregate several blocks that represent the result of independent aggregations from remote servers.) */ void mergeStream(BlockInputStreamPtr stream, AggregatedDataVariants & result, size_t max_threads); - /** Объединить несколько частично агрегированных блоков в один. + /** Merge several partially aggregated blocks into one. */ Block mergeBlocks(BlocksList & blocks, bool final); @@ -1080,14 +1080,14 @@ public: using CancellationHook = std::function; - /** Установить функцию, которая проверяет, можно ли прервать текущую задачу. + /** Set a function that checks whether the current task can be aborted. */ void setCancellationHook(const CancellationHook cancellation_hook); - /// Для IBlockInputStream. + /// For IBlockInputStream. String getID() const; - /// Для внешней агрегации. + /// For external aggregation. void writeToTemporaryFile(AggregatedDataVariants & data_variants, size_t rows); bool hasTemporaryFiles() const { return !temporary_files.empty(); } @@ -1116,14 +1116,14 @@ protected: AggregateFunctionsPlainPtrs aggregate_functions; - /** Данный массив служит для двух целей. + /** This array serves two purposes. * - * 1. Аргументы функции собраны рядом, и их не нужно собирать из разных мест. Также массив сделан zero-terminated. - * Внутренний цикл (для случая without_key) получается почти в два раза компактнее; прирост производительности около 30%. + * 1. Function arguments are collected side by side, and they do not need to be collected from different places. Also the array is made zero-terminated. + * The inner loop (for the case without_key) is almost twice as compact; performance gain of about 30%. * - * 2. Вызов по указателю на функцию лучше, чем виртуальный вызов, потому что в случае виртуального вызова, - * GCC 5.1.2 генерирует код, который на каждой итерации цикла заново грузит из памяти в регистр адрес функции - * (значение по смещению в таблице виртуальных функций). + * 2. Calling a function by pointer is better than a virtual call, because in the case of a virtual call, + * GCC 5.1.2 generates code that, at each iteration of the loop, reloads the function address from memory into the register + * (the offset value in the virtual function table). */ struct AggregateFunctionInstruction { @@ -1135,14 +1135,14 @@ protected: using AggregateFunctionInstructions = std::vector; - Sizes offsets_of_aggregate_states; /// Смещение до n-ой агрегатной функции в строке из агрегатных функций. - size_t total_size_of_aggregate_states = 0; /// Суммарный размер строки из агрегатных функций. + Sizes offsets_of_aggregate_states; /// The offset to the n-th aggregate function in a row of aggregate functions. + size_t total_size_of_aggregate_states = 0; /// The total size of the row from the aggregate functions. bool all_aggregates_has_trivial_destructor = false; - /// Сколько было использовано оперативки для обработки запроса до начала обработки первого блока. + /// How many RAM were used to process the query before processing the first block. Int64 memory_usage_before_aggregation = 0; - /// Для инициализации от первого блока при конкуррентном использовании. + /// To initialize from the first block when used concurrently. bool initialized = false; std::mutex mutex; @@ -1150,56 +1150,56 @@ protected: Logger * log = &Logger::get("Aggregator"); - /** Динамически скомпилированная библиотека для агрегации, если есть. - * Смысл динамической компиляции в том, чтобы специализировать код - * под конкретный список агрегатных функций. - * Это позволяет развернуть цикл по созданию и обновлению состояний агрегатных функций, - * а также использовать вместо виртуальных вызовов inline-код. + /** Dynamically compiled library for aggregation, if any. + * The meaning of dynamic compilation is to specialize code + * for a specific list of aggregate functions. + * This allows you to expand the loop to create and update states of aggregate functions, + * and also use inline-code instead of virtual calls. */ struct CompiledData { SharedLibraryPtr compiled_aggregator; - /// Получены с помощью dlsym. Нужно ещё сделать reinterpret_cast в указатель на функцию. + /// Obtained with dlsym. It is still necessary to make reinterpret_cast to the function pointer. void * compiled_method_ptr = nullptr; void * compiled_two_level_method_ptr = nullptr; }; - /// shared_ptr - чтобы передавать в callback, который может пережить Aggregator. + /// shared_ptr - to pass into a callback, that can survive Aggregator. std::shared_ptr compiled_data { new CompiledData }; bool compiled_if_possible = false; void compileIfPossible(AggregatedDataVariants::Type type); - /// Возвращает true, если можно прервать текущую задачу. + /// Returns true if you can abort the current task. CancellationHook isCancelled; - /// Для внешней агрегации. + /// For external aggregation. TemporaryFiles temporary_files; - /** Если заданы только имена столбцов (key_names, а также aggregates[i].column_name), то вычислить номера столбцов. - * Сформировать блок - пример результата. Он используется в методах convertToBlocks, mergeAndConvertToBlocks. + /** If only the column names (key_names, and also aggregates[i].column_name) are specified, then calculate the column numbers. + * Generate block - sample of the result. It is used in the convertToBlocks, mergeAndConvertToBlocks methods. */ void initialize(const Block & block); - /** Установить блок - пример результата, - * только если он ещё не был установлен. + /** Set the block - sample of the result, + * only if it has not already been set. */ void setSampleBlock(const Block & block); - /** Выбрать способ агрегации на основе количества и типов ключей. */ + /** Select the aggregation method based on the number and types of keys. */ AggregatedDataVariants::Type chooseAggregationMethod(const ConstColumnPlainPtrs & key_columns, Sizes & key_sizes) const; - /** Создать состояния агрегатных функций для одного ключа. + /** Create states of aggregate functions for one key. */ void createAggregateStates(AggregateDataPtr & aggregate_data) const; - /** Вызвать методы destroy для состояний агрегатных функций. - * Используется в обработчике исключений при агрегации, так как RAII в данном случае не применим. + /** Call `destroy` methods for states of aggregate functions. + * Used in the exception handler for aggregation, since RAII in this case is not applicable. */ void destroyAllAggregateStates(AggregatedDataVariants & result); - /// Обработать один блок данных, агрегировать данные в хэш-таблицу. + /// Process one data block, aggregate the data into a hash table. template void executeImpl( Method & method, @@ -1212,7 +1212,7 @@ protected: bool no_more_keys, AggregateDataPtr overflow_row) const; - /// Специализация для конкретного значения no_more_keys. + /// Specialization for a particular value no_more_keys. template void executeImplCase( Method & method, @@ -1225,7 +1225,7 @@ protected: StringRefs & keys, AggregateDataPtr overflow_row) const; - /// Для случая, когда нет ключей (всё агрегировать в одну строку). + /// For case when there are no keys (all aggregate into one row). void executeWithoutKeyImpl( AggregatedDataWithoutKey & res, size_t rows, @@ -1240,7 +1240,7 @@ protected: const String & path); public: - /// Шаблоны, инстанцирующиеся путём динамической компиляции кода - см. SpecializedAggregator.h + /// Templates that are instantiated by dynamic code compilation - see SpecializedAggregator.h template void executeSpecialized( @@ -1274,14 +1274,14 @@ public: Arena * arena) const; protected: - /// Слить данные из хэш-таблицы src в dst. + /// Merge data from hash table `src` into `dst`. template void mergeDataImpl( Table & table_dst, Table & table_src, Arena * arena) const; - /// Слить данные из хэш-таблицы src в dst, но только для ключей, которые уже есть в dst. В остальных случаях, слить данные в overflows. + /// Merge data from hash table `src` into `dst`, but only for keys that already exist in dst. In other cases, merge the data into `overflows`. template void mergeDataNoMoreKeysImpl( Table & table_dst, @@ -1289,7 +1289,7 @@ protected: Table & table_src, Arena * arena) const; - /// То же самое, но игнорирует остальные ключи. + /// Same, but ignores the rest of the keys. template void mergeDataOnlyExistingKeysImpl( Table & table_dst, @@ -1400,17 +1400,17 @@ protected: AggregatedDataVariants & result) const; - /** Проверяет ограничения на максимальное количество ключей для агрегации. - * Если оно превышено, то, в зависимости от group_by_overflow_mode, либо - * - кидает исключение; - * - возвращает false, что говорит о том, что выполнение нужно прервать; - * - выставляет переменную no_more_keys в true. + /** Checks constraints on the maximum number of keys for aggregation. + * If it is exceeded, then, depending on the group_by_overflow_mode, either + * - throws an exception; + * - returns false, which means that execution must be aborted; + * - sets the variable no_more_keys to true. */ bool checkLimits(size_t result_size, bool & no_more_keys) const; }; -/** Достать вариант агрегации по его типу. */ +/** Get the aggregation variant by its type. */ template Method & getDataVariant(AggregatedDataVariants & variants); #define M(NAME, IS_TWO_LEVEL) \ diff --git a/dbms/src/Interpreters/Cluster.h b/dbms/src/Interpreters/Cluster.h index b29dac9a4bf..671773744cb 100644 --- a/dbms/src/Interpreters/Cluster.h +++ b/dbms/src/Interpreters/Cluster.h @@ -9,23 +9,23 @@ namespace DB { -/// Cluster содержит пулы соединений до каждого из узлов -/// С локальными узлами соединение не устанавливается, а выполяется запрос напрямую. -/// Поэтому храним только количество локальных узлов -/// В конфиге кластер включает в себя узлы или +/// Cluster contains connection pools to each node +/// With the local nodes, the connection is not established, but the request is executed directly. +/// Therefore we store only the number of local nodes +/// In the config, the cluster includes nodes or class Cluster { public: Cluster(Poco::Util::AbstractConfiguration & config, const Settings & settings, const String & cluster_name); - /// Построить кластер по именам шардов и реплик. Локальные обрабатываются так же как удаленные. + /// Construct a cluster by the names of shards and replicas. Local are treated as well as remote ones. Cluster(const Settings & settings, const std::vector> & names, const String & username, const String & password); Cluster(const Cluster &) = delete; Cluster & operator=(const Cluster &) = delete; - /// используеться для выставления ограничения на размер таймаута + /// is used to set a limit on the size of the timeout static Poco::Timespan saturate(const Poco::Timespan & v, const Poco::Timespan & limit); public: @@ -73,7 +73,7 @@ public: public: /// contains names of directories for asynchronous write to StorageDistributed std::vector dir_names; - UInt32 shard_num; /// Номер шарда, начиная с 1. + UInt32 shard_num; /// Shard number, starting with 1. int weight; Addresses local_addresses; ConnectionPoolWithFailoverPtr pool; @@ -93,17 +93,17 @@ public: return shards_info.front(); } - /// Количество удалённых шардов. + /// The number of remote shards. size_t getRemoteShardCount() const { return remote_shard_count; } - /// Количество узлов clickhouse сервера, расположенных локально - /// к локальным узлам обращаемся напрямую. + /// The number of clickhouse nodes located locally + /// we access the local nodes directly. size_t getLocalShardCount() const { return local_shard_count; } - /// Количество всех шардов. + /// The number of all shards. size_t getShardCount() const { return shards_info.size(); } - /// Получить подкластер, состоящий из одного шарда - index по счёту (с нуля) шарда данного кластера. + /// Get a subcluster consisting of one shard - index by count (from 0) of the shard of this cluster. std::unique_ptr getClusterWithSingleShard(size_t index) const; private: @@ -121,21 +121,21 @@ private: /// on tables that have the distributed engine. void calculateHashOfAddresses(); - /// Для реализации getClusterWithSingleShard. + /// For getClusterWithSingleShard implementation. Cluster(const Cluster & from, size_t index); String hash_of_addresses; - /// Описание шардов кластера. + /// Description of the cluster shards. ShardsInfo shards_info; - /// Любой удалённый шард. + /// Any remote shard. ShardInfo * any_remote_shard_info = nullptr; - /// Непустым является либо addresses, либо addresses_with_failover. - /// Размер и порядок элементов в соответствующем массиве соответствует shards_info. + /// Non-empty is either addresses or addresses_with_failover. + /// The size and order of the elements in the corresponding array corresponds to shards_info. - /// Массив шардов. Каждый шард - адреса одного сервера. + /// An array of shards. Each shard is the address of one server. Addresses addresses; - /// Массив шардов. Для каждого шарда - массив адресов реплик (серверов, считающихся идентичными). + /// An array of shards. For each shard, an array of replica addresses (servers that are considered identical). AddressesWithFailover addresses_with_failover; size_t remote_shard_count = 0; diff --git a/dbms/src/Interpreters/Compiler.cpp b/dbms/src/Interpreters/Compiler.cpp index 04200371ded..4161f33e61f 100644 --- a/dbms/src/Interpreters/Compiler.cpp +++ b/dbms/src/Interpreters/Compiler.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/dbms/src/Interpreters/Compiler.h b/dbms/src/Interpreters/Compiler.h index 20f4bc9e17b..0bf629042c1 100644 --- a/dbms/src/Interpreters/Compiler.h +++ b/dbms/src/Interpreters/Compiler.h @@ -20,7 +20,7 @@ namespace DB { -/** Позволяет открыть динамическую библиотеку и получить из неё указатель на функцию. +/** Allows you to open a dynamic library and get a pointer to a function from it. */ class SharedLibrary : private boost::noncopyable { @@ -58,17 +58,17 @@ private: using SharedLibraryPtr = std::shared_ptr; -/** Позволяет скомпилировать кусок кода, использующий заголовочные файлы сервера, в динамическую библиотеку. - * Ведёт статистику вызовов, и инициирует компиляцию только на N-ый по счёту вызов для одного ключа. - * Компиляция выполняется асинхронно, в отдельных потоках, если есть свободные потоки. - * NOTE: Нет очистки устаревших и ненужных результатов. +/** Lets you compile a piece of code that uses the server's header files into the dynamic library. + * Conducts statistic of calls, and initiates compilation only on the N-th call for one key. + * Compilation is performed asynchronously, in separate threads, if there are free threads. + * NOTE: There is no cleaning of obsolete and unnecessary results. */ class Compiler { public: - /** path - путь к директории с временными файлами - результатами компиляции. - * Результаты компиляции сохраняются при перезапуске сервера, - * но используют в качестве части ключа номер ревизии. То есть, устаревают при обновлении сервера. + /** path - path to the directory with temporary files - the results of the compilation. + * The compilation results are saved when the server is restarted, + * but use the revision number as part of the key. That is, they become obsolete when the server is updated. */ Compiler(const std::string & path_, size_t threads); ~Compiler(); @@ -78,13 +78,13 @@ public: using CodeGenerator = std::function; using ReadyCallback = std::function; - /** Увеличить счётчик для заданного ключа key на единицу. - * Если результат компиляции уже есть (уже открыт, или есть файл с библиотекой), - * то вернуть готовую SharedLibrary. - * Иначе, если min_count_to_compile == 0, то инициировать компиляцию в том же потоке, дождаться её, и вернуть результат. - * Иначе, если счётчик достиг min_count_to_compile, - * инициировать компиляцию в отдельном потоке, если есть свободные потоки, и вернуть nullptr. - * Иначе вернуть nullptr. + /** Increase the counter for the given key `key` by one. + * If the compilation result already exists (already open, or there is a file with the library), + * then return ready SharedLibrary. + * Otherwise, if min_count_to_compile == 0, then initiate the compilation in the same thread, wait for it, and return the result. + * Otherwise, if the counter has reached min_count_to_compile, + * initiate compilation in a separate thread, if there are free threads, and return nullptr. + * Otherwise, return nullptr. */ SharedLibraryPtr getOrCount( const std::string & key, @@ -101,13 +101,13 @@ private: const std::string path; ThreadPool pool; - /// Количество вызовов функции getOrCount. + /// Number of calls to `getOrCount`. Counts counts; - /// Скомпилированные и открытые библиотеки. Или nullptr для библиотек в процессе компиляции. + /// Compiled and open libraries. Or nullptr for libraries in the compilation process. Libraries libraries; - /// Скомпилированные файлы, оставшиеся от предыдущих запусков, но ещё не открытые. + /// Compiled files remaining from previous runs, but not yet open. Files files; std::mutex mutex; diff --git a/dbms/src/Interpreters/Context.cpp b/dbms/src/Interpreters/Context.cpp index 6164dd746d2..60c95daf42f 100644 --- a/dbms/src/Interpreters/Context.cpp +++ b/dbms/src/Interpreters/Context.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,7 @@ #include #include +#include namespace ProfileEvents @@ -105,7 +107,7 @@ struct ContextShared String path; /// Path to the data directory, with a slash at the end. String tmp_path; /// The path to the temporary files that occur when processing the request. - String flags_path; /// + String flags_path; /// Path to the directory with some control flags for server maintenance. Databases databases; /// List of databases and tables in them. TableFunctionFactory table_function_factory; /// Table functions. FormatFactory format_factory; /// Formats. @@ -123,16 +125,17 @@ struct ContextShared InterserverIOHandler interserver_io_handler; /// Handler for interserver communication. BackgroundProcessingPoolPtr background_pool; /// The thread pool for the background work performed by the tables. ReshardingWorkerPtr resharding_worker; - Macros macros; /// Substitutions extracted from config. - std::unique_ptr compiler; /// Used for dynamic compilation of queries' parts if it necessary. - std::unique_ptr query_log; /// Used to log queries. - std::shared_ptr part_log; /// Used to log operations with parts + Macros macros; /// Substitutions from config. Can be used for parameters of ReplicatedMergeTree. + std::unique_ptr compiler; /// Used for dynamic compilation of queries' parts if it necessary. /// Rules for selecting the compression method, depending on the size of the part. mutable std::unique_ptr compression_method_selector; - std::unique_ptr merge_tree_settings; /// Settings of MergeTree* engines. - size_t max_table_size_to_drop = 50000000000lu; /// Protects MergeTree tables from accidental DROP (50GB by default) + std::unique_ptr merge_tree_settings; /// Settings of MergeTree* engines. + size_t max_table_size_to_drop = 50000000000lu; /// Protects MergeTree tables from accidental DROP (50GB by default) - class SessionKeyHash { + /// Named sessions. The user could specify session identifier to reuse settings and temporary tables in subsequent requests. + + class SessionKeyHash + { public: size_t operator()(const Context::SessionKey & key) const { @@ -196,9 +199,6 @@ struct ContextShared return; shutdown_called = true; - query_log.reset(); - part_log.reset(); - /** At this point, some tables may have threads that block our mutex. * To complete them correctly, we will copy the current list of tables, * and ask them all to finish their work. @@ -224,12 +224,24 @@ struct ContextShared Context::Context() - : shared(new ContextShared), - quota(new QuotaForIntervals) + : shared(std::make_shared()), + quota(std::make_shared()), + system_logs(std::make_shared()) { } -Context::~Context() = default; +Context::~Context() +{ + try + { + /// Destroy system logs while at least one Context is alive + system_logs.reset(); + } + catch (...) + { + tryLogCurrentException(__PRETTY_FUNCTION__); + } +} const TableFunctionFactory & Context::getTableFunctionFactory() const { return shared->table_function_factory; } @@ -272,14 +284,14 @@ Context::SessionKey Context::getSessionKey(const String & session_id) const } -void Context::scheduleClose(const Context::SessionKey & key, std::chrono::steady_clock::duration timeout) +void Context::scheduleCloseSession(const Context::SessionKey & key, std::chrono::steady_clock::duration timeout) { const UInt64 close_index = timeout / shared->close_interval + 1; const auto new_close_cycle = shared->close_cycle + close_index; - if (close_cycle != new_close_cycle) + if (session_close_cycle != new_close_cycle) { - close_cycle = new_close_cycle; + session_close_cycle = new_close_cycle; if (shared->close_times.size() < close_index + 1) shared->close_times.resize(close_index + 1); shared->close_times[close_index].emplace_back(key); @@ -301,7 +313,7 @@ std::shared_ptr Context::acquireSession(const String & session_id, std: auto new_session = std::make_shared(*global_context); - new_session->scheduleClose(key, timeout); + new_session->scheduleCloseSession(key, timeout); it = shared->sessions.insert(std::make_pair(key, std::move(new_session))).first; } @@ -312,9 +324,9 @@ std::shared_ptr Context::acquireSession(const String & session_id, std: const auto & session = it->second; - if (session->used) + if (session->session_is_used) throw Exception("Session is locked by a concurrent client.", ErrorCodes::SESSION_IS_LOCKED); - session->used = true; + session->session_is_used = true; session->client_info = client_info; @@ -326,9 +338,8 @@ void Context::releaseSession(const String & session_id, std::chrono::steady_cloc { auto lock = getLock(); - used = false; - - scheduleClose(getSessionKey(session_id), timeout); + session_is_used = false; + scheduleCloseSession(getSessionKey(session_id), timeout); } @@ -343,7 +354,7 @@ std::chrono::steady_clock::duration Context::closeSessions() const const auto current_cycle = shared->close_cycle; - ++(shared->close_cycle); + ++shared->close_cycle; shared->close_cycle_time = now + shared->close_interval; if (shared->close_times.empty()) @@ -355,10 +366,10 @@ std::chrono::steady_clock::duration Context::closeSessions() const { const auto session = shared->sessions.find(key); - if (session != shared->sessions.end() && session->second->close_cycle <= current_cycle) + if (session != shared->sessions.end() && session->second->session_close_cycle <= current_cycle) { - if (session->second->used) - session->second->scheduleClose(key, std::chrono::seconds(0)); + if (session->second->session_is_used) + session->second->scheduleCloseSession(key, std::chrono::seconds(0)); else shared->sessions.erase(session); } @@ -1206,10 +1217,13 @@ QueryLog & Context::getQueryLog() { auto lock = getLock(); - if (!shared->query_log) + if (!system_logs) + throw Exception("Query log have been already shutdown", ErrorCodes::LOGICAL_ERROR); + + if (!system_logs->query_log) { if (shared->shutdown_called) - throw Exception("Will not get query_log because shutdown was called", ErrorCodes::LOGICAL_ERROR); + throw Exception("Logical error: query log should be destroyed before tables shutdown", ErrorCodes::LOGICAL_ERROR); if (!global_context) throw Exception("Logical error: no global context for query log", ErrorCodes::LOGICAL_ERROR); @@ -1221,15 +1235,15 @@ QueryLog & Context::getQueryLog() size_t flush_interval_milliseconds = config.getUInt64( "query_log.flush_interval_milliseconds", DEFAULT_QUERY_LOG_FLUSH_INTERVAL_MILLISECONDS); - shared->query_log = std::make_unique( + system_logs->query_log = std::make_unique( *global_context, database, table, "MergeTree(event_date, event_time, 1024)", flush_interval_milliseconds); } - return *shared->query_log; + return *system_logs->query_log; } -std::shared_ptr Context::getPartLog() +PartLog * Context::getPartLog(const String & database, const String & table) { auto lock = getLock(); @@ -1237,23 +1251,33 @@ std::shared_ptr Context::getPartLog() if (!config.has("part_log")) return nullptr; - if (!shared->part_log) + /// System logs are shutdown + if (!system_logs) + return nullptr; + + String part_log_database = config.getString("part_log.database", "system"); + String part_log_table = config.getString("part_log.table", "part_log"); + + /// Will not log system.part_log itself. + /// It doesn't make sense and not allow to destruct PartLog correctly due to infinite logging and flushing + if (database == part_log_database && table == part_log_table) + return nullptr; + + if (!system_logs->part_log) { if (shared->shutdown_called) - throw Exception("Will not get part_log because shutdown was called", ErrorCodes::LOGICAL_ERROR); + throw Exception("Logical error: part log should be destroyed before tables shutdown", ErrorCodes::LOGICAL_ERROR); if (!global_context) throw Exception("Logical error: no global context for part log", ErrorCodes::LOGICAL_ERROR); - String database = config.getString("part_log.database", "system"); - String table = config.getString("part_log.table", "part_log"); size_t flush_interval_milliseconds = config.getUInt64( "part_log.flush_interval_milliseconds", DEFAULT_QUERY_LOG_FLUSH_INTERVAL_MILLISECONDS); - shared->part_log = std::make_unique( - *global_context, database, table, "MergeTree(event_date, event_time, 1024)", flush_interval_milliseconds); + system_logs->part_log = std::make_unique(*global_context, part_log_database, part_log_table, + "MergeTree(event_date, event_time, 1024)", flush_interval_milliseconds); } - return shared->part_log; + return system_logs->part_log.get(); } @@ -1360,6 +1384,7 @@ time_t Context::getUptimeSeconds() const void Context::shutdown() { + system_logs.reset(); shared->shutdown(); } diff --git a/dbms/src/Interpreters/Context.h b/dbms/src/Interpreters/Context.h index 70f0606e69f..f6f4527a0aa 100644 --- a/dbms/src/Interpreters/Context.h +++ b/dbms/src/Interpreters/Context.h @@ -65,21 +65,23 @@ class IBlockOutputStream; using BlockInputStreamPtr = std::shared_ptr; using BlockOutputStreamPtr = std::shared_ptr; class Block; +struct SystemLogs; +using SystemLogsPtr = std::shared_ptr; -/// (имя базы данных, имя таблицы) +/// (database name, table name) using DatabaseAndTableName = std::pair; -/// Таблица -> множество таблиц-представлений, которые деляют SELECT из неё. +/// Table -> set of table-views that make SELECT from it. using ViewDependencies = std::map>; using Dependencies = std::vector; -/** Набор известных объектов, которые могут быть использованы в запросе. - * Состоит из разделяемой части (всегда общей для всех сессий и запросов) - * и копируемой части (которая может быть своей для каждой сессии или запроса). +/** A set of known objects that can be used in the query. + * Consists of a shared part (always common to all sessions and queries) + * and copied part (which can be its own for each session or query). * - * Всё инкапсулировано для всяких проверок и блокировок. + * Everything is encapsulated for all sorts of checks and locks. */ class Context { @@ -89,21 +91,22 @@ private: ClientInfo client_info; - std::shared_ptr quota; /// Current quota. By default - empty quota, that have no limits. + std::shared_ptr quota; /// Current quota. By default - empty quota, that have no limits. String current_database; - Settings settings; /// Setting for query execution. + Settings settings; /// Setting for query execution. using ProgressCallback = std::function; - ProgressCallback progress_callback; /// Callback for tracking progress of query execution. - ProcessListElement * process_list_elem = nullptr; /// For tracking total resource usage for query. + ProgressCallback progress_callback; /// Callback for tracking progress of query execution. + ProcessListElement * process_list_elem = nullptr; /// For tracking total resource usage for query. - String default_format; /// Format, used when server formats data by itself and if query does not have FORMAT specification. + String default_format; /// Format, used when server formats data by itself and if query does not have FORMAT specification. /// Thus, used in HTTP interface. If not specified - then some globally default format is used. - Tables external_tables; /// Temporary tables. + Tables external_tables; /// Temporary tables. Context * session_context = nullptr; /// Session context or nullptr. Could be equal to this. - Context * global_context = nullptr; /// Global context or nullptr. Could be equal to this. + Context * global_context = nullptr; /// Global context or nullptr. Could be equal to this. + SystemLogsPtr system_logs; /// Used to log queries and operations on parts - UInt64 close_cycle = 0; - bool used = false; + UInt64 session_close_cycle = 0; + bool session_is_used = false; using DatabasePtr = std::shared_ptr; using Databases = std::map>; @@ -121,9 +124,9 @@ public: using ConfigurationPtr = Poco::AutoPtr; - /** Забрать список пользователей, квот и профилей настроек из этого конфига. - * Список пользователей полностью заменяется. - * Накопленные значения у квоты не сбрасываются, если квота не удалена. + /** Take the list of users, quotas and configuration profiles from this config. + * The list of users is completely replaced. + * The accumulated quota values are not reset if the quota is not deleted. */ void setUsersConfig(const ConfigurationPtr & config); @@ -142,14 +145,14 @@ public: void removeDependency(const DatabaseAndTableName & from, const DatabaseAndTableName & where); Dependencies getDependencies(const String & database_name, const String & table_name) const; - /// Проверка существования таблицы/БД. database может быть пустой - в этом случае используется текущая БД. + /// Checking the existence of the table/database. Database can be empty - in this case the current database is used. bool isTableExist(const String & database_name, const String & table_name) const; bool isDatabaseExist(const String & database_name) const; void assertTableExists(const String & database_name, const String & table_name) const; - /** Параметр check_database_access_rights существует, чтобы не проверить повторно права доступа к БД, - * когда assertTableDoesnExist или assertDatabaseExists вызывается внутри другой функции, которая уже - * сделала эту проверку. + /** The parameter check_database_access_rights exists to not check the permissions of the database again, + * when assertTableDoesntExist or assertDatabaseExists is called inside another function that already + * made this check. */ void assertTableDoesntExist(const String & database_name, const String & table_name, bool check_database_acccess_rights = true) const; void assertDatabaseExists(const String & database_name, bool check_database_acccess_rights = true) const; @@ -165,10 +168,10 @@ public: void addDatabase(const String & database_name, const DatabasePtr & database); DatabasePtr detachDatabase(const String & database_name); - /// Получить объект, который защищает таблицу от одновременного выполнения нескольких DDL операций. - /// Если такой объект уже есть - кидается исключение. + /// Get an object that protects the table from concurrently executing multiple DDL operations. + /// If such an object already exists, an exception is thrown. std::unique_ptr getDDLGuard(const String & database, const String & table, const String & message) const; - /// Если таблица уже есть - возвращается nullptr, иначе создаётся guard. + /// If the table already exists, it returns nullptr, otherwise guard is created. std::unique_ptr getDDLGuardIfTableDoesntExist(const String & database, const String & table, const String & message) const; String getCurrentDatabase() const; @@ -176,7 +179,7 @@ public: void setCurrentDatabase(const String & name); void setCurrentQueryId(const String & query_id); - String getDefaultFormat() const; /// Если default_format не задан - возвращается некоторый глобальный формат по-умолчанию. + String getDefaultFormat() const; /// If default_format is not specified, some global default format is returned. void setDefaultFormat(const String & name); const Macros & getMacros() const; @@ -187,10 +190,10 @@ public: Limits getLimits() const; - /// Установить настройку по имени. + /// Set a setting by name. void setSetting(const String & name, const Field & value); - /// Установить настройку по имени. Прочитать значение в текстовом виде из строки (например, из конфига, или из параметра URL). + /// Set a setting by name. Read the value in text form from a string (for example, from a config, or from a URL parameter). void setSetting(const String & name, const std::string & value); const TableFunctionFactory & getTableFunctionFactory() const; @@ -199,19 +202,19 @@ public: void tryCreateEmbeddedDictionaries() const; void tryCreateExternalDictionaries() const; - /// Форматы ввода-вывода. + /// I/O formats. BlockInputStreamPtr getInputFormat(const String & name, ReadBuffer & buf, const Block & sample, size_t max_block_size) const; BlockOutputStreamPtr getOutputFormat(const String & name, WriteBuffer & buf, const Block & sample) const; InterserverIOHandler & getInterserverIOHandler(); - /// Как другие серверы могут обратиться к этому для скачивания реплицируемых данных. + /// How other servers can access this for downloading replicated data. void setInterserverIOAddress(const String & host, UInt16 port); std::pair getInterserverIOAddress() const; - /// Порт, который сервер слушает для выполнения SQL-запросов. + /// The port that the server listens for executing SQL queries. UInt16 getTCPPort() const; - /// Получить запрос на CREATE таблицы. + /// Get query for the CREATE table. ASTPtr getCreateQuery(const String & database_name, const String & table_name) const; const DatabasePtr getDatabase(const String & database_name) const; @@ -222,12 +225,11 @@ public: const Databases getDatabases() const; Databases getDatabases(); - using SessionKey = std::pair; - std::shared_ptr acquireSession(const String & session_id, std::chrono::steady_clock::duration timeout, bool session_check) const; void releaseSession(const String & session_id, std::chrono::steady_clock::duration timeout); - std::chrono::steady_clock::duration closeSessions() const; + /// Close sessions, that has been expired. Returns how long to wait for next session to be expired, if no new sessions will be added. + std::chrono::steady_clock::duration closeSessions() const; /// For methods below you may need to acquire a lock by yourself. std::unique_lock getLock() const; @@ -246,32 +248,32 @@ public: void setProgressCallback(ProgressCallback callback); - /// Используется в InterpreterSelectQuery, чтобы передать его в IProfilingBlockInputStream. + /// Used in InterpreterSelectQuery to pass it to the IProfilingBlockInputStream. ProgressCallback getProgressCallback() const; - /** Устанавливается в executeQuery и InterpreterSelectQuery. Затем используется в IProfilingBlockInputStream, - * чтобы обновлять и контролировать информацию об общем количестве потраченных на запрос ресурсов. + /** Set in executeQuery and InterpreterSelectQuery. Then it is used in IProfilingBlockInputStream, + * to update and monitor information about the total number of resources spent for the query. */ void setProcessListElement(ProcessListElement * elem); - /// Может вернуть nullptr, если запрос не был вставлен в ProcessList. + /// Can return nullptr if the query was not inserted into the ProcessList. ProcessListElement * getProcessListElement(); - /// Список всех запросов. + /// List all queries. ProcessList & getProcessList(); const ProcessList & getProcessList() const; MergeList & getMergeList(); const MergeList & getMergeList() const; - /// Создать кэш разжатых блоков указанного размера. Это можно сделать только один раз. + /// Create a cache of uncompressed blocks of specified size. This can be done only once. void setUncompressedCache(size_t max_size_in_bytes); std::shared_ptr getUncompressedCache() const; void setZooKeeper(std::shared_ptr zookeeper); - /// Если в момент вызова текущая сессия просрочена, синхронно создает и возвращает новую вызовом startNewSession(). + /// If the current session is expired at the time of the call, synchronously creates and returns a new session with the startNewSession() call. std::shared_ptr getZooKeeper() const; - /// Создать кэш засечек указанного размера. Это можно сделать только один раз. + /// Create a cache of marks of specified size. This can be done only once. void setMarkCache(size_t cache_size_in_bytes); std::shared_ptr getMarkCache() const; @@ -280,11 +282,11 @@ public: void setReshardingWorker(std::shared_ptr resharding_worker); ReshardingWorker & getReshardingWorker(); - /** Очистить кэши разжатых блоков и засечек. - * Обычно это делается при переименовании таблиц, изменении типа столбцов, удалении таблицы. - * - так как кэши привязаны к именам файлов, и становятся некорректными. - * (при удалении таблицы - нужно, так как на её месте может появиться другая) - * const - потому что изменение кэша не считается существенным. + /** Clear the caches of the uncompressed blocks and marks. + * This is usually done when renaming tables, changing the type of columns, deleting a table. + * - since caches are linked to file names, and become incorrect. + * (when deleting a table - it is necessary, since in its place another can appear) + * const - because the change in the cache is not considered significant. */ void resetCaches() const; @@ -295,25 +297,28 @@ public: Compiler & getCompiler(); QueryLog & getQueryLog(); - std::shared_ptr getPartLog(); + + /// Returns an object used to log opertaions with parts if it possible. + /// Provide table name to make required cheks. + PartLog * getPartLog(const String & database, const String & table); const MergeTreeSettings & getMergeTreeSettings(); /// Prevents DROP TABLE if its size is greater than max_size (50GB by default, max_size=0 turn off this check) void setMaxTableSizeToDrop(size_t max_size); void checkTableCanBeDropped(const String & database, const String & table, size_t table_size); - /// Позволяет выбрать метод сжатия по условиям, описанным в конфигурационном файле. + /// Lets you select the compression method according to the conditions described in the configuration file. CompressionMethod chooseCompressionMethod(size_t part_size, double part_size_ratio) const; - /// Получить аптайм сервера в секундах. + /// Get the server uptime in seconds. time_t getUptimeSeconds() const; void shutdown(); enum class ApplicationType { - SERVER, /// The program is run as clickhouse-server daemon (default behavior) - CLIENT, /// clickhouse-client + SERVER, /// The program is run as clickhouse-server daemon (default behavior) + CLIENT, /// clickhouse-client LOCAL_SERVER /// clickhouse-local }; @@ -324,10 +329,13 @@ public: String getDefaultProfileName() const; void setDefaultProfileName(const String & name); + /// User name and session identifier. Named sessions are local to users. + using SessionKey = std::pair; + private: - /** Проверить, имеет ли текущий клиент доступ к заданной базе данных. - * Если доступ запрещён, кинуть исключение. - * NOTE: Этот метод надо всегда вызывать при захваченном мьютексе shared->mutex. + /** Check if the current client has access to the specified database. + * If access is denied, throw an exception. + * NOTE: This method should always be called when the `shared->mutex` mutex is acquired. */ void checkDatabaseAccessRights(const std::string & database_name) const; @@ -337,7 +345,9 @@ private: StoragePtr getTableImpl(const String & database_name, const String & table_name, Exception * exception) const; SessionKey getSessionKey(const String & session_id) const; - void scheduleClose(const SessionKey & key, std::chrono::steady_clock::duration timeout); + + /// Session will be closed after specified timeout. + void scheduleCloseSession(const SessionKey & key, std::chrono::steady_clock::duration timeout); }; diff --git a/dbms/src/Interpreters/ExpressionActions.h b/dbms/src/Interpreters/ExpressionActions.h index ac365da057b..84556ded0c2 100644 --- a/dbms/src/Interpreters/ExpressionActions.h +++ b/dbms/src/Interpreters/ExpressionActions.h @@ -32,7 +32,7 @@ class IBlockInputStream; using BlockInputStreamPtr = std::shared_ptr; -/** Действие над блоком. +/** Action on the block. */ struct ExpressionAction { @@ -45,16 +45,16 @@ public: APPLY_FUNCTION, - /** Заменяет указанные столбцы с массивами на столбцы с элементами. - * Размножает значения в остальных столбцах по количеству элементов в массивах. - * Массивы должны быть параллельными (иметь одинаковые длины). + /** Replaces the specified columns with arrays into columns with elements. + * Duplicates the values in the remaining columns by the number of elements in the arrays. + * Arrays must be parallel (have the same lengths). */ ARRAY_JOIN, /// INNER|LEFT JOIN. JOIN, - /// Переупорядочить и переименовать столбцы, удалить лишние. Допускаются одинаковые имена столбцов в результате. + /// Reorder and rename the columns, delete the extra ones. The same column names are allowed in the result. PROJECT, }; @@ -84,7 +84,7 @@ public: /// For PROJECT. NamesWithAliases projection; - /// Если result_name_ == "", в качестве имени используется "имя_функции(аргументы через запятую)". + /// If result_name_ == "", as name "function_name(arguments separated by commas) is used". static ExpressionAction applyFunction( const FunctionPtr & function_, const std::vector & argument_names_, std::string result_name_ = ""); @@ -96,8 +96,8 @@ public: static ExpressionAction arrayJoin(const NameSet & array_joined_columns, bool array_join_is_left, const Context & context); static ExpressionAction ordinaryJoin(std::shared_ptr join_, const NamesAndTypesList & columns_added_by_join_); - /// Какие столбцы нужны, чтобы выполнить это действие. - /// Если этот Action еще не добавлен в ExpressionActions, возвращаемый список может быть неполным, потому что не учтены prerequisites. + /// Which columns necessary to perform this action. + /// If this `Action` is not already added to `ExpressionActions`, the returned list may be incomplete, because `prerequisites` are not taken into account. Names getNeededColumns() const; std::string toString() const; @@ -112,7 +112,7 @@ private: }; -/** Содержит последовательность действий над блоком. +/** Contains a sequence of actions on the block. */ class ExpressionActions { @@ -126,7 +126,7 @@ public: sample_block.insert(ColumnWithTypeAndName(nullptr, input_elem.type, input_elem.name)); } - /// Для константных столбцов в input_columns_ могут содержаться сами столбцы. + /// For constant columns the columns themselves can be contained in `input_columns_`. ExpressionActions(const ColumnsWithTypeAndName & input_columns_, const Settings & settings_) : settings(settings_) { @@ -137,40 +137,40 @@ public: } } - /// Добавить входной столбец. - /// Название столбца не должно совпадать с названиями промежуточных столбцов, возникающих при вычислении выражения. - /// В выражении не должно быть действий PROJECT. + /// Add the input column. + /// The name of the column must not match the names of the intermediate columns that occur when evaluating the expression. + /// The expression must not have any PROJECT actions. void addInput(const ColumnWithTypeAndName & column); void addInput(const NameAndTypePair & column); void add(const ExpressionAction & action); - /// Кладет в out_new_columns названия новых столбцов - /// (образовавшихся в результате добавляемого действия и его rerequisites). + /// Adds new column names to out_new_columns + /// (formed as a result of the added action and its prerequisites). void add(const ExpressionAction & action, Names & out_new_columns); - /// Добавляет в начало удаление всех лишних столбцов. + /// Adds to the beginning the removal of all extra columns. void prependProjectInput(); - /// Добавить в начало указанное действие типа ARRAY JOIN. Поменять соответствующие входные типы на массивы. - /// Если в списке ARRAY JOIN есть неизвестные столбцы, взять их типы из sample_block, а сразу после ARRAY JOIN удалить. + /// Add the specified ARRAY JOIN action to the beginning. Change the appropriate input types to arrays. + /// If there are unknown columns in the ARRAY JOIN list, take their types from sample_block, and immediately after ARRAY JOIN remove them. void prependArrayJoin(const ExpressionAction & action, const Block & sample_block); - /// Если последнее действие - ARRAY JOIN, и оно не влияет на столбцы из required_columns, выбросить и вернуть его. - /// Поменять соответствующие выходные типы на массивы. + /// If the last action is ARRAY JOIN, and it does not affect the columns from required_columns, discard and return it. + /// Change the corresponding output types to arrays. bool popUnusedArrayJoin(const Names & required_columns, ExpressionAction & out_action); - /// - Добавляет действия для удаления всех столбцов, кроме указанных. - /// - Убирает неиспользуемые входные столбцы. - /// - Может как-нибудь оптимизировать выражение. - /// - Не переупорядочивает столбцы. - /// - Не удаляет "неожиданные" столбцы (например, добавленные функциями). - /// - Если output_columns пуст, оставляет один произвольный столбец (чтобы не потерялось количество строк в блоке). + /// - Adds actions to delete all but the specified columns. + /// - Removes unused input columns. + /// - Can somehow optimize the expression. + /// - Does not reorder the columns. + /// - Does not remove "unexpected" columns (for example, added by functions). + /// - If output_columns is empty, leaves one arbitrary column (so that the number of rows in the block is not lost). void finalize(const Names & output_columns); const Actions & getActions() const { return actions; } - /// Получить список входных столбцов. + /// Get a list of input columns. Names getRequiredColumns() const { Names names; @@ -181,15 +181,15 @@ public: const NamesAndTypesList & getRequiredColumnsWithTypes() const { return input_columns; } - /// Выполнить выражение над блоком. Блок должен содержать все столбцы , возвращаемые getRequiredColumns. + /// Execute the expression on the block. The block must contain all the columns returned by getRequiredColumns. void execute(Block & block) const; - /** Выполнить выражение над блоком тотальных значений. - * Почти не отличается от execute. Разница лишь при выполнении JOIN-а. + /** Execute the expression on the block of total values. + * Almost the same as `execute`. The difference is only when JOIN is executed. */ void executeOnTotals(Block & block) const; - /// Получить блок-образец, содержащий имена и типы столбцов результата. + /// Obtain a sample block that contains the names and types of result columns. const Block & getSampleBlock() const { return sample_block; } std::string getID() const; @@ -208,27 +208,27 @@ private: void checkLimits(Block & block) const; - /// Добавляет сначала все prerequisites, потом само действие. - /// current_names - столбцы, prerequisites которых сейчас обрабатываются. + /// Adds all `prerequisites` first, then the action itself. + /// current_names - columns whose `prerequisites` are currently being processed. void addImpl(ExpressionAction action, NameSet & current_names, Names & new_names); - /// Попробовать что-нибудь улучшить, не меняя списки входных и выходных столбцов. + /// Try to improve something without changing the lists of input and output columns. void optimize(); - /// Переместить все arrayJoin как можно ближе к концу. + /// Move all arrayJoin as close as possible to the end. void optimizeArrayJoin(); }; using ExpressionActionsPtr = std::shared_ptr; -/** Последовательность преобразований над блоком. - * Предполагается, что результат каждого шага подается на вход следующего шага. - * Используется для выполнения некоторых частей запроса по отдельности. +/** The sequence of transformations over the block. + * It is assumed that the result of each step is fed to the input of the next step. + * Used to execute parts of the query individually. * - * Например, можно составить цепочку из двух шагов: - * 1) вычислить выражение в секции WHERE, - * 2) вычислить выражение в секции SELECT, - * и между двумя шагами делать фильтрацию по значению в секции WHERE. + * For example, you can create a chain of two steps: + * 1) evaluate the expression in the WHERE clause, + * 2) calculate the expression in the SELECT section, + * and between the two steps do the filtering by value in the WHERE clause. */ struct ExpressionActionsChain { diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index dd59e96b4a4..11f9a6f7c11 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -52,7 +52,7 @@ #include #include -#include +#include #include @@ -534,6 +534,7 @@ void ExpressionAnalyzer::addExternalStorage(ASTPtr & subquery_or_table_name_or_t NamesAndTypesListPtr columns = std::make_shared(sample.getColumnsList()); StoragePtr external_storage = StorageMemory::create(external_table_name, columns); + external_storage->startup(); /** There are two ways to perform distributed GLOBAL subqueries. * diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.h b/dbms/src/Interpreters/ExpressionAnalyzer.h index f747bc47eca..1056805c134 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.h +++ b/dbms/src/Interpreters/ExpressionAnalyzer.h @@ -34,32 +34,32 @@ class ASTExpressionList; class ASTSelectQuery; -/** Информация о том, что делать при выполнении подзапроса в секции [GLOBAL] IN/JOIN. +/** Information on what to do when executing a subquery in the [GLOBAL] IN/JOIN section. */ struct SubqueryForSet { - /// Источник - получен с помощью InterpreterSelectQuery подзапроса. + /// The source is obtained using the InterpreterSelectQuery subquery. BlockInputStreamPtr source; Block source_sample; - /// Если задано - создать из результата Set. + /// If set, create from Set result. SetPtr set; - /// Если задано - создать из результата Join. + /// If set, create from Join result. JoinPtr join; - /// Если задано - положить результат в таблицу. - /// Это - временная таблица для передачи на удалённые серверы при распределённой обработке запроса. + /// If set, put the result into the table. + /// This is a temporary table for transferring to remote servers for distributed query processing. StoragePtr table; }; -/// ID подзапроса -> что с ним делать. +/// ID of subquery -> what to do with it. using SubqueriesForSets = std::unordered_map; -/** Превращает выражение из синтаксического дерева в последовательность действий для его выполнения. +/** Transforms an expression from a syntax tree into a sequence of actions to execute it. * - * NOTE: если ast - запрос SELECT из таблицы, структура этой таблицы не должна меняться во все время жизни ExpressionAnalyzer-а. + * NOTE: if `ast` is a SELECT query from a table, the structure of this table should not change during the lifetime of ExpressionAnalyzer. */ class ExpressionAnalyzer : private boost::noncopyable { @@ -75,20 +75,20 @@ public: size_t subquery_depth_ = 0, bool do_global_ = false); - /// Есть ли в выражении агрегатные функции или секция GROUP BY или HAVING. + /// Does the expression have aggregate functions or a GROUP BY or HAVING section. bool hasAggregation() const { return has_aggregation; } - /// Получить список ключей агрегирования и описаний агрегатных функций, если в запросе есть GROUP BY. + /// Get a list of aggregation keys and descriptions of aggregate functions if the query contains GROUP BY. void getAggregateInfo(Names & key_names, AggregateDescriptions & aggregates) const; - /** Получить набор столбцов, которых достаточно прочитать из таблицы для вычисления выражения. - * Не учитываются столбцы, добавляемые из другой таблицы путём JOIN-а. + /** Get a set of columns that are enough to read from the table to evaluate the expression. + * Columns added from another table by JOIN are not counted. */ Names getRequiredColumns(); - /** Эти методы позволяют собрать цепочку преобразований над блоком, получающую значения в нужных секциях запроса. + /** These methods allow you to build a chain of transformations over a block, that receives values in the desired sections of the query. * - * Пример использования: + * Example usage: * ExpressionActionsChain chain; * analyzer.appendWhere(chain); * chain.addStep(); @@ -96,48 +96,48 @@ public: * analyzer.appendOrderBy(chain); * chain.finalize(); * - * Если указано only_types = true, не выполняет подзапросы в соответствующих частях запроса. Полученные таким - * образом действия не следует выполнять, они нужны только чтобы получить список столбцов с их типами. + * If only_types = true set, does not execute subqueries in the relevant parts of the query. The actions got this way + * shouldn't be executed, they are only needed to get a list of columns with their types. */ - /// До агрегации: + /// Before aggregation: bool appendArrayJoin(ExpressionActionsChain & chain, bool only_types); bool appendJoin(ExpressionActionsChain & chain, bool only_types); bool appendWhere(ExpressionActionsChain & chain, bool only_types); bool appendGroupBy(ExpressionActionsChain & chain, bool only_types); void appendAggregateFunctionsArguments(ExpressionActionsChain & chain, bool only_types); - /// После агрегации: + /// After aggregation: bool appendHaving(ExpressionActionsChain & chain, bool only_types); void appendSelect(ExpressionActionsChain & chain, bool only_types); bool appendOrderBy(ExpressionActionsChain & chain, bool only_types); - /// Удаляет все столбцы кроме выбираемых SELECT, упорядочивает оставшиеся столбцы и переименовывает их в алиасы. + /// Deletes all columns except mentioned by SELECT, arranges the remaining columns and renames them to aliases. void appendProjectResult(ExpressionActionsChain & chain, bool only_types) const; - /// Если ast не запрос SELECT, просто получает все действия для вычисления выражения. - /// Если project_result, в выходном блоке останутся только вычисленные значения в нужном порядке, переименованные в алиасы. - /// Иначе, из блока будут удаляться только временные столбцы. + /// If `ast` is not a SELECT query, just gets all the actions to evaluate the expression. + /// If project_result, only the calculated values in the desired order, renamed to aliases, remain in the output block. + /// Otherwise, only temporary columns will be deleted from the block. ExpressionActionsPtr getActions(bool project_result); - /// Действия, которые можно сделать над пустым блоком: добавление констант и применение функций, зависящих только от констант. - /// Не выполняет подзапросы. + /// Actions that can be performed on an empty block: adding constants and applying functions that depend only on constants. + /// Does not execute subqueries. ExpressionActionsPtr getConstActions(); - /** Множества, для создания которых нужно будет выполнить подзапрос. - * Только множества, нужные для выполнения действий, возвращенных из уже вызванных append* или getActions. - * То есть, нужно вызвать getSetsWithSubqueries после всех вызовов append* или getActions - * и создать все возвращенные множества перед выполнением действий. + /** Sets that require a subquery to be create. + * Only the sets needed to perform actions returned from already executed `append*` or `getActions`. + * That is, you need to call getSetsWithSubqueries after all calls of `append*` or `getActions` + * and create all the returned sets before performing the actions. */ SubqueriesForSets getSubqueriesForSets() { return subqueries_for_sets; } - /** Таблицы, которые надо будет отправить на удалённые серверы при распределённой обработке запроса. + /** Tables that will need to be sent to remote servers for distributed query processing. */ const Tables & getExternalTables() const { return external_tables; } - /// Если ast - запрос SELECT, получает имена (алиасы) и типы столбцов из секции SELECT. + /// If ast is a SELECT query, it gets the aliases and column types from the SELECT section. Block getSelectSampleBlock(); - /// Создаем какие сможем Set из секции IN для использования индекса по ним. + /// Create Set-s that we can from IN section to use the index on them. void makeSetsForIndex(); private: @@ -147,18 +147,18 @@ private: Settings settings; size_t subquery_depth; - /// Столбцы, которые упоминаются в выражении, но не были заданы в конструкторе. + /// Columns that are mentioned in the expression, but were not specified in the constructor. NameSet unknown_required_columns; - /** Исходные столбцы. - * Сначала сюда помещаются все доступные столбцы таблицы. Затем (при разборе запроса) удаляются неиспользуемые столбцы. + /** Original columns. + * First, all available columns of the table are placed here. Then (when parsing the query), unused columns are deleted. */ NamesAndTypesList columns; - /// Столбцы после ARRAY JOIN, JOIN и/или агрегации. + /// Columns after ARRAY JOIN, JOIN, and/or aggregation. NamesAndTypesList aggregated_columns; - /// Таблица, из которой делается запрос. + /// The table from which the query is made. const StoragePtr storage; bool has_aggregation = false; @@ -167,14 +167,14 @@ private: SubqueriesForSets subqueries_for_sets; - /// NOTE: Пока поддерживается только один JOIN на запрос. + /// NOTE: So far, only one JOIN per query is supported. - /** Запрос вида SELECT expr(x) AS k FROM t1 ANY LEFT JOIN (SELECT expr(x) AS k FROM t2) USING k - * Соединение делается по столбцу k. - * Во время JOIN-а, - * - в "правой" таблице, он будет доступен по алиасу k, так как было выполнено действие Project для подзапроса. - * - в "левой" таблице, он будет доступен по имени expr(x), так как ещё не было выполнено действие Project. - * Надо запомнить оба этих варианта. + /** Query of the form `SELECT expr(x) AS FROM t1 ANY LEFT JOIN (SELECT expr(x) AS k FROM t2) USING k` + * The join is made by column k. + * During the JOIN, + * - in the "right" table, it will be available by alias `k`, since `Project` action for the subquery was executed. + * - in the "left" table, it will be accessible by the name `expr(x)`, since `Project` action has not been executed yet. + * You must remember both of these options. */ Names join_key_names_left; Names join_key_names_right; @@ -187,21 +187,21 @@ private: using SetOfASTs = std::set; using MapOfASTs = std::map; - /// Какой столбец нужно по-ARRAY-JOIN-ить, чтобы получить указанный. - /// Например, для SELECT s.v ... ARRAY JOIN a AS s сюда попадет "s.v" -> "a.v". + /// Which column is needed to be ARRAY-JOIN'ed to get the specified. + /// For example, for `SELECT s.v ... ARRAY JOIN a AS s` will get "s.v" -> "a.v". NameToNameMap array_join_result_to_source; - /// Для секции ARRAY JOIN отображение из алиаса в полное имя столбца. - /// Например, для ARRAY JOIN [1,2] AS b сюда попадет "b" -> "array(1,2)". + /// For the ARRAY JOIN section, mapping from the alias to the full column name. + /// For example, for `ARRAY JOIN [1,2] AS b` "b" -> "array(1,2)" will enter here. NameToNameMap array_join_alias_to_name; - /// Обратное отображение для array_join_alias_to_name. + /// The backward mapping for array_join_alias_to_name. NameToNameMap array_join_name_to_alias; - /// Нужно ли подготавливать к выполнению глобальные подзапросы при анализировании запроса. + /// Do I need to prepare for execution global subqueries when analyzing the query. bool do_global; - /// Все новые временные таблицы, полученные при выполнении подзапросов GLOBAL IN/JOIN. + /// All new temporary tables obtained by performing the GLOBAL IN/JOIN subqueries. Tables external_tables; size_t external_table_id = 1; @@ -211,22 +211,22 @@ private: static NamesAndTypesList::iterator findColumn(const String & name, NamesAndTypesList & cols); NamesAndTypesList::iterator findColumn(const String & name) { return findColumn(name, columns); } - /** Из списка всех доступных столбцов таблицы (columns) удалить все ненужные. - * Заодно, сформировать множество неизвестных столбцов (unknown_required_columns), - * а также столбцов, добавленных JOIN-ом (columns_added_by_join). + /** Remove all unnecessary columns from the list of all available columns of the table (`columns`). + * At the same time, form a set of unknown columns (`unknown_required_columns`), + * as well as the columns added by JOIN (`columns_added_by_join`). */ void collectUsedColumns(); - /** Найти столбцы, получаемые путём JOIN-а. + /** Find the columns that are obtained by JOIN. */ void collectJoinedColumns(NameSet & joined_columns, NamesAndTypesList & joined_columns_name_type); - /** Создать словарь алиасов. + /** Create a dictionary of aliases. */ void addASTAliases(ASTPtr & ast, int ignore_levels = 0); - /** Для узлов-звёздочек - раскрыть их в список всех столбцов. - * Для узлов-литералов - подставить алиасы. + /** For star nodes(`*`), expand them to a list of all columns. + * For literal nodes, substitute aliases. */ void normalizeTree(); void normalizeTreeImpl(ASTPtr & ast, MapOfASTs & finished_asts, SetOfASTs & current_asts, std::string current_alias, size_t level); @@ -234,7 +234,7 @@ private: /// Eliminates injective function calls and constant expressions from group by statement void optimizeGroupBy(); - /// Удалить из ORDER BY повторяющиеся элементы. + /// Remove duplicate items from ORDER BY. void optimizeOrderBy(); void optimizeLimitBy(); @@ -244,25 +244,25 @@ private: void optimizeIfWithConstantConditionImpl(ASTPtr & current_ast, Aliases & aliases) const; bool tryExtractConstValueFromCondition(const ASTPtr & condition, bool & value) const; - /// Превратить перечисление значений или подзапрос в ASTSet. node - функция in или notIn. + /// Transform the value enumeration or subquery into ASTSet. `node` - `in` or `notIn` function. void makeSet(ASTFunction * node, const Block & sample_block); - /// Добавляет список ALIAS столбцов из таблицы + /// Adds a list of ALIAS columns from the table void addAliasColumns(); - /// Замена скалярных подзапросов на значения-константы. + /// Replacing scalar subqueries with constant values. void executeScalarSubqueries(); void executeScalarSubqueriesImpl(ASTPtr & ast); - /// Находит глобальные подзапросы в секциях GLOBAL IN/JOIN. Заполняет external_tables. + /// Find global subqueries in the GLOBAL IN/JOIN sections. Fills in external_tables. void initGlobalSubqueriesAndExternalTables(); void initGlobalSubqueries(ASTPtr & ast); - /// Находит в запросе использования внешних таблиц (в виде идентификаторов таблиц). Заполняет external_tables. + /// Finds in the query the usage of external tables (as table identifiers). Fills in external_tables. void findExternalTables(ASTPtr & ast); - /** Инициализировать InterpreterSelectQuery для подзапроса в секции GLOBAL IN/JOIN, - * создать временную таблицу типа Memory и запомнить это в словаре external_tables. + /** Initialize InterpreterSelectQuery for a subquery in the GLOBAL IN/JOIN section, + * create a temporary table of type Memory and store it in the external_tables dictionary. */ void addExternalStorage(ASTPtr & subquery_or_table_name); @@ -279,35 +279,35 @@ private: void getActionsBeforeAggregation(ASTPtr ast, ExpressionActionsPtr & actions, bool no_subqueries); - /** Добавить ключи агрегации в aggregation_keys, агрегатные функции в aggregate_descriptions, - * Создать набор столбцов aggregated_columns, получаемых после агрегации, если она есть, - * или после всех действий, которые обычно выполняются до агрегации. - * Установить has_aggregation = true, если есть GROUP BY или хотя бы одна агрегатная функция. + /** Add aggregation keys to aggregation_keys, aggregate functions to aggregate_descriptions, + * Create a set of columns aggregated_columns resulting after the aggregation, if any, + * or after all the actions that are normally performed before aggregation. + * Set has_aggregation = true if there is GROUP BY or at least one aggregate function. */ void analyzeAggregation(); void getAggregates(const ASTPtr & ast, ExpressionActionsPtr & actions); void assertNoAggregates(const ASTPtr & ast, const char * description); - /** Получить множество нужных столбцов для чтения из таблицы. - * При этом, столбцы, указанные в ignored_names, считаются ненужными. И параметр ignored_names может модифицироваться. - * Множество столбцов available_joined_columns - столбцы, доступные из JOIN-а, они не нужны для чтения из основной таблицы. - * Положить в required_joined_columns множество столбцов, доступных из JOIN-а и востребованных. + /** Get a set of necessary columns to read from the table. + * In this case, the columns specified in ignored_names are considered unnecessary. And the ignored_names parameter can be modified. + * The set of columns available_joined_columns are the columns available from JOIN, they are not needed for reading from the main table. + * Put in required_joined_columns the set of columns available from JOIN and needed. */ void getRequiredColumnsImpl(ASTPtr ast, NameSet & required_columns, NameSet & ignored_names, const NameSet & available_joined_columns, NameSet & required_joined_columns); - /// Получить таблицу, из которой идет запрос + /// Get the table from which the query is made StoragePtr getTable(); - /// columns - столбцы, присутствующие до начала преобразований. + /// columns - the columns that are present before the transformations begin. void initChain(ExpressionActionsChain & chain, const NamesAndTypesList & columns) const; void assertSelect() const; void assertAggregation() const; - /** Создать Set из явного перечисления значений в запросе. - * Если create_ordered_set = true - создать структуру данных, подходящую для использования индекса. + /** Create Set from an explicit enumeration of values in the query. + * If create_ordered_set = true - create a data structure suitable for using the index. */ void makeExplicitSet(ASTFunction * node, const Block & sample_block, bool create_ordered_set); void makeSetsForIndexImpl(ASTPtr & node, const Block & sample_block); diff --git a/dbms/src/Interpreters/ExternalDictionaries.cpp b/dbms/src/Interpreters/ExternalDictionaries.cpp index 5de836460af..929f1d79da2 100644 --- a/dbms/src/Interpreters/ExternalDictionaries.cpp +++ b/dbms/src/Interpreters/ExternalDictionaries.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Interpreters/IInterpreter.h b/dbms/src/Interpreters/IInterpreter.h index 5cacb2c0449..b51e773a17b 100644 --- a/dbms/src/Interpreters/IInterpreter.h +++ b/dbms/src/Interpreters/IInterpreter.h @@ -6,14 +6,14 @@ namespace DB { -/** Интерфейс интерпретаторов разных запросов. +/** Interpreters interface for different queries. */ class IInterpreter { public: - /** Для запросов, возвращающих результат (SELECT и похожие), устанавливает в BlockIO поток, из которого можно будет читать этот результат. - * Для запросов, принимающих данные (INSERT), устанавливает в BlockIO поток, куда можно писать данные. - * Для запросов, которые не требуют данные и ничего не возвращают, BlockIO будет пустым. + /** For queries that return a result (SELECT and similar), sets in BlockIO a stream from which you can read this result. + * For queries that receive data (INSERT), sets a thread in BlockIO where you can write data. + * For queries that do not require data and return nothing, BlockIO will be empty. */ virtual BlockIO execute() = 0; diff --git a/dbms/src/Interpreters/InterpreterAlterQuery.h b/dbms/src/Interpreters/InterpreterAlterQuery.h index 8e678f65570..04ef1f64c54 100644 --- a/dbms/src/Interpreters/InterpreterAlterQuery.h +++ b/dbms/src/Interpreters/InterpreterAlterQuery.h @@ -10,8 +10,8 @@ namespace DB { -/** Позволяет добавить или удалить столбец в таблице. - * Также позволяет осуществить манипуляции с партициями таблиц семейства MergeTree. +/** Allows you add or remove a column in the table. + * It also allows you to manipulate the partitions of the MergeTree family tables. */ class InterpreterAlterQuery : public IInterpreter { @@ -37,13 +37,13 @@ private: Field partition; Field column_name; - bool detach = false; /// true для DETACH PARTITION. + bool detach = false; /// true for DETACH PARTITION. bool part = false; - String from; /// Для FETCH PARTITION - путь в ZK к шарду, с которого скачивать партицию. + String from; /// For FETCH PARTITION - path in ZK to the shard, from which to download the partition. - /// Для RESHARD PARTITION. + /// For RESHARD PARTITION. Field last_partition; WeightedZooKeeperPaths weighted_zookeeper_paths; ASTPtr sharding_key_expr; diff --git a/dbms/src/Interpreters/InterpreterCreateQuery.cpp b/dbms/src/Interpreters/InterpreterCreateQuery.cpp index c8c871df714..295d97164bb 100644 --- a/dbms/src/Interpreters/InterpreterCreateQuery.cpp +++ b/dbms/src/Interpreters/InterpreterCreateQuery.cpp @@ -534,6 +534,8 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) context.getDatabase(database_name)->createTable(table_name, res, query_ptr, storage_name, context.getSettingsRef()); } + res->startup(); + /// If the CREATE SELECT query is, insert the data into the table if (create.select && storage_name != "View" && (storage_name != "MaterializedView" || create.is_populate)) { diff --git a/dbms/src/Interpreters/InterpreterInsertQuery.h b/dbms/src/Interpreters/InterpreterInsertQuery.h index 4f7695ffb60..7b9ccbd99ac 100644 --- a/dbms/src/Interpreters/InterpreterInsertQuery.h +++ b/dbms/src/Interpreters/InterpreterInsertQuery.h @@ -10,17 +10,17 @@ namespace DB { -/** Интерпретирует запрос INSERT. +/** Interprets the INSERT query. */ class InterpreterInsertQuery : public IInterpreter { public: InterpreterInsertQuery(const ASTPtr & query_ptr_, const Context & context_); - /** Подготовить запрос к выполнению. Вернуть потоки блоков - * - поток, в который можно писать данные для выполнения запроса, если INSERT; - * - поток, из которого можно читать результат выполнения запроса, если SELECT и подобные; - * Или ничего, если запрос INSERT SELECT (самодостаточный запрос - не принимает входные данные, не отдаёт результат). + /** Prepare a request for execution. Return block streams + * - the stream into which you can write data to execute the query, if INSERT; + * - the stream from which you can read the result of the query, if SELECT and similar; + * Or nothing if the request INSERT SELECT (self-sufficient query - does not accept the input data, does not return the result). */ BlockIO execute() override; diff --git a/dbms/src/Interpreters/InterpreterSelectQuery.h b/dbms/src/Interpreters/InterpreterSelectQuery.h index 5f4a33bf60a..67f5a208d79 100644 --- a/dbms/src/Interpreters/InterpreterSelectQuery.h +++ b/dbms/src/Interpreters/InterpreterSelectQuery.h @@ -17,27 +17,27 @@ class ASTSelectQuery; struct SubqueryForSet; -/** Интерпретирует запрос SELECT. Возвращает поток блоков с результатами выполнения запроса до стадии to_stage. +/** Interprets the SELECT query. Returns the stream of blocks with the results of the query before `to_stage` stage. */ class InterpreterSelectQuery : public IInterpreter { public: - /** to_stage - * - стадия, до которой нужно выполнить запрос. По-умолчанию - до конца. - * Можно выполнить до промежуточного состояния агрегации, которые объединяются с разных серверов при распределённой обработке запроса. + /** `to_stage` + * - the stage to which the query is to be executed. By default - till to the end. + * You can perform till the intermediate aggregation state, which are combined from different servers for distributed query processing. * * subquery_depth - * - для контроля ограничений на глубину вложенности подзапросов. Для подзапросов передаётся значение, увеличенное на единицу. + * - to control the restrictions on the depth of nesting of subqueries. For subqueries, a value that is incremented by one is passed. * * input - * - если задан - читать не из таблицы, указанной в запросе, а из готового источника. + * - if given - read not from the table specified in the query, but from ready source. * * required_column_names - * - удалить из запроса все столбцы кроме указанных - используется для удаления ненужных столбцов из подзапросов. + * - delete all columns except the specified ones from the query - it is used to delete unnecessary columns from subqueries. * * table_column_names - * - список доступных столбцов таблицы. - * Используется, например, совместно с указанием input. + * - the list of available columns of the table. + * Used, for example, with reference to `input`. */ InterpreterSelectQuery( @@ -66,12 +66,12 @@ public: ~InterpreterSelectQuery(); - /** Выполнить запрос, возможно являющиийся цепочкой UNION ALL. - * Получить поток блоков для чтения + /** Execute a query, possibly part of UNION ALL chain. + * Get the stream of blocks to read */ BlockIO execute() override; - /** Выполнить запрос без объединения потоков, если это возможно. + /** Execute the query without union of threads, if it is possible. */ const BlockInputStreams & executeWithoutUnion(); @@ -84,8 +84,8 @@ public: private: /** - * - Оптимизация, если объект создаётся только, чтобы вызвать getSampleBlock(): учитываем только первый SELECT цепочки UNION ALL, потому что - * первый SELECT достаточен для определения нужных столбцов. + * - Optimization if an object is created only to call getSampleBlock(): consider only the first SELECT of the UNION ALL chain, because + * the first SELECT is sufficient to determine the required columns. */ struct OnlyAnalyzeTag {}; InterpreterSelectQuery( @@ -97,12 +97,12 @@ private: void basicInit(BlockInputStreamPtr input); void initQueryAnalyzer(); - /// Выполнить один запрос SELECT из цепочки UNION ALL. + /// Execute one SELECT query from the UNION ALL chain. void executeSingleQuery(); - /** Оставить в каждом запросе цепочки UNION ALL только нужные столбцы секции SELECT. - * Однако, если используется хоть один DISTINCT в цепочке, то все столбцы считаются нужными, - * так как иначе DISTINCT работал бы по-другому. + /** Leave only the necessary columns of the SELECT section in each query of the UNION ALL chain. + * However, if you use at least one DISTINCT in the chain, then all the columns are considered necessary, + * since otherwise DISTINCT would work differently. * * Always leave arrayJoin, because it changes number of rows. * @@ -112,23 +112,23 @@ private: */ void rewriteExpressionList(const Names & required_column_names); - /// Содержит ли запрос хотя бы один астериск? + /// Does the request contain at least one asterisk? bool hasAsterisk() const; - // Переименовать столбцы каждого запроса цепочки UNION ALL в такие же имена, как в первом запросе. + // Rename the columns of each query for the UNION ALL chain into the same names as in the first query. void renameColumns(); - /** Из какой таблицы читать. При JOIN, возвращается "левая" таблица. + /** From which table to read. With JOIN, the "left" table is returned. */ void getDatabaseAndTableNames(String & database_name, String & table_name); - /** Выбрать из списка столбцов какой-нибудь, лучше - минимального размера. + /** Select from the list of columns any, better - with minimum size. */ String getAnyColumn(); - /// Разные стадии выполнения запроса. + /// Different stages of query execution. - /// Вынимает данные из таблицы. Возвращает стадию, до которой запрос был обработан в Storage. + /// Fetch data from the table. Returns the stage to which the query was processed in Storage. QueryProcessingStage::Enum executeFetchColumns(); void executeWhere(ExpressionActionsPtr expression); @@ -156,11 +156,11 @@ private: void ignoreWithTotals(); - /** Если в запросе SELECT есть секция SETTINGS, то применить настройки из неё. + /** If there is a SETTINGS section in the SELECT query, then apply settings from it. * - * Секция SETTINGS - настройки для конкретного запроса. - * Обычно настройки могут быть переданы другими способами, не внутри запроса. - * Но использование такой секции оправдано, если нужно задать настройки для одного подзапроса. + * Section SETTINGS - settings for a specific query. + * Normally, the settings can be passed in other ways, not inside the query. + * But the use of this section is justified if you need to set the settings for one subquery. */ void initSettings(); @@ -172,33 +172,33 @@ private: std::unique_ptr query_analyzer; NamesAndTypesList table_column_names; - /** Потоки данных. - * Исходные потоки данных получаются в функции executeFetchColumns. - * Затем они преобразуются (оборачиваются в другие потоки) с помощью функций execute*, - * чтобы получить целый конвейер выполнения запроса. + /** Streams of data. + * The source data streams are produced in the executeFetchColumns function. + * Then they are converted (wrapped in other streams) using the `execute*` functions, + * to get the whole pipeline running the query. */ BlockInputStreams streams; - /** При выполнении FULL или RIGHT JOIN, здесь будет поток данных, из которого можно прочитать "неприсоединённые" строки. - * Он имеет особое значение, так как чтение из него должно осуществляться после чтения из основных потоков. - * Он подклеивается к основным потокам в UnionBlockInputStream или ParallelAggregatingBlockInputStream. + /** When executing FULL or RIGHT JOIN, there will be a data stream from which you can read "not joined" rows. + * It has a special meaning, since reading from it should be done after reading from the main streams. + * It is joined to the main streams in UnionBlockInputStream or ParallelAggregatingBlockInputStream. */ BlockInputStreamPtr stream_with_non_joined_data; - /// Являемся ли мы первым запросом SELECT цепочки UNION ALL? + /// Is it the first SELECT query of the UNION ALL chain? bool is_first_select_inside_union_all; - /// Объект создан только для анализа запроса. + /// The object was created only for query analysis. bool only_analyze = false; - /// Следующий запрос SELECT в цепочке UNION ALL, если есть. + /// The next SELECT query in the UNION ALL chain, if any. std::unique_ptr next_select_in_union_all; - /// Таблица, откуда читать данные, если не подзапрос. + /// Table from where to read data, if not subquery. StoragePtr storage; TableStructureReadLockPtr table_lock; - /// Выполнить объединение потоков внутри запроса SELECT? + /// Do union of streams within a SELECT query? bool union_within_single_query = false; Poco::Logger * log; diff --git a/dbms/src/Interpreters/InterserverIOHandler.h b/dbms/src/Interpreters/InterserverIOHandler.h index 205e9bd3bb2..29717951253 100644 --- a/dbms/src/Interpreters/InterserverIOHandler.h +++ b/dbms/src/Interpreters/InterserverIOHandler.h @@ -22,7 +22,7 @@ namespace ErrorCodes extern const int NO_SUCH_INTERSERVER_IO_ENDPOINT; } -/** Местонахождение сервиса. +/** Location of the service. */ struct InterserverIOEndpointLocation { @@ -32,7 +32,7 @@ public: { } - /// Создаёт местонахождение на основе его сериализованного представления. + /// Creates a location based on its serialized representation. InterserverIOEndpointLocation(const std::string & serialized_location) { ReadBufferFromString buf(serialized_location); @@ -42,7 +42,7 @@ public: assertEOF(buf); } - /// Сериализует местонахождение. + /// Serializes the location. std::string toString() const { std::string serialized_location; @@ -60,7 +60,7 @@ public: UInt16 port; }; -/** Обработчик запросов от других серверов. +/** Query processor from other servers. */ class InterserverIOEndpoint { @@ -72,15 +72,15 @@ public: void cancel() { is_cancelled = true; } protected: - /// Нужно остановить передачу данных. + /// You need to stop the data transfer. std::atomic is_cancelled {false}; }; using InterserverIOEndpointPtr = std::shared_ptr; -/** Сюда можно зарегистрировать сервис, обрататывающий запросы от других серверов. - * Используется для передачи кусков в ReplicatedMergeTree. +/** Here you can register a service that processes requests from other servers. + * Used to transfer chunks in ReplicatedMergeTree. */ class InterserverIOHandler { @@ -116,7 +116,7 @@ private: std::mutex mutex; }; -/// В конструкторе вызывает addEndpoint, в деструкторе - removeEndpoint. +/// In the constructor calls `addEndpoint`, in the destructor - `removeEndpoint`. class InterserverIOEndpointHolder { public: @@ -136,8 +136,8 @@ public: try { handler.removeEndpoint(name); - /// После уничтожения объекта, endpoint ещё может жить, так как владение им захватывается на время обработки запроса, - /// см. InterserverIOHTTPHandler.cpp + /// After destroying the object, `endpoint` can still live, since its ownership is acquired during the processing of the request, + /// see InterserverIOHTTPHandler.cpp } catch (...) { diff --git a/dbms/src/Interpreters/LogicalExpressionsOptimizer.h b/dbms/src/Interpreters/LogicalExpressionsOptimizer.h index dfb17052e9b..8b0e1c7f9c5 100644 --- a/dbms/src/Interpreters/LogicalExpressionsOptimizer.h +++ b/dbms/src/Interpreters/LogicalExpressionsOptimizer.h @@ -16,20 +16,20 @@ struct Settings; class ASTFunction; class ASTSelectQuery; -/** Этот класс предоставляет функции для оптимизации логических выражений внутри запросов. +/** This class provides functions for optimizing boolean expressions within queries. * - * Для простоты назовём однородной OR-цепочой любое выражение имеющее следующую структуру: + * For simplicity, we call a homogeneous OR-chain any expression having the following structure: * expr = x1 OR ... OR expr = xN - * где expr - произвольное выражение и x1, ..., xN - литералы одного типа + * where `expr` is an arbitrary expression and x1, ..., xN are literals of the same type */ class LogicalExpressionsOptimizer final { public: - /// Конструктор. Принимает корень DAG запроса. + /// Constructor. Accepts the root of the query DAG. LogicalExpressionsOptimizer(ASTSelectQuery * select_query_, const Settings & settings_); - /** Заменить все довольно длинные однородные OR-цепочки expr = x1 OR ... OR expr = xN - * на выражения expr IN (x1, ..., xN). + /** Replace all rather long homogeneous OR-chains expr = x1 OR ... OR expr = xN + * on the expressions `expr` IN (x1, ..., xN). */ void perform(); @@ -37,7 +37,7 @@ public: LogicalExpressionsOptimizer & operator=(const LogicalExpressionsOptimizer &) = delete; private: - /** Функция OR с выражением. + /** The OR function with the expression. */ struct OrWithExpression { @@ -60,27 +60,27 @@ private: using DisjunctiveEqualityChain = DisjunctiveEqualityChainsMap::value_type; private: - /** Собрать информация про все равенства входящие в цепочки OR (не обязательно однородные). - * Эта информация сгруппирована по выражению, которое стоит в левой части равенства. + /** Collect information about all the equations in the OR chains (not necessarily homogeneous). + * This information is grouped by the expression that is on the left side of the equation. */ void collectDisjunctiveEqualityChains(); - /** Проверить, что множество равенств expr = x1, ..., expr = xN выполняет два следующих требования: - * 1. Оно не слишком маленькое - * 2. x1, ... xN имеют один и тот же тип + /** Check that the set of equalities expr = x1, ..., expr = xN fulfills the following two requirements: + * 1. It's not too small + * 2. x1, ... xN have the same type */ bool mayOptimizeDisjunctiveEqualityChain(const DisjunctiveEqualityChain & chain) const; - /// Вставить выражение IN в OR-цепочку. + /// Insert the IN expression into the OR chain. void addInExpression(const DisjunctiveEqualityChain & chain); - /// Удалить равенства, которые были заменены выражениями IN. + /// Delete the equalities that were replaced by the IN expressions. void cleanupOrExpressions(); - /// Удалить выражения OR, которые имеют только один операнд. + /// Delete OR expressions that have only one operand. void fixBrokenOrExpressions(); - /// Восстановить исходный порядок столбцов после оптимизации. + /// Restore the original column order after optimization. void reorderColumns(); private: @@ -91,13 +91,13 @@ private: private: ASTSelectQuery * select_query; const Settings & settings; - /// Информация про OR-цепочки внутри запроса. + /// Information about the OR-chains inside the query. DisjunctiveEqualityChainsMap disjunctive_equality_chains_map; - /// Количество обработанных OR-цепочек. + /// Number of processed OR-chains. size_t processed_count = 0; - /// Родители функций OR. + /// Parents of OR functions. FunctionParentMap or_parent_map; - /// Позиция каждого столбца. + /// The position of each column. ColumnToPosition column_to_position; /// Set of nodes, that was visited. std::unordered_set visited_nodes; diff --git a/dbms/src/Interpreters/QueryPriorities.h b/dbms/src/Interpreters/QueryPriorities.h index bad570b0d14..32544e5fd39 100644 --- a/dbms/src/Interpreters/QueryPriorities.h +++ b/dbms/src/Interpreters/QueryPriorities.h @@ -60,7 +60,7 @@ private: while (true) { - /// Если ли хотя бы один более приоритетный запрос? + /// Is there at least one more priority query? bool found = false; for (const auto & value : container) { diff --git a/dbms/src/Interpreters/Set.h b/dbms/src/Interpreters/Set.h index 1c16fb27e31..97aa6309d29 100644 --- a/dbms/src/Interpreters/Set.h +++ b/dbms/src/Interpreters/Set.h @@ -77,41 +77,41 @@ private: * We have not implemented such sophisticated behaviour. */ - /** Типы данных, из которых было создано множество. - * При проверке на принадлежность множеству, типы проверяемых столбцов должны с ними совпадать. + /** The data types from which the set was created. + * When checking for belonging to a set, the types of columns to be checked must match with them. */ DataTypes data_types; Logger * log; - /// Ограничения на максимальный размер множества + /// Limitations on the maximum size of the set size_t max_rows; size_t max_bytes; OverflowMode overflow_mode; - /// Если в левой части IN стоит массив. Проверяем, что хоть один элемент массива лежит в множестве. + /// If there is an array on the left side of IN. We check that at least one element of the array presents in the set. void executeArray(const ColumnArray * key_column, ColumnUInt8::Container_t & vec_res, bool negative) const; - /// Если в левой части набор столбцов тех же типов, что элементы множества. + /// If in the left part columns contains the same types as the elements of the set. void executeOrdinary( const ConstColumnPlainPtrs & key_columns, ColumnUInt8::Container_t & vec_res, bool negative, const PaddedPODArray * null_map) const; - /// Проверить не превышены ли допустимые размеры множества ключей + /// Check whether the permissible sizes of keys set reached bool checkSetSizeLimits() const; - /// Вектор упорядоченных элементов Set. - /// Нужен для работы индекса по первичному ключу в операторе IN. + /// Vector of ordered elements of `Set`. + /// It is necessary for the index to work on the primary key in the IN statement. using OrderedSetElements = std::vector; using OrderedSetElementsPtr = std::unique_ptr; OrderedSetElementsPtr ordered_set_elements; - /** Защищает работу с множеством в функциях insertFromBlock и execute. - * Эти функции могут вызываться одновременно из разных потоков только при использовании StorageSet, - * и StorageSet вызывает только эти две функции. - * Поэтому остальные функции по работе с множеством, не защинены. + /** Protects work with the set in the functions `insertFromBlock` and `execute`. + * These functions can be called simultaneously from different threads only when using StorageSet, + * and StorageSet calls only these two functions. + * Therefore, the rest of the functions for working with set are not protected. */ mutable Poco::RWLock rwlock; diff --git a/dbms/src/Interpreters/SetVariants.h b/dbms/src/Interpreters/SetVariants.h index 5fbe8513b8c..985514c6e74 100644 --- a/dbms/src/Interpreters/SetVariants.h +++ b/dbms/src/Interpreters/SetVariants.h @@ -18,8 +18,8 @@ namespace DB */ -/// Для случая, когда есть один числовой ключ. -template /// UInt8/16/32/64 для любых типов соответствующей битности. +/// For the case where there is one numeric key. +template /// UInt8/16/32/64 for any types with corresponding bit width. struct SetMethodOneNumber { using Data = TData; @@ -27,36 +27,36 @@ struct SetMethodOneNumber Data data; - /// Для использования одного Method в разных потоках, используйте разные State. + /// To use one `Method` in different threads, use different `State`. struct State { const FieldType * vec; - /** Вызывается в начале обработки каждого блока. - * Устанавливает переменные, необходимые для остальных методов, вызываемых во внутренних циклах. + /** Called at the start of each block processing. + * Sets the variables required for the other methods called in internal loops. */ void init(const ConstColumnPlainPtrs & key_columns) { vec = &static_cast *>(key_columns[0])->getData()[0]; } - /// Достать из ключевых столбцов ключ для вставки в хэш-таблицу. + /// Get key from key columns for insertion into hash table. Key getKey( - const ConstColumnPlainPtrs & key_columns, /// Ключевые столбцы. - size_t keys_size, /// Количество ключевых столбцов. - size_t i, /// Из какой строки блока достать ключ. - const Sizes & key_sizes) const /// Если ключи фиксированной длины - их длины. Не используется в методах по ключам переменной длины. + const ConstColumnPlainPtrs & key_columns, /// Key columns. + size_t keys_size, /// Number of key columns. + size_t i, /// From what row of the block I get the key. + const Sizes & key_sizes) const /// If keys of a fixed length - their lengths. Not used in methods for variable length keys. { return unionCastToUInt64(vec[i]); } }; - /** Разместить дополнительные данные, если это необходимо, в случае, когда в хэш-таблицу был вставлен новый ключ. + /** Place additional data, if necessary, in case a new key was inserted into the hash table. */ static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool) {} }; -/// Для случая, когда есть один строковый ключ. +/// For the case where there is one string key. template struct SetMethodString { @@ -96,7 +96,7 @@ struct SetMethodString } }; -/// Для случая, когда есть один строковый ключ фиксированной длины. +/// For the case when there is one fixed-length string key. template struct SetMethodFixedString { @@ -231,7 +231,7 @@ protected: } -/// Для случая, когда все ключи фиксированной длины, и они помещаются в N (например, 128) бит. +/// For the case when all keys are of fixed length, and they fit in N (for example, 128) bits. template struct SetMethodKeysFixed { @@ -271,7 +271,7 @@ struct SetMethodKeysFixed static void onNewKey(typename Data::value_type & value, size_t keys_size, size_t i, Arena & pool) {} }; -/// Для остальных случаев. По 128 битному хэшу от ключа. +/// For other cases. 128 bit hash from the key. template struct SetMethodHashed { @@ -300,17 +300,17 @@ struct SetMethodHashed }; -/** Разные варианты реализации множества. +/** Different implementations of the set. */ struct NonClearableSet { - /// TODO Использовать для этих двух вариантов bit- или byte- set. + /// TODO Use either bit- or byte-set for these two options. std::unique_ptr>>> key8; std::unique_ptr>>> key16; - /** Также для эксперимента проверялась возможность использовать SmallSet, - * пока количество элементов в множестве небольшое (и, при необходимости, конвертировать в полноценный HashSet). - * Но этот эксперимент показал, что преимущество есть только в редких случаях. + /** Also for the experiment was tested the ability to use SmallSet, + * as long as the number of elements in the set is small (and, if necessary, converted to a full-fledged HashSet). + * But this experiment showed that there is an advantage only in rare cases. */ std::unique_ptr>>> key32; std::unique_ptr>>> key64; @@ -323,15 +323,15 @@ struct NonClearableSet /// Support for nullable keys (for DISTINCT implementation). std::unique_ptr, true>> nullable_keys128; std::unique_ptr, true>> nullable_keys256; - /** В отличие от Aggregator, здесь не используется метод concat. - * Это сделано потому что метод hashed, хоть и медленнее, но в данном случае, использует меньше оперативки. - * так как при его использовании, сами значения ключей не сохраняются. + /** Unlike Aggregator, `concat` method is not used here. + * This is done because `hashed` method, although slower, but in this case, uses less RAM. + * since when you use it, the key values themselves are not stored. */ }; struct ClearableSet { - /// TODO Использовать для этих двух вариантов bit- или byte- set. + /// TODO Use either bit- or byte-set for these two options. std::unique_ptr>>> key8; std::unique_ptr>>> key16; @@ -346,9 +346,9 @@ struct ClearableSet /// Support for nullable keys (for DISTINCT implementation). std::unique_ptr, true>> nullable_keys128; std::unique_ptr, true>> nullable_keys256; - /** В отличие от Aggregator, здесь не используется метод concat. - * Это сделано потому что метод hashed, хоть и медленнее, но в данном случае, использует меньше оперативки. - * так как при его использовании, сами значения ключей не сохраняются. + /** Unlike Aggregator, `concat` method is not used here. + * This is done because `hashed` method, although slower, but in this case, uses less RAM. + * since when you use it, the key values themselves are not stored. */ }; @@ -392,7 +392,7 @@ struct SetVariantsTemplate: public Variant void init(Type type_); size_t getTotalRowCount() const; - /// Считает размер в байтах буфера Set и размер string_pool'а + /// Counts the size in bytes of the Set buffer and the size of the `string_pool` size_t getTotalByteCount() const; }; diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index 5653fe484a4..fd96cb9e35f 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -16,7 +16,7 @@ namespace DB */ struct Settings { - /// For initialization from empty initializer-list to be "value initialization", not "aggregate initialization" in С++14. + /// For initialization from empty initializer-list to be "value initialization", not "aggregate initialization" in C++14. /// http://en.cppreference.com/w/cpp/language/aggregate_initialization Settings() {} @@ -145,7 +145,7 @@ struct Settings M(SettingBool, force_index_by_date, 0) \ M(SettingBool, force_primary_key, 0) \ \ - /** In the INSERT query with specified columns, fill in the default values ​​only for columns with explicit DEFAULTs. */ \ + /** In the INSERT query with specified columns, fill in the default values only for columns with explicit DEFAULTs. */ \ M(SettingBool, strict_insert_defaults, 0) \ \ /** If the maximum size of mark_cache is exceeded, delete only records older than mark_cache_min_lifetime seconds. */ \ diff --git a/dbms/src/Interpreters/SettingsCommon.h b/dbms/src/Interpreters/SettingsCommon.h index 95e388a475e..ee2e0bf8213 100644 --- a/dbms/src/Interpreters/SettingsCommon.h +++ b/dbms/src/Interpreters/SettingsCommon.h @@ -26,11 +26,11 @@ namespace ErrorCodes } -/** Одна настройка какого-либо типа. - * Хранит внутри себя значение, а также флаг - было ли значение изменено. - * Это сделано, чтобы можно было отправлять на удалённые серверы только изменённые (или явно указанные в конфиге) значения. - * То есть, если настройка не была указана в конфиге и не была изменена динамически, то она не отправляется на удалённый сервер, - * и удалённый сервер будет использовать своё значение по-умолчанию. +/** One setting for any type. + * Stores a value within itself, as well as a flag - whether the value was changed. + * This is done so that you can send to the remote servers only changed settings (or explicitly specified in the config) values. + * That is, if the configuration was not specified in the config and was not dynamically changed, it is not sent to the remote server, + * and the remote server will use its default value. */ template @@ -83,9 +83,9 @@ using SettingInt64 = SettingInt; using SettingBool = SettingUInt64; -/** В отличие от SettingUInt64, поддерживает значение 'auto' - количество процессорных ядер без учёта SMT. - * Значение 0 так же воспринимается как auto. - * При сериализации, auto записывается так же, как 0. +/** Unlike SettingUInt64, supports the value of 'auto' - the number of processor cores without taking into account SMT. + * A value of 0 is also treated as auto. + * When serializing, `auto` is written in the same way as 0. */ struct SettingMaxThreads { @@ -100,7 +100,7 @@ struct SettingMaxThreads String toString() const { - /// Вместо значения auto выводим актуальное значение, чтобы его было легче посмотреть. + /// Instead of the `auto` value, we output the actual value to make it easier to see. return DB::toString(value); } @@ -151,7 +151,7 @@ struct SettingMaxThreads return res; } - /// Выполняется один раз за всё время. Выполняется из одного потока. + /// Executed once for all time. Executed from one thread. UInt64 getAutoValueImpl() const { return getNumberOfPhysicalCPUCores(); @@ -323,12 +323,12 @@ struct SettingFloat enum class LoadBalancing { - /// среди реплик с минимальным количеством ошибок выбирается случайная + /// among replicas with a minimum number of errors selected randomly RANDOM = 0, - /// среди реплик с минимальным количеством ошибок выбирается реплика - /// с минимальным количеством отличающихся символов в имени реплики и имени локального хоста + /// a replica is selected among the replicas with the minimum number of errors + /// with the minimum number of distinguished characters in the replica name and local hostname NEAREST_HOSTNAME, - /// реплики перебираются строго по порядку; количество ошибок не имеет значение + /// replicas are walked through strictly in order; the number of errors does not matter IN_ORDER, }; @@ -390,16 +390,16 @@ struct SettingLoadBalancing }; -/// Какие строки включать в TOTALS. +/// Which rows should be included in TOTALS. enum class TotalsMode { - BEFORE_HAVING = 0, /// Считать HAVING по всем прочитанным строкам; - /// включая не попавшие в max_rows_to_group_by - /// и не прошедшие HAVING после группировки. - AFTER_HAVING_INCLUSIVE = 1, /// Считать по всем строкам, кроме не прошедших HAVING; - /// то есть, включать в TOTALS все строки, не прошедшие max_rows_to_group_by. - AFTER_HAVING_EXCLUSIVE = 2, /// Включать только строки, прошедшие и max_rows_to_group_by, и HAVING. - AFTER_HAVING_AUTO = 3, /// Автоматически выбирать между INCLUSIVE и EXCLUSIVE, + BEFORE_HAVING = 0, /// Count HAVING for all read rows; + /// including those not in max_rows_to_group_by + /// and have not passed HAVING after grouping. + AFTER_HAVING_INCLUSIVE = 1, /// Count on all rows except those that have not passed HAVING; + /// that is, to include in TOTALS all the rows that did not pass max_rows_to_group_by. + AFTER_HAVING_EXCLUSIVE = 2, /// Include only the rows that passed and max_rows_to_group_by, and HAVING. + AFTER_HAVING_AUTO = 3, /// Automatically select between INCLUSIVE and EXCLUSIVE, }; struct SettingTotalsMode @@ -465,13 +465,13 @@ struct SettingTotalsMode } }; -/// Что делать, если ограничение превышено. +/// What to do if the limit is exceeded. enum class OverflowMode { - THROW = 0, /// Кинуть исключение. - BREAK = 1, /// Прервать выполнение запроса, вернуть что есть. - ANY = 2, /** Только для GROUP BY: не добавлять новые строки в набор, - * но продолжать агрегировать для ключей, успевших попасть в набор. + THROW = 0, /// Throw exception. + BREAK = 1, /// Abort query execution, return what is. + ANY = 2, /** Only for GROUP BY: do not add new rows to the set, + * but continue to aggregate for keys that are already in the set. */ }; @@ -613,13 +613,13 @@ struct SettingCompressionMethod } }; -/// Настройка для выполнения распределённых подзапросов внутри секций IN или JOIN. +/// The setting for executing distributed subqueries inside IN or JOIN sections. enum class DistributedProductMode { - DENY = 0, /// Запретить - LOCAL, /// Конвертировать в локальный запрос - GLOBAL, /// Конвертировать в глобальный запрос - ALLOW /// Разрешить + DENY = 0, /// Disable + LOCAL, /// Convert to local query + GLOBAL, /// Convert to global query + ALLOW /// Enable }; struct SettingDistributedProductMode @@ -680,11 +680,11 @@ struct SettingDistributedProductMode } }; -/// Способ выполнения глобальных распределённых подзапросов. +/// Method for executing global distributed subqueries. enum class GlobalSubqueriesMethod { - PUSH = 0, /// Отправлять данные подзапроса на все удалённые серверы. - PULL = 1, /// Удалённые серверы будут скачивать данные подзапроса с сервера-инициатора. + PUSH = 0, /// Send the subquery data to all remote servers. + PULL = 1, /// Remote servers will download the subquery data from the initiating server. }; struct SettingGlobalSubqueriesMethod diff --git a/dbms/src/Interpreters/SpecializedAggregator.h b/dbms/src/Interpreters/SpecializedAggregator.h index eea3a69708a..32291222060 100644 --- a/dbms/src/Interpreters/SpecializedAggregator.h +++ b/dbms/src/Interpreters/SpecializedAggregator.h @@ -22,16 +22,16 @@ namespace DB { -/** Шаблон цикла агрегации, позволяющий сгенерировать специализированный вариант для конкретной комбинации агрегатных функций. - * Отличается от обычного тем, что вызовы агрегатных функций должны инлайниться, а цикл обновления агрегатных функций должен развернуться. +/** An aggregation cycle template that allows you to generate a custom variant for a specific combination of aggregate functions. + * It differs from the usual one in that calls to aggregate functions should be inlined, and the update cycle of the aggregate functions should be unfold. * - * Так как возможных комбинаций слишком много, то не представляется возможным сгенерировать их все заранее. - * Этот шаблон предназначен для того, чтобы инстанцировать его в рантайме, - * путём запуска компилятора, компиляции shared library и использования её с помощью dlopen. + * Since there are too many possible combinations, it is not possible to generate them all in advance. + * This template is intended to instantiate it in runtime, + * by running the compiler, compiling shared library, and using it with `dlopen`. */ -/** Список типов - для удобного перечисления агрегатных функций. +/** List of types - for convenient listing of aggregate functions. */ template struct TypeList @@ -132,10 +132,10 @@ void AggregateFunctionsCreator::operator()() try { - /** Может возникнуть исключение при нехватке памяти. - * Для того, чтобы потом всё правильно уничтожилось, "откатываем" часть созданных состояний. - * Код не очень удобный. - */ + /** An exception may occur if there is a shortage of memory. + * To ensure that everything is properly destroyed, we "roll back" some of the created states. + * The code is not very convenient. + */ func->create(aggregate_data + offsets_of_aggregate_states[column_num]); } catch (...) @@ -186,27 +186,27 @@ void NO_INLINE Aggregator::executeSpecializedCase( StringRefs & keys, AggregateDataPtr overflow_row) const { - /// Для всех строчек. + /// For all rows. typename Method::iterator it; typename Method::Key prev_key; for (size_t i = 0; i < rows; ++i) { - bool inserted; /// Вставили новый ключ, или такой ключ уже был? - bool overflow = false; /// Новый ключ не поместился в хэш-таблицу из-за no_more_keys. + bool inserted; /// Inserted a new key, or was this key already? + bool overflow = false; /// New key did not fit in the hash table because of no_more_keys. - /// Получаем ключ для вставки в хэш-таблицу. + /// Get the key to insert into the hash table. typename Method::Key key = state.getKey(key_columns, params.keys_size, i, key_sizes, keys, *aggregates_pool); - if (!no_more_keys) /// Вставляем. + if (!no_more_keys) /// Insert. { - /// Оптимизация для часто повторяющихся ключей. + /// Optimization for frequently repeating keys. if (!Method::no_consecutive_keys_optimization) { if (i != 0 && key == prev_key) { AggregateDataPtr value = Method::getAggregateData(it->second); - /// Добавляем значения в агрегатные функции. + /// Add values into aggregate functions. AggregateFunctionsList::forEach(AggregateFunctionsUpdater( aggregate_functions, offsets_of_aggregate_states, aggregate_columns, value, i, aggregates_pool)); @@ -221,21 +221,21 @@ void NO_INLINE Aggregator::executeSpecializedCase( } else { - /// Будем добавлять только если ключ уже есть. + /// Add only if the key already exists. inserted = false; it = method.data.find(key); if (method.data.end() == it) overflow = true; } - /// Если ключ не поместился, и данные не надо агрегировать в отдельную строку, то делать нечего. + /// If the key does not fit, and the data does not need to be aggregated in a separate row, then there's nothing to do. if (no_more_keys && overflow && !overflow_row) { method.onExistingKey(key, keys, *aggregates_pool); continue; } - /// Если вставили новый ключ - инициализируем состояния агрегатных функций, и возможно, что-нибудь связанное с ключом. + /// If a new key is inserted, initialize the states of the aggregate functions, and possibly some stuff related to the key. if (inserted) { AggregateDataPtr & aggregate_data = Method::getAggregateData(it->second); @@ -255,7 +255,7 @@ void NO_INLINE Aggregator::executeSpecializedCase( AggregateDataPtr value = (!no_more_keys || !overflow) ? Method::getAggregateData(it->second) : overflow_row; - /// Добавляем значения в агрегатные функции. + /// Add values into the aggregate functions. AggregateFunctionsList::forEach(AggregateFunctionsUpdater( aggregate_functions, offsets_of_aggregate_states, aggregate_columns, value, i, aggregates_pool)); } @@ -270,7 +270,7 @@ void NO_INLINE Aggregator::executeSpecializedWithoutKey( AggregateColumns & aggregate_columns, Arena * arena) const { - /// Оптимизация в случае единственной агрегатной функции count. + /// Optimization in the case of a single aggregate function `count`. AggregateFunctionCount * agg_count = params.aggregates_size == 1 ? typeid_cast(aggregate_functions[0]) : NULL; @@ -290,25 +290,25 @@ void NO_INLINE Aggregator::executeSpecializedWithoutKey( } -/** Основной код компилируется с помощью gcc 5. - * Но SpecializedAggregator компилируется с помощью clang 3.6 в .so-файл. - * Это делается потому что gcc не удаётся заставить инлайнить функции, - * которые были девиртуализированы, в конкретном случае, и производительность получается ниже. - * А также clang проще распространять для выкладки на серверы. +/** The main code is compiled with gcc 5. + * But SpecializedAggregator is compiled using clang 3.6 into the .so file. + * This is done because gcc can not get functions inlined, + * which were de-virtualized, in a particular case, and the performance is lower. + * And also it's easier to distribute clang for deploy to the servers. * - * После перехода с gcc 4.8 и gnu++1x на gcc 4.9 и gnu++1y (а затем на gcc 5), - * при dlopen стала возникать ошибка: undefined symbol: __cxa_pure_virtual + * After switching from gcc 4.8 and gnu++1x to gcc 4.9 and gnu++1y (and then to gcc 5), + * an error occurred with `dlopen`: undefined symbol: __cxa_pure_virtual * - * Скорее всего, это происходит из-за изменившейся версии этого символа: - * gcc создаёт в .so символ + * Most likely, this is due to the changed version of this symbol: + * gcc creates a symbol in .so * U __cxa_pure_virtual@@CXXABI_1.3 - * а clang создаёт символ + * but clang creates a symbol * U __cxa_pure_virtual * - * Но нам не принципиально, как будет реализована функция __cxa_pure_virtual, - * потому что она не вызывается при нормальной работе программы, - * а если вызывается - то программа и так гарантированно глючит. + * But it does not matter for us how the __cxa_pure_virtual function will be implemented, + * because it is not called during normal program execution, + * and if called - then the program is guaranteed buggy. * - * Поэтому, мы можем обойти проблему таким образом: + * Therefore, we can work around the problem this way */ extern "C" void __attribute__((__visibility__("default"), __noreturn__)) __cxa_pure_virtual() { abort(); }; diff --git a/dbms/src/Interpreters/SystemLog.cpp b/dbms/src/Interpreters/SystemLog.cpp new file mode 100644 index 00000000000..a68a55c79b2 --- /dev/null +++ b/dbms/src/Interpreters/SystemLog.cpp @@ -0,0 +1,11 @@ +#include +#include +#include + + +namespace DB +{ + +SystemLogs::~SystemLogs() = default; + +} diff --git a/dbms/src/Interpreters/SystemLog.h b/dbms/src/Interpreters/SystemLog.h index 904d59db099..7b9f43a26a5 100644 --- a/dbms/src/Interpreters/SystemLog.h +++ b/dbms/src/Interpreters/SystemLog.h @@ -18,6 +18,7 @@ #include #include #include +#include namespace DB @@ -51,6 +52,21 @@ namespace DB #define DBMS_SYSTEM_LOG_QUEUE_SIZE 1024 class Context; +class QueryLog; +class PartLog; + + +/// System logs should be destroyed in destructor of last Context and before tables, +/// because SystemLog destruction makes insert query while flushing data into underlying tables +struct SystemLogs +{ + ~SystemLogs(); + + std::unique_ptr query_log; /// Used to log queries. + std::unique_ptr part_log; /// Used to log operations with parts +}; + + template @@ -224,7 +240,7 @@ void SystemLog::flush() Block block = LogElement::createBlock(); for (const LogElement & elem : data) elem.appendToBlock(block); - + /// Clear queue early, because insertion to the table could lead to generation of more log entrites /// and pushing them to already full queue will lead to deadlock. data.clear(); @@ -267,7 +283,7 @@ void SystemLog::prepareTable() if (!blocksHaveEqualStructure(actual, expected)) { - /// Переименовываем существующую таблицу. + /// Rename the existing table. int suffix = 0; while (context.isTableExist(database_name, table_name + "_" + toString(suffix))) ++suffix; @@ -293,7 +309,7 @@ void SystemLog::prepareTable() InterpreterRenameQuery(rename, context).execute(); - /// Нужная таблица будет создана. + /// The required table will be created. table = nullptr; } else @@ -302,7 +318,7 @@ void SystemLog::prepareTable() if (!table) { - /// Создаём таблицу. + /// Create the table. LOG_DEBUG(log, "Creating new table " << description << " for " + LogElement::name()); auto create = std::make_shared(); diff --git a/dbms/src/Interpreters/Users.cpp b/dbms/src/Interpreters/Users.cpp index 44bfb7b1aa0..a4891d09188 100644 --- a/dbms/src/Interpreters/Users.cpp +++ b/dbms/src/Interpreters/Users.cpp @@ -21,7 +21,7 @@ #include -#include +#include namespace DB diff --git a/dbms/src/Interpreters/convertFieldToType.h b/dbms/src/Interpreters/convertFieldToType.h index 1461ee72e3e..801beddd876 100644 --- a/dbms/src/Interpreters/convertFieldToType.h +++ b/dbms/src/Interpreters/convertFieldToType.h @@ -8,12 +8,12 @@ namespace DB class IDataType; -/** Используется для интерпретации выражений в множестве в IN, - * а также в запросе вида INSERT ... VALUES ... +/** Used to interpret expressions in a set in IN, + * and also in the query of the form INSERT ... VALUES ... * - * Чтобы корректно работали выражения вида 1.0 IN (1) или чтобы 1 IN (1, 2.0, 2.5, -1) работало так же, как 1 IN (1, 2). - * Проверяет совместимость типов, проверяет попадание значений в диапазон допустимых значений типа, делает преобразование типа. - * Если значение не попадает в диапазон - возвращает Null. + * To work correctly with expressions of the form `1.0 IN (1)` or, for example, `1 IN (1, 2.0, 2.5, -1)` work the same way as `1 IN (1, 2)`. + * Checks for the compatibility of types, checks values fall in the range of valid values of the type, makes type conversion. + * If the value does not fall into the range - returns Null. */ Field convertFieldToType(const Field & from_value, const IDataType & to_type, const IDataType * from_type_hint = nullptr); diff --git a/dbms/src/Interpreters/getClusterName.h b/dbms/src/Interpreters/getClusterName.h index d218d839460..dab45713345 100644 --- a/dbms/src/Interpreters/getClusterName.h +++ b/dbms/src/Interpreters/getClusterName.h @@ -8,13 +8,13 @@ namespace DB class IAST; -/// Получить имя кластера из AST. -/** Имя кластера - это имя тега в xml-конфигурации. - * Обычно оно парсится как идентификатор. То есть, оно может содержать подчёркивания, но не может содержать дефисы, - * при условии, что идентификатор не находится в обратных кавычках. - * Но в xml в качестве имени тега более привычно использовать дефисы. - * Такое имя будет парситься как выражение с оператором минус - совсем не то, что нужно. - * Поэтому, рассмотрим такой случай отдельно. +/// Get the cluster name from AST. +/** The name of the cluster is the name of the tag in the xml configuration. + * Usually it is parsed as an identifier. That is, it can contain underscores, but can not contain hyphens, + * provided that the identifier is not in backquotes. + * But in xml, as a tag name, it's more common to use hyphens. + * This name will be parsed as an expression with an operator minus - not at all what you need. + * Therefore, consider this case separately. */ std::string getClusterName(const IAST & node); diff --git a/dbms/src/Interpreters/sortBlock.h b/dbms/src/Interpreters/sortBlock.h index e9a83ea4ddc..7cd4824a904 100644 --- a/dbms/src/Interpreters/sortBlock.h +++ b/dbms/src/Interpreters/sortBlock.h @@ -7,25 +7,25 @@ namespace DB { -/// Отсортировать один блок по описанию desc. Если limit != 0, то производится partial sort первых limit строк. +/// Sort one block by `description`. If limit != 0, then the partial sort of the first `limit` rows is produced. void sortBlock(Block & block, const SortDescription & description, size_t limit = 0); -/** Используется только в StorageMergeTree для сортировки данных при INSERT-е. - * Сортировка стабильная. Это важно для сохранения порядка записей в движке CollapsingMergeTree - * - так как на основе порядка записей определяется, удалять ли или оставлять группы строчек при коллапсировании. - * Не поддерживаются collations. Не поддерживается частичная сортировка. +/** Used only in StorageMergeTree to sort the data with INSERT. + * Sorting is stable. This is important for keeping the order of rows in the CollapsingMergeTree engine + * - because based on the order of rows it is determined whether to delete or leave groups of rows when collapsing. + * Collations are not supported. Partial sorting is not supported. */ void stableSortBlock(Block & block, const SortDescription & description); -/** То же, что и stableSortBlock, но не сортировать блок, а только рассчитать перестановку значений, - * чтобы потом можно было переставить значения столбцов самостоятельно. +/** Same as stableSortBlock, but do not sort the block, but only calculate the permutation of the values, + * so that you can rearrange the column values yourself. */ void stableGetPermutation(const Block & block, const SortDescription & description, IColumn::Permutation & out_permutation); -/** Быстро проверить, является ли блок уже отсортированным. Если блок не отсортирован - возвращает false максимально быстро. - * Не поддерживаются collations. +/** Quickly check whether the block is already sorted. If the block is not sorted - returns false as fast as possible. + * Collations are not supported. */ bool isAlreadySorted(const Block & block, const SortDescription & description); diff --git a/dbms/src/Interpreters/tests/in_join_subqueries_preprocessor.cpp b/dbms/src/Interpreters/tests/in_join_subqueries_preprocessor.cpp index a786f061a94..931c0758dfb 100644 --- a/dbms/src/Interpreters/tests/in_join_subqueries_preprocessor.cpp +++ b/dbms/src/Interpreters/tests/in_join_subqueries_preprocessor.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include @@ -27,16 +27,11 @@ namespace DB /// Simplified version of the StorageDistributed class. -class StorageDistributedFake : private ext::shared_ptr_helper, public DB::IStorage +class StorageDistributedFake : public ext::shared_ptr_helper, public DB::IStorage { friend class ext::shared_ptr_helper; public: - static DB::StoragePtr create(const std::string & remote_database_, const std::string & remote_table_, size_t shard_count_) - { - return make_shared(remote_database_, remote_table_, shard_count_); - } - std::string getName() const override { return "DistributedFake"; } bool isRemote() const override { return true; } size_t getShardCount() const { return shard_count; } diff --git a/dbms/src/Interpreters/tests/select_query.cpp b/dbms/src/Interpreters/tests/select_query.cpp index 76ad62c994c..0343aeaa6f4 100644 --- a/dbms/src/Interpreters/tests/select_query.cpp +++ b/dbms/src/Interpreters/tests/select_query.cpp @@ -40,8 +40,8 @@ try DatabasePtr system = std::make_shared("system", "./metadata/system/"); context.addDatabase("system", system); system->loadTables(context, nullptr, false); - system->attachTable("one", StorageSystemOne::create("one")); - system->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system->attachTable("one", StorageSystemOne::create("one")); + system->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); context.setCurrentDatabase("default"); ReadBufferFromIStream in(std::cin); diff --git a/dbms/src/Server/HTTPHandler.cpp b/dbms/src/Server/HTTPHandler.cpp index 4045885d618..fb2863c14db 100644 --- a/dbms/src/Server/HTTPHandler.cpp +++ b/dbms/src/Server/HTTPHandler.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include @@ -80,6 +80,7 @@ namespace ErrorCodes extern const int INVALID_SESSION_TIMEOUT; } + static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int exception_code) { using namespace Poco::Net; @@ -127,30 +128,21 @@ static Poco::Net::HTTPResponse::HTTPStatus exceptionCodeToHTTPStatus(int excepti static std::chrono::steady_clock::duration parseSessionTimeout(const HTMLForm & params) { - int session_timeout; + const auto & config = Poco::Util::Application::instance().config(); + unsigned session_timeout = config.getInt("default_session_timeout", 60); if (params.has("session_timeout")) { - auto max_session_timeout = Poco::Util::Application::instance().config().getInt("max_session_timeout", 3600); - auto session_timeout_str = params.get("session_timeout"); + unsigned max_session_timeout = config.getUInt("max_session_timeout", 3600); + std::string session_timeout_str = params.get("session_timeout"); - try - { - session_timeout = std::stoi(session_timeout_str); - } - catch (...) - { - session_timeout = -1; - } + session_timeout = parse(session_timeout_str); - if (session_timeout < 0 || max_session_timeout < session_timeout) - throw Exception("Invalid session timeout '" + session_timeout_str + "', valid values are integers from 0 to " + std::to_string(max_session_timeout), + if (session_timeout > max_session_timeout) + throw Exception("Session timeout '" + session_timeout_str + "' is larger than max_session_timeout: " + toString(max_session_timeout) + + ". Maximum session timeout could be modified in configuration file.", ErrorCodes::INVALID_SESSION_TIMEOUT); } - else - { - session_timeout = Poco::Util::Application::instance().config().getInt("default_session_timeout", 60); - } return std::chrono::seconds(session_timeout); } @@ -196,6 +188,7 @@ HTTPHandler::HTTPHandler(Server & server_) { } + void HTTPHandler::processQuery( Poco::Net::HTTPServerRequest & request, HTMLForm & params, @@ -213,7 +206,6 @@ void HTTPHandler::processQuery( if (!query_param.empty()) query_param += '\n'; - /// User name and password can be passed using query parameters or using HTTP Basic auth (both methods are insecure). /// The user and password can be passed by headers (similar to X-Auth-*), which is used by load balancers to pass authentication information std::string user = request.get("X-ClickHouse-User", params.get("user", "default")); @@ -236,6 +228,9 @@ void HTTPHandler::processQuery( context.setUser(user, password, request.clientAddress(), quota_key); context.setCurrentQueryId(query_id); + /// The user could specify session identifier and session timeout. + /// It allows to modify settings, create temporary tables and reuse them in subsequent requests. + std::shared_ptr session; String session_id; std::chrono::steady_clock::duration session_timeout; diff --git a/dbms/src/Server/Server.cpp b/dbms/src/Server/Server.cpp index 4d160fae787..9cee2db7efa 100644 --- a/dbms/src/Server/Server.cpp +++ b/dbms/src/Server/Server.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/dbms/src/Server/TCPHandler.cpp b/dbms/src/Server/TCPHandler.cpp index 23b36c9c2b7..28d6ef551ff 100644 --- a/dbms/src/Server/TCPHandler.cpp +++ b/dbms/src/Server/TCPHandler.cpp @@ -630,6 +630,7 @@ bool TCPHandler::receiveData() { NamesAndTypesListPtr columns = std::make_shared(block.getColumnsList()); storage = StorageMemory::create(external_table_name, columns); + storage->startup(); query_context.addExternalTable(external_table_name, storage); } /// The data will be written directly to the table. diff --git a/dbms/src/Storages/IStorage.h b/dbms/src/Storages/IStorage.h index ca7870696f4..d41c99153a7 100644 --- a/dbms/src/Storages/IStorage.h +++ b/dbms/src/Storages/IStorage.h @@ -74,8 +74,8 @@ using TableFullWriteLockPtr = std::pair #include #include -#include -#include -#include +#include +#include +#include namespace DB diff --git a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp index f2ec320954a..21ebfdb36d1 100644 --- a/dbms/src/Storages/MergeTree/DataPartsExchange.cpp +++ b/dbms/src/Storages/MergeTree/DataPartsExchange.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include diff --git a/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp b/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp index 8de82e13386..854ab1b7b74 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeBaseBlockInputStream.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include namespace DB diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp index 1baebb13c86..d4369a5c74d 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataPart.cpp @@ -305,12 +305,13 @@ size_t MergeTreeDataPart::getColumnUncompressedSize(const String & name) const /** Returns the name of a column with minimum compressed size (as returned by getColumnSize()). - * If no checksums are present returns the name of the first physically existing column. */ + * If no checksums are present returns the name of the first physically existing column. + */ String MergeTreeDataPart::getColumnNameWithMinumumCompressedSize() const { const auto & columns = storage.getColumnsList(); const std::string * minimum_size_column = nullptr; - auto minimum_size = std::numeric_limits::max(); + size_t minimum_size = std::numeric_limits::max(); for (const auto & column : columns) { diff --git a/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp b/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp index 113e866336f..c548ee560ee 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeDataWriter.cpp @@ -161,7 +161,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeDataWriter::writeTempPart(BlockWithDa ProfileEvents::increment(ProfileEvents::MergeTreeDataWriterUncompressedBytes, block.bytes()); ProfileEvents::increment(ProfileEvents::MergeTreeDataWriterCompressedBytes, new_data_part->size_in_bytes); - if (std::shared_ptr part_log = context.getPartLog()) + if (auto part_log = context.getPartLog(data.getDatabaseName(), data.getTableName())) { PartLogElement elem; elem.event_time = time(0); diff --git a/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp b/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp index 2b2774feb22..e4bf988fc70 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReadPool.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include namespace ProfileEvents diff --git a/dbms/src/Storages/MergeTree/MergeTreeReader.cpp b/dbms/src/Storages/MergeTree/MergeTreeReader.cpp index ebf8515ea2d..96118082f7a 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeReader.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeReader.cpp @@ -433,9 +433,9 @@ void MergeTreeReader::addStream(const String & name, const IDataType & type, con void MergeTreeReader::readData( - const String & name, const IDataType & type, IColumn & column, - size_t from_mark, size_t max_rows_to_read, - size_t level, bool read_offsets) + const String & name, const IDataType & type, IColumn & column, + size_t from_mark, size_t max_rows_to_read, + size_t level, bool read_offsets) { if (type.isNullable()) { diff --git a/dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp b/dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp index 17cbd510260..6459cb7af02 100644 --- a/dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp +++ b/dbms/src/Storages/MergeTree/MergeTreeWhereOptimizer.cpp @@ -11,8 +11,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/dbms/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.h b/dbms/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.h index bc91303cdd6..8e4f2b9f633 100644 --- a/dbms/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.h +++ b/dbms/src/Storages/MergeTree/ReplicatedMergeTreePartCheckThread.h @@ -85,7 +85,7 @@ private: /** Parts for which you want to check one of two: * - If we have the part, check, its data with its checksums, and them with ZooKeeper. - * - If we do not have a part, check to see if it (or the part covering it) exists anywhere. + * - If we do not have a part, check to see if it (or the part covering it) exists anywhere on another replicas. */ StringSet parts_set; diff --git a/dbms/src/Storages/StorageBuffer.cpp b/dbms/src/Storages/StorageBuffer.cpp index 6d34d58e287..50665fa988c 100644 --- a/dbms/src/Storages/StorageBuffer.cpp +++ b/dbms/src/Storages/StorageBuffer.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include namespace ProfileEvents @@ -43,20 +43,6 @@ namespace ErrorCodes } -StoragePtr StorageBuffer::create(const std::string & name_, NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - Context & context_, - size_t num_shards_, const Thresholds & min_thresholds_, const Thresholds & max_thresholds_, - const String & destination_database_, const String & destination_table_) -{ - return make_shared( - name_, columns_, materialized_columns_, alias_columns_, column_defaults_, - context_, num_shards_, min_thresholds_, max_thresholds_, destination_database_, destination_table_); -} - - StorageBuffer::StorageBuffer(const std::string & name_, NamesAndTypesListPtr columns_, const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & alias_columns_, @@ -70,8 +56,7 @@ StorageBuffer::StorageBuffer(const std::string & name_, NamesAndTypesListPtr col min_thresholds(min_thresholds_), max_thresholds(max_thresholds_), destination_database(destination_database_), destination_table(destination_table_), no_destination(destination_database.empty() && destination_table.empty()), - log(&Logger::get("StorageBuffer (" + name + ")")), - flush_thread(&StorageBuffer::flushThread, this) + log(&Logger::get("StorageBuffer (" + name + ")")) { } @@ -346,6 +331,12 @@ BlockOutputStreamPtr StorageBuffer::write(const ASTPtr & query, const Settings & } +void StorageBuffer::startup() +{ + flush_thread = std::thread(&StorageBuffer::flushThread, this); +} + + void StorageBuffer::shutdown() { shutdown_event.set(); diff --git a/dbms/src/Storages/StorageBuffer.h b/dbms/src/Storages/StorageBuffer.h index 48cecab4345..10e9acb043c 100644 --- a/dbms/src/Storages/StorageBuffer.h +++ b/dbms/src/Storages/StorageBuffer.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -25,18 +25,18 @@ class Context; * The buffer is a set of num_shards blocks. * When writing, select the block number by the remainder of the `ThreadNumber` division by `num_shards` (or one of the others), * and add rows to the corresponding block. - * When using a block, it is blocked by some mutex. If during write the corresponding block is already occupied - * - try to block the next block clockwise, and so no more than `num_shards` times (further blocked). + * When using a block, it is locked by some mutex. If during write the corresponding block is already occupied + * - try to lock the next block in a round-robin fashion, and so no more than `num_shards` times (then wait for lock). * Thresholds are checked on insertion, and, periodically, in the background thread (to implement time thresholds). * Thresholds act independently for each shard. Each shard can be flushed independently of the others. * If a block is inserted into the table, which itself exceeds the max-thresholds, it is written directly to the subordinate table without buffering. * Thresholds can be exceeded. For example, if max_rows = 1 000 000, the buffer already had 500 000 rows, - * and a part of 800,000 lines is added, then there will be 1 300 000 rows in the buffer, and then such a block will be written to the subordinate table + * and a part of 800 000 rows is added, then there will be 1 300 000 rows in the buffer, and then such a block will be written to the subordinate table. * - * When you destroy a Buffer type table and when you quit, all data is discarded. + * When you destroy a Buffer table, all remaining data is flushed to the subordinate table. * The data in the buffer is not replicated, not logged to disk, not indexed. With a rough restart of the server, the data is lost. */ -class StorageBuffer : private ext::shared_ptr_helper, public IStorage +class StorageBuffer : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class BufferBlockInputStream; @@ -51,17 +51,6 @@ public: size_t bytes; /// The number of (uncompressed) bytes in the block. }; - /** num_shards - the level of internal parallelism (the number of independent buffers) - * The buffer is reset if all minimum thresholds or at least one of the maximum thresholds are exceeded. - */ - static StoragePtr create(const std::string & name_, NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - Context & context_, - size_t num_shards_, const Thresholds & min_thresholds_, const Thresholds & max_thresholds_, - const String & destination_database_, const String & destination_table_); - std::string getName() const override { return "Buffer"; } std::string getTableName() const override { return name; } @@ -77,7 +66,8 @@ public: BlockOutputStreamPtr write(const ASTPtr & query, const Settings & settings) override; - /// Resets all buffers to the subordinate table. + void startup() override; + /// Flush all buffers into the subordinate table and stop background thread. void shutdown() override; bool optimize(const String & partition, bool final, bool deduplicate, const Settings & settings) override; @@ -122,6 +112,9 @@ private: /// Resets data by timeout. std::thread flush_thread; + /** num_shards - the level of internal parallelism (the number of independent buffers) + * The buffer is flushed if all minimum thresholds or at least one of the maximum thresholds are exceeded. + */ StorageBuffer(const std::string & name_, NamesAndTypesListPtr columns_, const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & alias_columns_, diff --git a/dbms/src/Storages/StorageCloud.cpp b/dbms/src/Storages/StorageCloud.cpp index 16c8ecad894..ee926e81659 100644 --- a/dbms/src/Storages/StorageCloud.cpp +++ b/dbms/src/Storages/StorageCloud.cpp @@ -28,17 +28,4 @@ StorageCloud::StorageCloud( DatabaseCloud & db = static_cast(*owned_db); } - -StoragePtr StorageCloud::create( - DatabasePtr & database_ptr_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_) -{ - return make_shared(database_ptr_, name_, columns_, materialized_columns_, alias_columns_, column_defaults_); -} - - } diff --git a/dbms/src/Storages/StorageCloud.h b/dbms/src/Storages/StorageCloud.h index cc0c4d8d30f..fcd72c46bb5 100644 --- a/dbms/src/Storages/StorageCloud.h +++ b/dbms/src/Storages/StorageCloud.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -16,19 +16,11 @@ class Context; /** Cloud table. It can only be in the cloud database. * When writing to a table, data is written to local tables on multiple cloud servers. */ -class StorageCloud : private ext::shared_ptr_helper, public IStorage +class StorageCloud : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create( - DatabasePtr & database_ptr_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_); - std::string getName() const override { return "Cloud"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/StorageDistributed.cpp b/dbms/src/Storages/StorageDistributed.cpp index 784d4b6b9cf..cae28ed6de4 100644 --- a/dbms/src/Storages/StorageDistributed.cpp +++ b/dbms/src/Storages/StorageDistributed.cpp @@ -122,6 +122,10 @@ void initializeFileNamesIncrement(const std::string & path, SimpleIncrement & in } +/// For destruction of std::unique_ptr of type that is incomplete in class definition. +StorageDistributed::~StorageDistributed() = default; + + StorageDistributed::StorageDistributed( const std::string & name_, NamesAndTypesListPtr columns_, @@ -138,8 +142,6 @@ StorageDistributed::StorageDistributed( sharding_key_column_name(sharding_key_ ? sharding_key_->getColumnName() : String{}), path(data_path_.empty() ? "" : (data_path_ + escapeForFileName(name) + '/')) { - createDirectoryMonitors(); - initializeFileNamesIncrement(path, file_names_increment); } @@ -163,35 +165,10 @@ StorageDistributed::StorageDistributed( sharding_key_column_name(sharding_key_ ? sharding_key_->getColumnName() : String{}), path(data_path_.empty() ? "" : (data_path_ + escapeForFileName(name) + '/')) { - createDirectoryMonitors(); - initializeFileNamesIncrement(path, file_names_increment); } -StoragePtr StorageDistributed::create( - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - const String & remote_database_, - const String & remote_table_, - const String & cluster_name_, - const Context & context_, - const ASTPtr & sharding_key_, - const String & data_path_) -{ - return make_shared( - name_, columns_, - materialized_columns_, alias_columns_, column_defaults_, - remote_database_, remote_table_, - cluster_name_, context_, - sharding_key_, data_path_ - ); -} - - -StoragePtr StorageDistributed::create( +StoragePtr StorageDistributed::createWithOwnCluster( const std::string & name_, NamesAndTypesListPtr columns_, const String & remote_database_, @@ -201,8 +178,7 @@ StoragePtr StorageDistributed::create( { auto res = make_shared( name_, columns_, remote_database_, - remote_table_, String{}, context_ - ); + remote_table_, String{}, context_); res->owned_cluster = owned_cluster_; @@ -288,6 +264,13 @@ void StorageDistributed::alter(const AlterCommands & params, const String & data } +void StorageDistributed::startup() +{ + createDirectoryMonitors(); + initializeFileNamesIncrement(path, file_names_increment); +} + + void StorageDistributed::shutdown() { directory_monitors.clear(); diff --git a/dbms/src/Storages/StorageDistributed.h b/dbms/src/Storages/StorageDistributed.h index e13beda1e35..73b02fd947e 100644 --- a/dbms/src/Storages/StorageDistributed.h +++ b/dbms/src/Storages/StorageDistributed.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -25,27 +25,16 @@ class StorageDistributedDirectoryMonitor; * You can pass one address, not several. * In this case, the table can be considered remote, rather than distributed. */ -class StorageDistributed : private ext::shared_ptr_helper, public IStorage +class StorageDistributed : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class DistributedBlockOutputStream; friend class StorageDistributedDirectoryMonitor; public: - static StoragePtr create( - const std::string & name_, /// The name of the table. - NamesAndTypesListPtr columns_, /// List of columns. - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - const String & remote_database_, /// database on remote servers. - const String & remote_table_, /// The name of the table on the remote servers. - const String & cluster_name, - const Context & context_, - const ASTPtr & sharding_key_, - const String & data_path_); + ~StorageDistributed() override; - static StoragePtr create( + static StoragePtr createWithOwnCluster( const std::string & name_, /// The name of the table. NamesAndTypesListPtr columns_, /// List of columns. const String & remote_database_, /// database on remote servers. @@ -82,6 +71,7 @@ public: /// the structure of the sub-table is not checked void alter(const AlterCommands & params, const String & database_name, const String & table_name, const Context & context) override; + void startup() override; void shutdown() override; void reshardPartitions( @@ -136,9 +126,6 @@ private: ClusterPtr getCluster() const; - /// Get monotonically increasing string to name files with data to be written to remote servers. - String getMonotonicFileName(); - String name; NamesAndTypesListPtr columns; diff --git a/dbms/src/Storages/StorageFactory.cpp b/dbms/src/Storages/StorageFactory.cpp index 48cfe7dc39a..a45a73ff78d 100644 --- a/dbms/src/Storages/StorageFactory.cpp +++ b/dbms/src/Storages/StorageFactory.cpp @@ -518,7 +518,7 @@ StoragePtr StorageFactory::get( * * db, table - in which table to put data from buffer. * num_buckets - level of parallelism. - * min_time, max_time, min_rows, max_rows, min_bytes, max_bytes - conditions for pushing out from the buffer. + * min_time, max_time, min_rows, max_rows, min_bytes, max_bytes - conditions for flushing the buffer. */ ASTs & args_func = typeid_cast(*typeid_cast(*query).storage).children; @@ -554,7 +554,9 @@ StoragePtr StorageFactory::get( table_name, columns, materialized_columns, alias_columns, column_defaults, context, - num_buckets, {min_time, min_rows, min_bytes}, {max_time, max_rows, max_bytes}, + num_buckets, + StorageBuffer::Thresholds{min_time, min_rows, min_bytes}, + StorageBuffer::Thresholds{max_time, max_rows, max_bytes}, destination_database, destination_table); } else if (name == "TrivialBuffer") @@ -602,7 +604,8 @@ StoragePtr StorageFactory::get( table_name, columns, materialized_columns, alias_columns, column_defaults, context, num_blocks_to_deduplicate, path_in_zk_for_deduplication, - {min_time, min_rows, min_bytes}, {max_time, max_rows, max_bytes}, + StorageTrivialBuffer::Thresholds{min_time, min_rows, min_bytes}, + StorageTrivialBuffer::Thresholds{max_time, max_rows, max_bytes}, destination_database, destination_table); } else if (endsWith(name, "MergeTree")) diff --git a/dbms/src/Storages/StorageFactory.h b/dbms/src/Storages/StorageFactory.h index 9ed7543526a..a26a25f5422 100644 --- a/dbms/src/Storages/StorageFactory.h +++ b/dbms/src/Storages/StorageFactory.h @@ -10,8 +10,9 @@ namespace DB class Context; -/** Allows you to create a table by the name of the engine. +/** Allows you to create a table by the name and parameters of the engine. * In 'columns', 'materialized_columns', etc., Nested data structures must be flattened. + * You should subsequently call IStorage::startup method to work with table. */ class StorageFactory : public Singleton { diff --git a/dbms/src/Storages/StorageJoin.h b/dbms/src/Storages/StorageJoin.h index 0ad21bc2bb3..fa83dbd846f 100644 --- a/dbms/src/Storages/StorageJoin.h +++ b/dbms/src/Storages/StorageJoin.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -20,7 +20,7 @@ using JoinPtr = std::shared_ptr; * * When using, JOIN must be of the appropriate type (ANY|ALL LEFT|INNER ...). */ -class StorageJoin : private ext::shared_ptr_helper, public StorageSetOrJoinBase +class StorageJoin : public ext::shared_ptr_helper, public StorageSetOrJoinBase { friend class ext::shared_ptr_helper; diff --git a/dbms/src/Storages/StorageLog.cpp b/dbms/src/Storages/StorageLog.cpp index b3258b2fd44..764bd5890d4 100644 --- a/dbms/src/Storages/StorageLog.cpp +++ b/dbms/src/Storages/StorageLog.cpp @@ -589,35 +589,6 @@ StorageLog::StorageLog( null_marks_file = Poco::File(path + escapeForFileName(name) + '/' + DBMS_STORAGE_LOG_NULL_MARKS_FILE_NAME); } -StoragePtr StorageLog::create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - size_t max_compress_block_size_) -{ - return make_shared( - path_, name_, columns_, - materialized_columns_, alias_columns_, column_defaults_, - max_compress_block_size_ - ); -} - -StoragePtr StorageLog::create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - size_t max_compress_block_size_) -{ - return make_shared( - path_, name_, columns_, - NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, - max_compress_block_size_ - ); -} - void StorageLog::addFile(const String & column_name, const IDataType & type, size_t level) { diff --git a/dbms/src/Storages/StorageLog.h b/dbms/src/Storages/StorageLog.h index 8909de06caf..912e14d52a8 100644 --- a/dbms/src/Storages/StorageLog.h +++ b/dbms/src/Storages/StorageLog.h @@ -2,7 +2,7 @@ #include -#include +#include #include #include @@ -38,32 +38,13 @@ using Marks = std::vector; * Keys are not supported. * The data is stored in a compressed form. */ -class StorageLog : private ext::shared_ptr_helper, public IStorage +class StorageLog : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class LogBlockInputStream; friend class LogBlockOutputStream; public: - /** hook the table with the appropriate name, along the appropriate path (with / at the end), - * (the correctness of names and paths is not verified) - * consisting of the specified columns; Create files if they do not exist. - */ - static StoragePtr create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - size_t max_compress_block_size_ = DEFAULT_MAX_COMPRESS_BLOCK_SIZE); - - static StoragePtr create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - size_t max_compress_block_size_ = DEFAULT_MAX_COMPRESS_BLOCK_SIZE); - std::string getName() const override { return "Log"; } std::string getTableName() const override { return name; } @@ -102,6 +83,10 @@ protected: Poco::RWLock rwlock; + /** Attach the table with the appropriate name, along the appropriate path (with / at the end), + * (the correctness of names and paths is not verified) + * consisting of the specified columns; Create files if they do not exist. + */ StorageLog( const std::string & path_, const std::string & name_, diff --git a/dbms/src/Storages/StorageMaterializedView.h b/dbms/src/Storages/StorageMaterializedView.h index 818f74c453c..06f8de36574 100644 --- a/dbms/src/Storages/StorageMaterializedView.h +++ b/dbms/src/Storages/StorageMaterializedView.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -8,7 +8,7 @@ namespace DB { -class StorageMaterializedView : private ext::shared_ptr_helper, public StorageView +class StorageMaterializedView : public ext::shared_ptr_helper, public StorageView { friend class ext::shared_ptr_helper; diff --git a/dbms/src/Storages/StorageMemory.cpp b/dbms/src/Storages/StorageMemory.cpp index c5fb386e9eb..faa548f9e8f 100644 --- a/dbms/src/Storages/StorageMemory.cpp +++ b/dbms/src/Storages/StorageMemory.cpp @@ -94,24 +94,6 @@ StorageMemory::StorageMemory( } -StoragePtr StorageMemory::create( - const std::string & name_, - NamesAndTypesListPtr columns_) -{ - return make_shared(name_, columns_); -} - -StoragePtr StorageMemory::create( - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_) -{ - return make_shared(name_, columns_, materialized_columns_, alias_columns_, column_defaults_); -} - - BlockInputStreams StorageMemory::read( const Names & column_names, const ASTPtr & query, diff --git a/dbms/src/Storages/StorageMemory.h b/dbms/src/Storages/StorageMemory.h index e19e677acaa..31e3e2176cd 100644 --- a/dbms/src/Storages/StorageMemory.h +++ b/dbms/src/Storages/StorageMemory.h @@ -2,7 +2,7 @@ #include -#include +#include #include #include @@ -20,24 +20,13 @@ class StorageMemory; * It does not support keys. * Data is stored as a set of blocks and is not stored anywhere else. */ -class StorageMemory : private ext::shared_ptr_helper, public IStorage +class StorageMemory : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class MemoryBlockInputStream; friend class MemoryBlockOutputStream; public: - static StoragePtr create( - const std::string & name_, - NamesAndTypesListPtr columns_); - - static StoragePtr create( - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_); - std::string getName() const override { return "Memory"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/StorageMerge.cpp b/dbms/src/Storages/StorageMerge.cpp index 852f9fe3095..785285b2ded 100644 --- a/dbms/src/Storages/StorageMerge.cpp +++ b/dbms/src/Storages/StorageMerge.cpp @@ -50,35 +50,6 @@ StorageMerge::StorageMerge( { } -StoragePtr StorageMerge::create( - const std::string & name_, - NamesAndTypesListPtr columns_, - const String & source_database_, - const String & table_name_regexp_, - const Context & context_) -{ - return make_shared( - name_, columns_, - source_database_, table_name_regexp_, context_ - ); -} - -StoragePtr StorageMerge::create( - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - const String & source_database_, - const String & table_name_regexp_, - const Context & context_) -{ - return make_shared( - name_, columns_, materialized_columns_, alias_columns_, column_defaults_, - source_database_, table_name_regexp_, context_ - ); -} - NameAndTypePair StorageMerge::getColumn(const String & column_name) const { auto type = VirtualColumnFactory::tryGetType(column_name); diff --git a/dbms/src/Storages/StorageMerge.h b/dbms/src/Storages/StorageMerge.h index 8dfaa3ec6c4..2245e196aea 100644 --- a/dbms/src/Storages/StorageMerge.h +++ b/dbms/src/Storages/StorageMerge.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -12,28 +12,11 @@ namespace DB /** A table that represents the union of an arbitrary number of other tables. * All tables must have the same structure. */ -class StorageMerge : private ext::shared_ptr_helper, public IStorage +class StorageMerge : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create( - const std::string & name_, /// The name of the table. - NamesAndTypesListPtr columns_, /// List of columns. - const String & source_database_, /// In which database to look for source tables. - const String & table_name_regexp_, /// Regex names of source tables. - const Context & context_); /// Known tables. - - static StoragePtr create( - const std::string & name_, /// The name of the table. - NamesAndTypesListPtr columns_, /// List of columns. - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - const String & source_database_, /// In which database to look for source tables. - const String & table_name_regexp_, /// Regex names of source tables. - const Context & context_); /// Known tables. - std::string getName() const override { return "Merge"; } std::string getTableName() const override { return name; } @@ -70,11 +53,11 @@ private: const Context & context; StorageMerge( - const std::string & name_, - NamesAndTypesListPtr columns_, - const String & source_database_, - const String & table_name_regexp_, - const Context & context_); + const std::string & name_, /// The name of the table. + NamesAndTypesListPtr columns_, /// List of columns. + const String & source_database_, /// In which database to look for source tables. + const String & table_name_regexp_, /// Regex names of source tables. + const Context & context_); /// Known tables. StorageMerge( const std::string & name_, diff --git a/dbms/src/Storages/StorageMergeTree.cpp b/dbms/src/Storages/StorageMergeTree.cpp index df047316c70..900b2052a72 100644 --- a/dbms/src/Storages/StorageMergeTree.cpp +++ b/dbms/src/Storages/StorageMergeTree.cpp @@ -58,38 +58,17 @@ StorageMergeTree::StorageMergeTree( data.loadDataParts(has_force_restore_data_flag); data.clearOldParts(); - /// Temporary directories contain unfinalized results of Merges (after forced restart) + /// Temporary directories contain incomplete results of merges (after forced restart) /// and don't allow to reinitialize them, so delete each of them immediately data.clearOldTemporaryDirectories(0); increment.set(data.getMaxDataPartIndex()); } -StoragePtr StorageMergeTree::create( - const String & path_, const String & database_name_, const String & table_name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - bool attach, - Context & context_, - ASTPtr & primary_expr_ast_, - const String & date_column_name_, - const ASTPtr & sampling_expression_, - size_t index_granularity_, - const MergeTreeData::MergingParams & merging_params_, - bool has_force_restore_data_flag_, - const MergeTreeSettings & settings_) -{ - auto res = make_shared( - path_, database_name_, table_name_, - columns_, materialized_columns_, alias_columns_, column_defaults_, attach, - context_, primary_expr_ast_, date_column_name_, - sampling_expression_, index_granularity_, merging_params_, has_force_restore_data_flag_, settings_ - ); - res->merge_task_handle = res->background_pool.addTask(std::bind(&StorageMergeTree::mergeTask, res.get())); - return res; +void StorageMergeTree::startup() +{ + merge_task_handle = background_pool.addTask([this] { return mergeTask(); }); } @@ -346,7 +325,7 @@ bool StorageMergeTree::merge( merger.renameMergedTemporaryPart(merging_tagger->parts, new_part, merged_name, nullptr); - if (std::shared_ptr part_log = context.getPartLog()) + if (auto part_log = context.getPartLog(database_name, table_name)) { PartLogElement elem; elem.event_time = time(0); diff --git a/dbms/src/Storages/StorageMergeTree.h b/dbms/src/Storages/StorageMergeTree.h index dd498ec3165..9093b1c927f 100644 --- a/dbms/src/Storages/StorageMergeTree.h +++ b/dbms/src/Storages/StorageMergeTree.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -16,38 +16,13 @@ namespace DB /** See the description of the data structure in MergeTreeData. */ -class StorageMergeTree : private ext::shared_ptr_helper, public IStorage +class StorageMergeTree : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class MergeTreeBlockOutputStream; public: - /** hook the table with the appropriate name, along the appropriate path (with / at the end), - * (correctness of names and paths are not checked) - * consisting of the specified columns. - * - * primary_expr_ast - expression for sorting; - * date_column_name - the name of the column with the date; - * index_granularity - fow how many rows one index value is written. - */ - static StoragePtr create( - const String & path_, - const String & database_name_, - const String & table_name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - bool attach, - Context & context_, - ASTPtr & primary_expr_ast_, - const String & date_column_name_, - const ASTPtr & sampling_expression_, /// nullptr, if sampling is not supported. - size_t index_granularity_, - const MergeTreeData::MergingParams & merging_params_, - bool has_force_restore_data_flag, - const MergeTreeSettings & settings_); - + void startup() override; void shutdown() override; ~StorageMergeTree() override; @@ -140,6 +115,14 @@ private: friend struct CurrentlyMergingPartsTagger; + /** Attach the table with the appropriate name, along the appropriate path (with / at the end), + * (correctness of names and paths are not checked) + * consisting of the specified columns. + * + * primary_expr_ast - expression for sorting; + * date_column_name - the name of the column with the date; + * index_granularity - fow how many rows one index value is written. + */ StorageMergeTree( const String & path_, const String & database_name_, diff --git a/dbms/src/Storages/StorageNull.h b/dbms/src/Storages/StorageNull.h index 6915aa6e55b..7717cfc07d6 100644 --- a/dbms/src/Storages/StorageNull.h +++ b/dbms/src/Storages/StorageNull.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -14,21 +14,11 @@ namespace DB /** When writing, does nothing. * When reading, returns nothing. */ -class StorageNull : private ext::shared_ptr_helper, public IStorage +class StorageNull : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create( - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_) - { - return make_shared(name_, columns_, materialized_columns_, alias_columns_, column_defaults_); - } - std::string getName() const override { return "Null"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.cpp b/dbms/src/Storages/StorageReplicatedMergeTree.cpp index 33b6e96ec8a..50e9cbc2318 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.cpp +++ b/dbms/src/Storages/StorageReplicatedMergeTree.cpp @@ -40,8 +40,8 @@ #include -#include -#include +#include +#include #include #include @@ -221,8 +221,7 @@ StorageReplicatedMergeTree::StorageReplicatedMergeTree( sampling_expression_, index_granularity_, merging_params_, settings_, database_name_ + "." + table_name, true, attach, [this] (const std::string & name) { enqueuePartForCheck(name); }, - [this] () { clearOldPartsAndRemoveFromZK(); } - ), + [this] () { clearOldPartsAndRemoveFromZK(); }), reader(data), writer(data, context), merger(data, context.getBackgroundPool()), fetcher(data), sharded_partition_uploader_client(*this), shutdown_event(false), part_check_thread(*this), log(&Logger::get(database_name + "." + table_name + " (StorageReplicatedMergeTree)")) @@ -296,16 +295,6 @@ StorageReplicatedMergeTree::StorageReplicatedMergeTree( } createNewZooKeeperNodes(); - - queue.initialize( - zookeeper_path, replica_path, - database_name + "." + table_name + " (ReplicatedMergeTreeQueue)", - data.getDataParts(), current_zookeeper); - - queue.pullLogsToQueue(current_zookeeper, nullptr); - - /// In this thread replica will be activated. - restarting_thread = std::make_unique(*this); } @@ -1180,7 +1169,7 @@ bool StorageReplicatedMergeTree::executeLogEntry(const LogEntry & entry) merger.renameMergedTemporaryPart(parts, part, entry.new_part_name, &transaction); getZooKeeper()->multi(ops); /// After long merge, get fresh ZK handle, because previous session may be expired. - if (std::shared_ptr part_log = context.getPartLog()) + if (auto part_log = context.getPartLog(database_name, table_name)) { PartLogElement elem; elem.event_time = time(0); @@ -2141,7 +2130,7 @@ bool StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin MergeTreeData::Transaction transaction; auto removed_parts = data.renameTempPartAndReplace(part, nullptr, &transaction); - if (std::shared_ptr part_log = context.getPartLog()) + if (auto part_log = context.getPartLog(database_name, table_name)) { PartLogElement elem; elem.event_time = time(0); @@ -2202,6 +2191,23 @@ bool StorageReplicatedMergeTree::fetchPart(const String & part_name, const Strin } +void StorageReplicatedMergeTree::startup() +{ + if (is_readonly) + return; + + queue.initialize( + zookeeper_path, replica_path, + database_name + "." + table_name + " (ReplicatedMergeTreeQueue)", + data.getDataParts(), current_zookeeper); + + queue.pullLogsToQueue(current_zookeeper, nullptr); + + /// In this thread replica will be activated. + restarting_thread = std::make_unique(*this); +} + + void StorageReplicatedMergeTree::shutdown() { /** This must be done before waiting for restarting_thread. diff --git a/dbms/src/Storages/StorageReplicatedMergeTree.h b/dbms/src/Storages/StorageReplicatedMergeTree.h index 1daf0029484..48a37255d25 100644 --- a/dbms/src/Storages/StorageReplicatedMergeTree.h +++ b/dbms/src/Storages/StorageReplicatedMergeTree.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include @@ -69,12 +69,12 @@ namespace DB * as the time will take the time of creation the appropriate part on any of the replicas. */ -class StorageReplicatedMergeTree : private ext::shared_ptr_helper, public IStorage +class StorageReplicatedMergeTree : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - /** If !attach, either creates a new table in ZK, or adds a replica to an existing table. + /** If not 'attach', either creates a new table in ZK, or adds a replica to an existing table. */ static StoragePtr create( const String & zookeeper_path_, @@ -94,6 +94,7 @@ public: bool has_force_restore_data_flag, const MergeTreeSettings & settings_); + void startup() override; void shutdown() override; ~StorageReplicatedMergeTree() override; diff --git a/dbms/src/Storages/StorageSet.h b/dbms/src/Storages/StorageSet.h index f01bacfea07..52fff963484 100644 --- a/dbms/src/Storages/StorageSet.h +++ b/dbms/src/Storages/StorageSet.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -14,7 +14,7 @@ using SetPtr = std::shared_ptr; /** Common part of StorageSet and StorageJoin. */ -class StorageSetOrJoinBase : private ext::shared_ptr_helper, public IStorage +class StorageSetOrJoinBase : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class SetOrJoinBlockOutputStream; @@ -59,7 +59,7 @@ private: * and also written to a file-backup, for recovery after a restart. * Reading from the table is not possible directly - it is possible to specify only the right part of the IN statement. */ -class StorageSet : private ext::shared_ptr_helper, public StorageSetOrJoinBase +class StorageSet : public ext::shared_ptr_helper, public StorageSetOrJoinBase { friend class ext::shared_ptr_helper; diff --git a/dbms/src/Storages/StorageStripeLog.cpp b/dbms/src/Storages/StorageStripeLog.cpp index 0f3a8b83d78..daf9b930f8d 100644 --- a/dbms/src/Storages/StorageStripeLog.cpp +++ b/dbms/src/Storages/StorageStripeLog.cpp @@ -206,23 +206,6 @@ StorageStripeLog::StorageStripeLog( } } -StoragePtr StorageStripeLog::create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - bool attach, - size_t max_compress_block_size_) -{ - return make_shared( - path_, name_, columns_, - materialized_columns_, alias_columns_, column_defaults_, - attach, max_compress_block_size_ - ); -} - void StorageStripeLog::rename(const String & new_path_to_db, const String & new_database_name, const String & new_table_name) { diff --git a/dbms/src/Storages/StorageStripeLog.h b/dbms/src/Storages/StorageStripeLog.h index 9f378250ce3..90eb2dd124c 100644 --- a/dbms/src/Storages/StorageStripeLog.h +++ b/dbms/src/Storages/StorageStripeLog.h @@ -2,7 +2,7 @@ #include -#include +#include #include @@ -17,28 +17,13 @@ namespace DB /** Implements a repository that is suitable for small pieces of the log. * In doing so, stores all the columns in a single Native file, with a nearby index. */ -class StorageStripeLog : private ext::shared_ptr_helper, public IStorage +class StorageStripeLog : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class StripeLogBlockInputStream; friend class StripeLogBlockOutputStream; public: - /** hook the table with the appropriate name, along the appropriate path (with / at the end), - * (the correctness of names and paths is not checked) - * consisting of the specified columns. - * If not specified `attach` - create a directory if it does not exist. - */ - static StoragePtr create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - bool attach, - size_t max_compress_block_size_ = DEFAULT_MAX_COMPRESS_BLOCK_SIZE); - std::string getName() const override { return "StripeLog"; } std::string getTableName() const override { return name; } @@ -87,7 +72,7 @@ private: const NamesAndTypesList & alias_columns_, const ColumnDefaults & column_defaults_, bool attach, - size_t max_compress_block_size_); + size_t max_compress_block_size_ = DEFAULT_MAX_COMPRESS_BLOCK_SIZE); }; } diff --git a/dbms/src/Storages/StorageTinyLog.cpp b/dbms/src/Storages/StorageTinyLog.cpp index 58ca8bee023..8dd5d555ea6 100644 --- a/dbms/src/Storages/StorageTinyLog.cpp +++ b/dbms/src/Storages/StorageTinyLog.cpp @@ -464,24 +464,6 @@ StorageTinyLog::StorageTinyLog( } -StoragePtr StorageTinyLog::create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - bool attach, - size_t max_compress_block_size_) -{ - return make_shared( - path_, name_, columns_, - materialized_columns_, alias_columns_, column_defaults_, - attach, max_compress_block_size_ - ); -} - - void StorageTinyLog::addFile(const String & column_name, const IDataType & type, size_t level) { if (files.end() != files.find(column_name)) diff --git a/dbms/src/Storages/StorageTinyLog.h b/dbms/src/Storages/StorageTinyLog.h index c12d67c6b0a..11b0d210037 100644 --- a/dbms/src/Storages/StorageTinyLog.h +++ b/dbms/src/Storages/StorageTinyLog.h @@ -2,7 +2,7 @@ #include -#include +#include #include @@ -17,28 +17,13 @@ namespace DB /** Implements a repository that is suitable for small pieces of the log. * It differs from StorageLog in the absence of mark files. */ -class StorageTinyLog : private ext::shared_ptr_helper, public IStorage +class StorageTinyLog : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class TinyLogBlockInputStream; friend class TinyLogBlockOutputStream; public: - /** hook the table with the appropriate name, along the appropriate path (with / at the end), - * (the correctness of names and paths is not verified) - * consisting of the specified columns. - * If not specified `attach` - create a directory if it does not exist. - */ - static StoragePtr create( - const std::string & path_, - const std::string & name_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - bool attach, - size_t max_compress_block_size_ = DEFAULT_MAX_COMPRESS_BLOCK_SIZE); - std::string getName() const override { return "TinyLog"; } std::string getTableName() const override { return name; } @@ -90,7 +75,7 @@ private: const NamesAndTypesList & alias_columns_, const ColumnDefaults & column_defaults_, bool attach, - size_t max_compress_block_size_); + size_t max_compress_block_size_ = DEFAULT_MAX_COMPRESS_BLOCK_SIZE); void addFile(const String & column_name, const IDataType & type, size_t level = 0); }; diff --git a/dbms/src/Storages/StorageTrivialBuffer.cpp b/dbms/src/Storages/StorageTrivialBuffer.cpp index f594054e337..df7744f1fdd 100644 --- a/dbms/src/Storages/StorageTrivialBuffer.cpp +++ b/dbms/src/Storages/StorageTrivialBuffer.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include namespace ProfileEvents @@ -43,23 +43,6 @@ namespace ErrorCodes } -StoragePtr StorageTrivialBuffer::create(const std::string & name_, NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - Context & context_, const size_t num_blocks_to_deduplicate_, - const String & path_in_zk_for_deduplication_, - const Thresholds & min_thresholds_, const Thresholds & max_thresholds_, - const String & destination_database_, const String & destination_table_) -{ - return make_shared( - name_, columns_, materialized_columns_, alias_columns_, column_defaults_, - context_, num_blocks_to_deduplicate_, path_in_zk_for_deduplication_, - min_thresholds_, max_thresholds_, - destination_database_, destination_table_); -} - - StorageTrivialBuffer::StorageTrivialBuffer(const std::string & name_, NamesAndTypesListPtr columns_, const NamesAndTypesList & materialized_columns_, const NamesAndTypesList & alias_columns_, @@ -77,8 +60,7 @@ StorageTrivialBuffer::StorageTrivialBuffer(const std::string & name_, NamesAndTy min_thresholds(min_thresholds_), max_thresholds(max_thresholds_), destination_database(destination_database_), destination_table(destination_table_), no_destination(destination_database.empty() && destination_table.empty()), - log(&Logger::get("TrivialBuffer (" + name + ")")), - flush_thread(&StorageTrivialBuffer::flushThread, this) + log(&Logger::get("TrivialBuffer (" + name + ")")) { zookeeper->createAncestors(path_in_zk_for_deduplication); zookeeper->createOrUpdate(path_in_zk_for_deduplication, {}, zkutil::CreateMode::Persistent); @@ -357,6 +339,12 @@ BlockOutputStreamPtr StorageTrivialBuffer::write(const ASTPtr & query, const Set return std::make_shared(*this); } +void StorageTrivialBuffer::startup() +{ + flush_thread = std::thread(&StorageTrivialBuffer::flushThread, this); +} + + void StorageTrivialBuffer::shutdown() { shutdown_event.set(); @@ -421,7 +409,7 @@ bool StorageTrivialBuffer::checkThresholds( } bool StorageTrivialBuffer::checkThresholdsImpl(const size_t rows, const size_t bytes, - const time_t time_passed) const + const time_t time_passed) const { if (time_passed > min_thresholds.time && rows > min_thresholds.rows && bytes > min_thresholds.bytes) { diff --git a/dbms/src/Storages/StorageTrivialBuffer.h b/dbms/src/Storages/StorageTrivialBuffer.h index b2dced13940..c40bf76e48c 100644 --- a/dbms/src/Storages/StorageTrivialBuffer.h +++ b/dbms/src/Storages/StorageTrivialBuffer.h @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include @@ -31,7 +31,7 @@ class Context; * The data in the buffer is not replicated, logged or stored. After hard reset of the * server, the data is lost. */ -class StorageTrivialBuffer : private ext::shared_ptr_helper, public IStorage +class StorageTrivialBuffer : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; friend class TrivialBufferBlockInputStream; @@ -45,15 +45,6 @@ public: size_t bytes; /// Number of bytes (incompressed) in buffer. }; - static StoragePtr create(const std::string & name_, NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_, - Context & context_, size_t num_blocks_to_deduplicate_, - const String & path_in_zk_for_deduplication_, - const Thresholds & min_thresholds_, const Thresholds & max_thresholds_, - const String & destination_database_, const String & destination_table_); - std::string getName() const override { return "TrivialBuffer"; } std::string getTableName() const override { return name; } @@ -74,7 +65,9 @@ public: bool checkThresholdsImpl(const size_t rows, const size_t bytes, const time_t time_passed) const; - /// Writes all the blocks in buffer into the destination table. + /// Start flushing thread. + void startup() override; + /// Writes all the blocks in buffer into the destination table. Stop flushing thread. void shutdown() override; bool optimize(const String & partition, bool final, bool deduplicate, const Settings & settings) override; @@ -89,7 +82,7 @@ public: /// Does not check or alter the structure of dependent table. void alter(const AlterCommands & params, const String & database_name, - const String & table_name, const Context & context) override; + const String & table_name, const Context & context) override; class ZookeeperDeduplicationController { diff --git a/dbms/src/Storages/StorageView.cpp b/dbms/src/Storages/StorageView.cpp index e749c576690..6fcdf3f56a0 100644 --- a/dbms/src/Storages/StorageView.cpp +++ b/dbms/src/Storages/StorageView.cpp @@ -15,23 +15,6 @@ namespace ErrorCodes } -StoragePtr StorageView::create( - const String & table_name_, - const String & database_name_, - Context & context_, - ASTPtr & query_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_) -{ - return make_shared( - table_name_, database_name_, context_, query_, - columns_, materialized_columns_, alias_columns_, column_defaults_ - ); -} - - StorageView::StorageView( const String & table_name_, const String & database_name_, diff --git a/dbms/src/Storages/StorageView.h b/dbms/src/Storages/StorageView.h index cb3416be34e..ea68a3dcea6 100644 --- a/dbms/src/Storages/StorageView.h +++ b/dbms/src/Storages/StorageView.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -9,21 +9,11 @@ namespace DB { -class StorageView : private ext::shared_ptr_helper, public IStorage +class StorageView : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create( - const String & table_name_, - const String & database_name_, - Context & context_, - ASTPtr & query_, - NamesAndTypesListPtr columns_, - const NamesAndTypesList & materialized_columns_, - const NamesAndTypesList & alias_columns_, - const ColumnDefaults & column_defaults_); - std::string getName() const override { return "View"; } std::string getTableName() const override { return table_name; } const NamesAndTypesList & getColumnsListImpl() const override { return *columns; } diff --git a/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.cpp b/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.cpp index e79102562c2..bd6040a8958 100644 --- a/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.cpp +++ b/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.cpp @@ -23,11 +23,6 @@ StorageSystemAsynchronousMetrics::StorageSystemAsynchronousMetrics(const std::st { } -StoragePtr StorageSystemAsynchronousMetrics::create(const std::string & name_, const AsynchronousMetrics & async_metrics_) -{ - return make_shared(name_, async_metrics_); -} - BlockInputStreams StorageSystemAsynchronousMetrics::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.h b/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.h index 8497d31a917..af42c360619 100644 --- a/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.h +++ b/dbms/src/Storages/System/StorageSystemAsynchronousMetrics.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -13,13 +13,11 @@ class Context; /** Implements system table asynchronous_metrics, which allows to get values of periodically (asynchronously) updated metrics. */ -class StorageSystemAsynchronousMetrics : private ext::shared_ptr_helper, public IStorage +class StorageSystemAsynchronousMetrics : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create(const std::string & name_, const AsynchronousMetrics & async_metrics_); - std::string getName() const override { return "SystemAsynchronousMetrics"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemBuildOptions.cpp b/dbms/src/Storages/System/StorageSystemBuildOptions.cpp index d64adab88e1..43a2f7b11e9 100644 --- a/dbms/src/Storages/System/StorageSystemBuildOptions.cpp +++ b/dbms/src/Storages/System/StorageSystemBuildOptions.cpp @@ -19,11 +19,6 @@ StorageSystemBuildOptions::StorageSystemBuildOptions(const std::string & name_) { } -StoragePtr StorageSystemBuildOptions::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemBuildOptions::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemBuildOptions.h b/dbms/src/Storages/System/StorageSystemBuildOptions.h index 2ca8885c0db..13883b76791 100644 --- a/dbms/src/Storages/System/StorageSystemBuildOptions.h +++ b/dbms/src/Storages/System/StorageSystemBuildOptions.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,11 @@ class Context; /** System table "build_options" with many params used for clickhouse building */ -class StorageSystemBuildOptions : private ext::shared_ptr_helper, public IStorage +class StorageSystemBuildOptions : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemBuildOptions"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemClusters.cpp b/dbms/src/Storages/System/StorageSystemClusters.cpp index 9c82be234fd..fcc2ee6052b 100644 --- a/dbms/src/Storages/System/StorageSystemClusters.cpp +++ b/dbms/src/Storages/System/StorageSystemClusters.cpp @@ -29,10 +29,6 @@ StorageSystemClusters::StorageSystemClusters(const std::string & name_, Context { } -StoragePtr StorageSystemClusters::create(const std::string & name_, Context & context_) -{ - return make_shared(name_, context_); -} BlockInputStreams StorageSystemClusters::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemClusters.h b/dbms/src/Storages/System/StorageSystemClusters.h index 49efd8cc0ff..6071e6907e6 100644 --- a/dbms/src/Storages/System/StorageSystemClusters.h +++ b/dbms/src/Storages/System/StorageSystemClusters.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -13,13 +13,12 @@ class Context; * that allows to obtain information about available clusters * (which may be specified in Distributed tables). */ -class StorageSystemClusters : private ext::shared_ptr_helper, public IStorage +class StorageSystemClusters : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: StorageSystemClusters(const std::string & name_, Context & context_); - static StoragePtr create(const std::string & name_, Context & context_); std::string getName() const override { return "SystemClusters"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemColumns.cpp b/dbms/src/Storages/System/StorageSystemColumns.cpp index 5736c3b14f5..eacbddd761a 100644 --- a/dbms/src/Storages/System/StorageSystemColumns.cpp +++ b/dbms/src/Storages/System/StorageSystemColumns.cpp @@ -31,10 +31,6 @@ StorageSystemColumns::StorageSystemColumns(const std::string & name_) { } -StoragePtr StorageSystemColumns::create(const std::string & name_) -{ - return make_shared(name_); -} BlockInputStreams StorageSystemColumns::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemColumns.h b/dbms/src/Storages/System/StorageSystemColumns.h index fa81798ea95..dc7f5c23726 100644 --- a/dbms/src/Storages/System/StorageSystemColumns.h +++ b/dbms/src/Storages/System/StorageSystemColumns.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -11,12 +11,10 @@ class Context; /** Implements system table 'columns', that allows to get information about columns for every table. */ -class StorageSystemColumns : private ext::shared_ptr_helper, public IStorage +class StorageSystemColumns : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemColumns"; } std::string getTableName() const override { return name; } const NamesAndTypesList & getColumnsListImpl() const override { return columns; } diff --git a/dbms/src/Storages/System/StorageSystemDatabases.cpp b/dbms/src/Storages/System/StorageSystemDatabases.cpp index c47850d2376..fd2c8f0a2e1 100644 --- a/dbms/src/Storages/System/StorageSystemDatabases.cpp +++ b/dbms/src/Storages/System/StorageSystemDatabases.cpp @@ -20,11 +20,6 @@ StorageSystemDatabases::StorageSystemDatabases(const std::string & name_) { } -StoragePtr StorageSystemDatabases::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemDatabases::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemDatabases.h b/dbms/src/Storages/System/StorageSystemDatabases.h index 0ebd8124cda..be233aa4838 100644 --- a/dbms/src/Storages/System/StorageSystemDatabases.h +++ b/dbms/src/Storages/System/StorageSystemDatabases.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements `databases` system table, which allows you to get information about all databases. */ -class StorageSystemDatabases : private ext::shared_ptr_helper, public IStorage +class StorageSystemDatabases : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemDatabases"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemDictionaries.cpp b/dbms/src/Storages/System/StorageSystemDictionaries.cpp index 042c412b006..280728d21f0 100644 --- a/dbms/src/Storages/System/StorageSystemDictionaries.cpp +++ b/dbms/src/Storages/System/StorageSystemDictionaries.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include namespace DB @@ -39,10 +39,6 @@ StorageSystemDictionaries::StorageSystemDictionaries(const std::string & name) { } -StoragePtr StorageSystemDictionaries::create(const std::string & name) -{ - return make_shared(name); -} BlockInputStreams StorageSystemDictionaries::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemDictionaries.h b/dbms/src/Storages/System/StorageSystemDictionaries.h index 2b8f6d63d23..87063398556 100644 --- a/dbms/src/Storages/System/StorageSystemDictionaries.h +++ b/dbms/src/Storages/System/StorageSystemDictionaries.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -10,13 +10,10 @@ namespace DB class Context; -class StorageSystemDictionaries : private ext::shared_ptr_helper, public IStorage +class StorageSystemDictionaries : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name); - std::string getName() const override { return "SystemDictionaries"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemEvents.cpp b/dbms/src/Storages/System/StorageSystemEvents.cpp index 6ff7db542b4..bd23cde46ee 100644 --- a/dbms/src/Storages/System/StorageSystemEvents.cpp +++ b/dbms/src/Storages/System/StorageSystemEvents.cpp @@ -20,11 +20,6 @@ StorageSystemEvents::StorageSystemEvents(const std::string & name_) { } -StoragePtr StorageSystemEvents::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemEvents::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemEvents.h b/dbms/src/Storages/System/StorageSystemEvents.h index de4edcfb96b..b9473b0f1d0 100644 --- a/dbms/src/Storages/System/StorageSystemEvents.h +++ b/dbms/src/Storages/System/StorageSystemEvents.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements `events` system table, which allows you to obtain information for profiling. */ -class StorageSystemEvents : private ext::shared_ptr_helper, public IStorage +class StorageSystemEvents : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemEvents"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemFunctions.cpp b/dbms/src/Storages/System/StorageSystemFunctions.cpp index 4abdb4e1ac6..97820603420 100644 --- a/dbms/src/Storages/System/StorageSystemFunctions.cpp +++ b/dbms/src/Storages/System/StorageSystemFunctions.cpp @@ -22,10 +22,6 @@ StorageSystemFunctions::StorageSystemFunctions(const std::string & name_) { } -StoragePtr StorageSystemFunctions::create(const std::string & name_) -{ - return make_shared(name_); -} BlockInputStreams StorageSystemFunctions::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemFunctions.h b/dbms/src/Storages/System/StorageSystemFunctions.h index d08ab07a2f1..14c1eec60c4 100644 --- a/dbms/src/Storages/System/StorageSystemFunctions.h +++ b/dbms/src/Storages/System/StorageSystemFunctions.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -13,13 +13,10 @@ class Context; /** Implements `functions`system table, which allows you to get a list * all normal and aggregate functions. */ -class StorageSystemFunctions : private ext::shared_ptr_helper, public IStorage +class StorageSystemFunctions : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemFunctions"; } std::string getTableName() const override { return name; } const NamesAndTypesList & getColumnsListImpl() const override { return columns; } diff --git a/dbms/src/Storages/System/StorageSystemGraphite.cpp b/dbms/src/Storages/System/StorageSystemGraphite.cpp index b4c7afa780f..0a9f8052f00 100644 --- a/dbms/src/Storages/System/StorageSystemGraphite.cpp +++ b/dbms/src/Storages/System/StorageSystemGraphite.cpp @@ -124,10 +124,6 @@ StorageSystemGraphite::StorageSystemGraphite(const std::string & name_) { } -StoragePtr StorageSystemGraphite::create(const std::string & name_) -{ - return make_shared(name_); -} BlockInputStreams StorageSystemGraphite::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemGraphite.h b/dbms/src/Storages/System/StorageSystemGraphite.h index a3c9a267a6f..7b1668d1e3a 100644 --- a/dbms/src/Storages/System/StorageSystemGraphite.h +++ b/dbms/src/Storages/System/StorageSystemGraphite.h @@ -1,21 +1,16 @@ #pragma once #include -#include +#include namespace DB { -/// Provides information about graphite configuration. -class StorageSystemGraphite - : private ext::shared_ptr_helper - , public IStorage +/// Provides information about Graphite configuration. +class StorageSystemGraphite : public ext::shared_ptr_helper, public IStorage { - friend class ext::shared_ptr_helper; - +friend class ext::shared_ptr_helper; public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemGraphite"; } std::string getTableName() const override { return name; } const NamesAndTypesList & getColumnsListImpl() const override { return columns; } diff --git a/dbms/src/Storages/System/StorageSystemMerges.cpp b/dbms/src/Storages/System/StorageSystemMerges.cpp index 881a4db210f..9cd80cb682a 100644 --- a/dbms/src/Storages/System/StorageSystemMerges.cpp +++ b/dbms/src/Storages/System/StorageSystemMerges.cpp @@ -34,10 +34,6 @@ StorageSystemMerges::StorageSystemMerges(const std::string & name) { } -StoragePtr StorageSystemMerges::create(const std::string & name) -{ - return make_shared(name); -} BlockInputStreams StorageSystemMerges::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemMerges.h b/dbms/src/Storages/System/StorageSystemMerges.h index e1bbbe7e97c..28ebaca5686 100644 --- a/dbms/src/Storages/System/StorageSystemMerges.h +++ b/dbms/src/Storages/System/StorageSystemMerges.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -10,13 +10,10 @@ namespace DB class Context; -class StorageSystemMerges : private ext::shared_ptr_helper, public IStorage +class StorageSystemMerges : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name); - std::string getName() const override { return "SystemMerges"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemMetrics.cpp b/dbms/src/Storages/System/StorageSystemMetrics.cpp index 568ee9af5bd..91527f71194 100644 --- a/dbms/src/Storages/System/StorageSystemMetrics.cpp +++ b/dbms/src/Storages/System/StorageSystemMetrics.cpp @@ -21,11 +21,6 @@ StorageSystemMetrics::StorageSystemMetrics(const std::string & name_) { } -StoragePtr StorageSystemMetrics::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemMetrics::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemMetrics.h b/dbms/src/Storages/System/StorageSystemMetrics.h index e4a5043c4bc..286bd9071b8 100644 --- a/dbms/src/Storages/System/StorageSystemMetrics.h +++ b/dbms/src/Storages/System/StorageSystemMetrics.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -11,14 +11,11 @@ class Context; /** Implements `metrics` system table, which provides information about the operation of the server. - */ -class StorageSystemMetrics : private ext::shared_ptr_helper, public IStorage + */ +class StorageSystemMetrics : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemMetrics"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemNumbers.cpp b/dbms/src/Storages/System/StorageSystemNumbers.cpp index e6fcc8089a9..7c2b7cf64e5 100644 --- a/dbms/src/Storages/System/StorageSystemNumbers.cpp +++ b/dbms/src/Storages/System/StorageSystemNumbers.cpp @@ -53,11 +53,6 @@ StorageSystemNumbers::StorageSystemNumbers(const std::string & name_, bool multi { } -StoragePtr StorageSystemNumbers::create(const std::string & name_, bool multithreaded_) -{ - return make_shared(name_, multithreaded_); -} - BlockInputStreams StorageSystemNumbers::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemNumbers.h b/dbms/src/Storages/System/StorageSystemNumbers.h index da8df2ab398..ad7ceadb292 100644 --- a/dbms/src/Storages/System/StorageSystemNumbers.h +++ b/dbms/src/Storages/System/StorageSystemNumbers.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -14,13 +14,10 @@ class Context; * The table contains the only column number UInt64. * From this table, you can read all natural numbers, starting from 0 (to 2^64 - 1, and then again). */ -class StorageSystemNumbers : private ext::shared_ptr_helper, public IStorage +class StorageSystemNumbers : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_, bool multithreaded_ = false); - std::string getName() const override { return "SystemNumbers"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemOne.cpp b/dbms/src/Storages/System/StorageSystemOne.cpp index d14e3502b9d..cd0e5fcda84 100644 --- a/dbms/src/Storages/System/StorageSystemOne.cpp +++ b/dbms/src/Storages/System/StorageSystemOne.cpp @@ -15,11 +15,6 @@ StorageSystemOne::StorageSystemOne(const std::string & name_) { } -StoragePtr StorageSystemOne::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemOne::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemOne.h b/dbms/src/Storages/System/StorageSystemOne.h index 2eda7af0aad..7f714e5764d 100644 --- a/dbms/src/Storages/System/StorageSystemOne.h +++ b/dbms/src/Storages/System/StorageSystemOne.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -15,13 +15,10 @@ class Context; * Used when the table is not specified in the query. * Analog of the DUAL table in Oracle and MySQL. */ -class StorageSystemOne : private ext::shared_ptr_helper, public IStorage +class StorageSystemOne : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemOne"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemParts.cpp b/dbms/src/Storages/System/StorageSystemParts.cpp index 253c815eedd..e56f60c7380 100644 --- a/dbms/src/Storages/System/StorageSystemParts.cpp +++ b/dbms/src/Storages/System/StorageSystemParts.cpp @@ -44,11 +44,6 @@ StorageSystemParts::StorageSystemParts(const std::string & name_) { } -StoragePtr StorageSystemParts::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemParts::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemParts.h b/dbms/src/Storages/System/StorageSystemParts.h index f48722cd89c..22bcfab456a 100644 --- a/dbms/src/Storages/System/StorageSystemParts.h +++ b/dbms/src/Storages/System/StorageSystemParts.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,12 +12,10 @@ class Context; /** Implements system table 'parts' which allows to get information about data parts for tables of MergeTree family. */ -class StorageSystemParts : private ext::shared_ptr_helper, public IStorage +class StorageSystemParts : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemParts"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemProcesses.cpp b/dbms/src/Storages/System/StorageSystemProcesses.cpp index 09aa4dc53b2..4a43d9adcf1 100644 --- a/dbms/src/Storages/System/StorageSystemProcesses.cpp +++ b/dbms/src/Storages/System/StorageSystemProcesses.cpp @@ -52,11 +52,6 @@ StorageSystemProcesses::StorageSystemProcesses(const std::string & name_) { } -StoragePtr StorageSystemProcesses::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemProcesses::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemProcesses.h b/dbms/src/Storages/System/StorageSystemProcesses.h index 1ed56a50521..f3ca99590c0 100644 --- a/dbms/src/Storages/System/StorageSystemProcesses.h +++ b/dbms/src/Storages/System/StorageSystemProcesses.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements `processes` system table, which allows you to get information about the queries that are currently executing. */ -class StorageSystemProcesses : private ext::shared_ptr_helper, public IStorage +class StorageSystemProcesses : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemProcesses"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemReplicas.cpp b/dbms/src/Storages/System/StorageSystemReplicas.cpp index 17d33d54269..33ce5b1a21f 100644 --- a/dbms/src/Storages/System/StorageSystemReplicas.cpp +++ b/dbms/src/Storages/System/StorageSystemReplicas.cpp @@ -46,11 +46,6 @@ StorageSystemReplicas::StorageSystemReplicas(const std::string & name_) { } -StoragePtr StorageSystemReplicas::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemReplicas::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemReplicas.h b/dbms/src/Storages/System/StorageSystemReplicas.h index 1f21790fc58..365556b0ad5 100644 --- a/dbms/src/Storages/System/StorageSystemReplicas.h +++ b/dbms/src/Storages/System/StorageSystemReplicas.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements `replicas` system table, which provides information about the status of the replicated tables. */ -class StorageSystemReplicas : private ext::shared_ptr_helper, public IStorage +class StorageSystemReplicas : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemReplicas"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemReplicationQueue.cpp b/dbms/src/Storages/System/StorageSystemReplicationQueue.cpp index fa65d1046be..898272cc4e0 100644 --- a/dbms/src/Storages/System/StorageSystemReplicationQueue.cpp +++ b/dbms/src/Storages/System/StorageSystemReplicationQueue.cpp @@ -46,11 +46,6 @@ StorageSystemReplicationQueue::StorageSystemReplicationQueue(const std::string & { } -StoragePtr StorageSystemReplicationQueue::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemReplicationQueue::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemReplicationQueue.h b/dbms/src/Storages/System/StorageSystemReplicationQueue.h index f4f60fc6e44..c884d2b637b 100644 --- a/dbms/src/Storages/System/StorageSystemReplicationQueue.h +++ b/dbms/src/Storages/System/StorageSystemReplicationQueue.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements the `replication_queue` system table, which allows you to view the replication queues for the replicated tables. */ -class StorageSystemReplicationQueue : private ext::shared_ptr_helper, public IStorage +class StorageSystemReplicationQueue : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemReplicationQueue"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemSettings.cpp b/dbms/src/Storages/System/StorageSystemSettings.cpp index 9952a2711d7..8e3c1c630cc 100644 --- a/dbms/src/Storages/System/StorageSystemSettings.cpp +++ b/dbms/src/Storages/System/StorageSystemSettings.cpp @@ -21,11 +21,6 @@ StorageSystemSettings::StorageSystemSettings(const std::string & name_) { } -StoragePtr StorageSystemSettings::create(const std::string & name_) -{ - return make_shared(name_); -} - BlockInputStreams StorageSystemSettings::read( const Names & column_names, diff --git a/dbms/src/Storages/System/StorageSystemSettings.h b/dbms/src/Storages/System/StorageSystemSettings.h index a17f81fe9d0..eafc0486053 100644 --- a/dbms/src/Storages/System/StorageSystemSettings.h +++ b/dbms/src/Storages/System/StorageSystemSettings.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** implements system table "settings", which allows to get information about the current settings. */ -class StorageSystemSettings : private ext::shared_ptr_helper, public IStorage +class StorageSystemSettings : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemSettings"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemTables.cpp b/dbms/src/Storages/System/StorageSystemTables.cpp index 711b59a1c89..cce9d5641af 100644 --- a/dbms/src/Storages/System/StorageSystemTables.cpp +++ b/dbms/src/Storages/System/StorageSystemTables.cpp @@ -30,11 +30,6 @@ StorageSystemTables::StorageSystemTables(const std::string & name_) { } -StoragePtr StorageSystemTables::create(const std::string & name_) -{ - return make_shared(name_); -} - static ColumnWithTypeAndName getFilteredDatabases(const ASTPtr & query, const Context & context) { diff --git a/dbms/src/Storages/System/StorageSystemTables.h b/dbms/src/Storages/System/StorageSystemTables.h index 7c40a03d003..61e2eda493c 100644 --- a/dbms/src/Storages/System/StorageSystemTables.h +++ b/dbms/src/Storages/System/StorageSystemTables.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements the system table `tables`, which allows you to get information about all tables. */ -class StorageSystemTables : private ext::shared_ptr_helper, public IStorage +class StorageSystemTables : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemTables"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/StorageSystemZooKeeper.cpp b/dbms/src/Storages/System/StorageSystemZooKeeper.cpp index d21d4c68bd3..67c391c2ca6 100644 --- a/dbms/src/Storages/System/StorageSystemZooKeeper.cpp +++ b/dbms/src/Storages/System/StorageSystemZooKeeper.cpp @@ -21,29 +21,24 @@ namespace DB StorageSystemZooKeeper::StorageSystemZooKeeper(const std::string & name_) : name(name_) , columns{ - { "name", std::make_shared() }, - { "value", std::make_shared() }, - { "czxid", std::make_shared() }, - { "mzxid", std::make_shared() }, - { "ctime", std::make_shared()}, - { "mtime", std::make_shared()}, - { "version", std::make_shared() }, - { "cversion", std::make_shared() }, - { "aversion", std::make_shared() }, - { "ephemeralOwner", std::make_shared() }, - { "dataLength", std::make_shared() }, - { "numChildren", std::make_shared() }, - { "pzxid", std::make_shared() }, - { "path", std::make_shared() }, + { "name", std::make_shared() }, + { "value", std::make_shared() }, + { "czxid", std::make_shared() }, + { "mzxid", std::make_shared() }, + { "ctime", std::make_shared() }, + { "mtime", std::make_shared() }, + { "version", std::make_shared() }, + { "cversion", std::make_shared() }, + { "aversion", std::make_shared() }, + { "ephemeralOwner", std::make_shared() }, + { "dataLength", std::make_shared() }, + { "numChildren", std::make_shared() }, + { "pzxid", std::make_shared() }, + { "path", std::make_shared() }, } { } -StoragePtr StorageSystemZooKeeper::create(const std::string & name_) -{ - return make_shared(name_); -} - static bool extractPathImpl(const IAST & elem, String & res) { diff --git a/dbms/src/Storages/System/StorageSystemZooKeeper.h b/dbms/src/Storages/System/StorageSystemZooKeeper.h index cd51f11fe67..b9062521f86 100644 --- a/dbms/src/Storages/System/StorageSystemZooKeeper.h +++ b/dbms/src/Storages/System/StorageSystemZooKeeper.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include @@ -12,13 +12,10 @@ class Context; /** Implements `zookeeper` system table, which allows you to view the data in ZooKeeper for debugging purposes. */ -class StorageSystemZooKeeper : private ext::shared_ptr_helper, public IStorage +class StorageSystemZooKeeper : public ext::shared_ptr_helper, public IStorage { friend class ext::shared_ptr_helper; - public: - static StoragePtr create(const std::string & name_); - std::string getName() const override { return "SystemZooKeeper"; } std::string getTableName() const override { return name; } diff --git a/dbms/src/Storages/System/attachSystemTables.cpp b/dbms/src/Storages/System/attachSystemTables.cpp index 8a2e980c04b..7cebab4400f 100644 --- a/dbms/src/Storages/System/attachSystemTables.cpp +++ b/dbms/src/Storages/System/attachSystemTables.cpp @@ -26,7 +26,7 @@ namespace DB void attachSystemTablesLocal(DatabasePtr system_database) { system_database->attachTable("one", StorageSystemOne::create("one")); - system_database->attachTable("numbers", StorageSystemNumbers::create("numbers")); + system_database->attachTable("numbers", StorageSystemNumbers::create("numbers", false)); system_database->attachTable("numbers_mt", StorageSystemNumbers::create("numbers_mt", true)); system_database->attachTable("databases", StorageSystemDatabases::create("databases")); system_database->attachTable("tables", StorageSystemTables::create("tables")); diff --git a/dbms/src/Storages/tests/hit_log.cpp b/dbms/src/Storages/tests/hit_log.cpp index 66aa0311a31..7c172c6c2d2 100644 --- a/dbms/src/Storages/tests/hit_log.cpp +++ b/dbms/src/Storages/tests/hit_log.cpp @@ -29,62 +29,62 @@ try { NamesAndTypesList names_and_types_list { - {"WatchID", std::make_shared()}, - {"JavaEnable", std::make_shared()}, - {"Title", std::make_shared()}, - {"EventTime", std::make_shared()}, - {"CounterID", std::make_shared()}, - {"ClientIP", std::make_shared()}, - {"RegionID", std::make_shared()}, - {"UniqID", std::make_shared()}, - {"CounterClass", std::make_shared()}, - {"OS", std::make_shared()}, - {"UserAgent", std::make_shared()}, - {"URL", std::make_shared()}, - {"Referer", std::make_shared()}, - {"ResolutionWidth", std::make_shared()}, - {"ResolutionHeight", std::make_shared()}, - {"ResolutionDepth", std::make_shared()}, - {"FlashMajor", std::make_shared()}, - {"FlashMinor", std::make_shared()}, - {"FlashMinor2", std::make_shared()}, - {"NetMajor", std::make_shared()}, - {"NetMinor", std::make_shared()}, - {"UserAgentMajor", std::make_shared()}, - {"UserAgentMinor", std::make_shared(2)}, - {"CookieEnable", std::make_shared()}, - {"JavascriptEnable", std::make_shared()}, - {"IsMobile", std::make_shared()}, - {"MobilePhone", std::make_shared()}, - {"MobilePhoneModel", std::make_shared()}, - {"Params", std::make_shared()}, - {"IPNetworkID", std::make_shared()}, - {"TraficSourceID", std::make_shared()}, - {"SearchEngineID", std::make_shared()}, - {"SearchPhrase", std::make_shared()}, - {"AdvEngineID", std::make_shared()}, - {"IsArtifical", std::make_shared()}, - {"WindowClientWidth", std::make_shared()}, - {"WindowClientHeight", std::make_shared()}, - {"ClientTimeZone", std::make_shared()}, - {"ClientEventTime", std::make_shared()}, - {"SilverlightVersion1", std::make_shared()}, - {"SilverlightVersion2", std::make_shared()}, - {"SilverlightVersion3", std::make_shared()}, - {"SilverlightVersion4", std::make_shared()}, - {"PageCharset", std::make_shared()}, - {"CodeVersion", std::make_shared()}, - {"IsLink", std::make_shared()}, - {"IsDownload", std::make_shared()}, - {"IsNotBounce", std::make_shared()}, - {"FUniqID", std::make_shared()}, - {"OriginalURL", std::make_shared()}, - {"HID", std::make_shared()}, - {"IsOldCounter", std::make_shared()}, - {"IsEvent", std::make_shared()}, - {"IsParameter", std::make_shared()}, - {"DontCountHits", std::make_shared()}, - {"WithHash", std::make_shared()}, + {"WatchID", std::make_shared()}, + {"JavaEnable", std::make_shared()}, + {"Title", std::make_shared()}, + {"EventTime", std::make_shared()}, + {"CounterID", std::make_shared()}, + {"ClientIP", std::make_shared()}, + {"RegionID", std::make_shared()}, + {"UniqID", std::make_shared()}, + {"CounterClass", std::make_shared()}, + {"OS", std::make_shared()}, + {"UserAgent", std::make_shared()}, + {"URL", std::make_shared()}, + {"Referer", std::make_shared()}, + {"ResolutionWidth", std::make_shared()}, + {"ResolutionHeight", std::make_shared()}, + {"ResolutionDepth", std::make_shared()}, + {"FlashMajor", std::make_shared()}, + {"FlashMinor", std::make_shared()}, + {"FlashMinor2", std::make_shared()}, + {"NetMajor", std::make_shared()}, + {"NetMinor", std::make_shared()}, + {"UserAgentMajor", std::make_shared()}, + {"UserAgentMinor", std::make_shared(2)}, + {"CookieEnable", std::make_shared()}, + {"JavascriptEnable", std::make_shared()}, + {"IsMobile", std::make_shared()}, + {"MobilePhone", std::make_shared()}, + {"MobilePhoneModel", std::make_shared()}, + {"Params", std::make_shared()}, + {"IPNetworkID", std::make_shared()}, + {"TraficSourceID", std::make_shared()}, + {"SearchEngineID", std::make_shared()}, + {"SearchPhrase", std::make_shared()}, + {"AdvEngineID", std::make_shared()}, + {"IsArtifical", std::make_shared()}, + {"WindowClientWidth", std::make_shared()}, + {"WindowClientHeight", std::make_shared()}, + {"ClientTimeZone", std::make_shared()}, + {"ClientEventTime", std::make_shared()}, + {"SilverlightVersion1", std::make_shared()}, + {"SilverlightVersion2", std::make_shared()}, + {"SilverlightVersion3", std::make_shared()}, + {"SilverlightVersion4", std::make_shared()}, + {"PageCharset", std::make_shared()}, + {"CodeVersion", std::make_shared()}, + {"IsLink", std::make_shared()}, + {"IsDownload", std::make_shared()}, + {"IsNotBounce", std::make_shared()}, + {"FUniqID", std::make_shared()}, + {"OriginalURL", std::make_shared()}, + {"HID", std::make_shared()}, + {"IsOldCounter", std::make_shared()}, + {"IsEvent", std::make_shared()}, + {"IsParameter", std::make_shared()}, + {"DontCountHits", std::make_shared()}, + {"WithHash", std::make_shared()}, }; DataTypes data_types; @@ -98,7 +98,9 @@ try /// create a hit log table - StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list)); + StoragePtr table = StorageLog::create("./", "HitLog", std::make_shared(names_and_types_list), + NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, DEFAULT_MAX_COMPRESS_BLOCK_SIZE); + table->startup(); /// create a description of how to read data from the tab separated dump diff --git a/dbms/src/Storages/tests/merge_tree.cpp b/dbms/src/Storages/tests/merge_tree.cpp index ba86abf1695..6bceb9eb94d 100644 --- a/dbms/src/Storages/tests/merge_tree.cpp +++ b/dbms/src/Storages/tests/merge_tree.cpp @@ -45,9 +45,10 @@ try StoragePtr table = StorageMergeTree::create( "./", "default", "test", - names_and_types, {}, {}, ColumnDefaults{}, false, + names_and_types, NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, false, context, primary_expr, "d", - nullptr, 101, params, false, {}); + ASTPtr{}, 101, params, false, MergeTreeSettings{}); + table->startup(); /// write into it { diff --git a/dbms/src/Storages/tests/storage_log.cpp b/dbms/src/Storages/tests/storage_log.cpp index 08fd0838f12..56c86ee1fec 100644 --- a/dbms/src/Storages/tests/storage_log.cpp +++ b/dbms/src/Storages/tests/storage_log.cpp @@ -24,7 +24,9 @@ try names_and_types->push_back(NameAndTypePair("a", std::make_shared())); names_and_types->push_back(NameAndTypePair("b", std::make_shared())); - StoragePtr table = StorageLog::create("./", "test", names_and_types); + StoragePtr table = StorageLog::create("./", "test", names_and_types, + NamesAndTypesList{}, NamesAndTypesList{}, ColumnDefaults{}, DEFAULT_MAX_COMPRESS_BLOCK_SIZE); + table->startup(); /// write into it { diff --git a/dbms/src/Storages/tests/system_numbers.cpp b/dbms/src/Storages/tests/system_numbers.cpp index fdb10441c7d..a6b2851b81f 100644 --- a/dbms/src/Storages/tests/system_numbers.cpp +++ b/dbms/src/Storages/tests/system_numbers.cpp @@ -15,7 +15,7 @@ try { using namespace DB; - StoragePtr table = StorageSystemNumbers::create("Numbers"); + StoragePtr table = StorageSystemNumbers::create("numbers", false); Names column_names; column_names.push_back("number"); diff --git a/dbms/src/TableFunctions/TableFunctionMerge.cpp b/dbms/src/TableFunctions/TableFunctionMerge.cpp index dcda825131f..221543d370e 100644 --- a/dbms/src/TableFunctions/TableFunctionMerge.cpp +++ b/dbms/src/TableFunctions/TableFunctionMerge.cpp @@ -75,12 +75,14 @@ StoragePtr TableFunctionMerge::execute(const ASTPtr & ast_function, const Contex String source_database = static_cast(*args[0]).value.safeGet(); String table_name_regexp = static_cast(*args[1]).value.safeGet(); - return StorageMerge::create( + auto res = StorageMerge::create( getName(), std::make_shared(chooseColumns(source_database, table_name_regexp, context)), source_database, table_name_regexp, context); + res->startup(); + return res; } } diff --git a/dbms/src/TableFunctions/TableFunctionRemote.cpp b/dbms/src/TableFunctions/TableFunctionRemote.cpp index 13796f64622..d12f2a27521 100644 --- a/dbms/src/TableFunctions/TableFunctionRemote.cpp +++ b/dbms/src/TableFunctions/TableFunctionRemote.cpp @@ -274,13 +274,15 @@ StoragePtr TableFunctionRemote::execute(const ASTPtr & ast_function, const Conte auto cluster = std::make_shared(context.getSettings(), names, username, password); - return StorageDistributed::create( + auto res = StorageDistributed::createWithOwnCluster( getName(), std::make_shared(getStructureOfRemoteTable(*cluster, remote_database, remote_table, context)), remote_database, remote_table, cluster, context); + res->startup(); + return res; } } diff --git a/dbms/src/TableFunctions/TableFunctionShardByHash.cpp b/dbms/src/TableFunctions/TableFunctionShardByHash.cpp index bd5f90c7930..f773b8f5bcb 100644 --- a/dbms/src/TableFunctions/TableFunctionShardByHash.cpp +++ b/dbms/src/TableFunctions/TableFunctionShardByHash.cpp @@ -71,13 +71,15 @@ StoragePtr TableFunctionShardByHash::execute(const ASTPtr & ast_function, const std::shared_ptr shard(cluster->getClusterWithSingleShard(shard_index).release()); - return StorageDistributed::create( + auto res = StorageDistributed::createWithOwnCluster( getName(), std::make_shared(getStructureOfRemoteTable(*shard, remote_database, remote_table, context)), remote_database, remote_table, shard, context); + res->startup(); + return res; } } diff --git a/dbms/tests/queries/0_stateless/00079_defaulted_columns.reference b/dbms/tests/queries/0_stateless/00079_defaulted_columns.reference index 78f03303623..732837d6557 100644 --- a/dbms/tests/queries/0_stateless/00079_defaulted_columns.reference +++ b/dbms/tests/queries/0_stateless/00079_defaulted_columns.reference @@ -5,6 +5,7 @@ col3 UInt64 MATERIALIZED col1 + 2 col4 UInt64 ALIAS col1 + 3 10 11 12 13 +99 payload String date Date MATERIALIZED today() key UInt64 MATERIALIZED 0 * rand() diff --git a/dbms/tests/queries/0_stateless/00079_defaulted_columns.sql b/dbms/tests/queries/0_stateless/00079_defaulted_columns.sql index a2c4f3dfcbb..ce9d2c429f2 100644 --- a/dbms/tests/queries/0_stateless/00079_defaulted_columns.sql +++ b/dbms/tests/queries/0_stateless/00079_defaulted_columns.sql @@ -11,6 +11,11 @@ select * from defaulted_test; select col3, col4 from defaulted_test; drop table defaulted_test; +create table defaulted_test (col1 Int8, col2 UInt64 default (SELECT dummy+99 from system.one)) engine=Memory; +insert into defaulted_test (col1) values (0); +select col2 from defaulted_test; +drop table defaulted_test; + create table defaulted_test (payload String, date materialized today(), key materialized 0 * rand()) engine=MergeTree(date, key, 8192); desc table defaulted_test; insert into defaulted_test (payload) values ('hello clickhouse'); diff --git a/doc/developers/style_ru.md b/doc/developers/style_ru.md index a191b588f8d..505d6fe286e 100644 --- a/doc/developers/style_ru.md +++ b/doc/developers/style_ru.md @@ -20,58 +20,58 @@ 1. Отступы - 4 пробела. Настройте среду разработки так, чтобы таб добавлял четыре пробела. 2. Открывающая фигурная скобка на новой, отдельной строке. (Закрывающая - тоже.) - ```cpp - inline void readBoolText(bool & x, ReadBuffer & buf) - { - char tmp = '0'; - readChar(tmp, buf); - x = tmp != '0'; - } - ``` + ```cpp + inline void readBoolText(bool & x, ReadBuffer & buf) + { + char tmp = '0'; + readChar(tmp, buf); + x = tmp != '0'; + } + ``` 3. Но если всё тело функции достаточно короткое (один statement) - при желании, его можно целиком разместить на одной строке. - При этом, вокруг фигурных скобок ставятся пробелы (кроме пробела на конце строки). - ```cpp - inline size_t mask() const { return buf_size() - 1; } - inline size_t place(HashValue x) const { return x & mask(); } - ``` + При этом, вокруг фигурных скобок ставятся пробелы (кроме пробела на конце строки). + ```cpp + inline size_t mask() const { return buf_size() - 1; } + inline size_t place(HashValue x) const { return x & mask(); } + ``` 4. Для функций, пробелы вокруг скобок не ставятся. - ```cpp - void reinsert(const Value & x) - ``` - ```cpp - memcpy(&buf[place_value], &x, sizeof(x)); - ``` + ```cpp + void reinsert(const Value & x) + ``` + ```cpp + memcpy(&buf[place_value], &x, sizeof(x)); + ``` 5. При использовании выражений if, for, while, ... (в отличие от вызовов функций) перед открывающей скобкой ставится пробел. - ```cpp - for (size_t i = 0; i < rows; i += storage.index_granularity) - ``` + ```cpp + for (size_t i = 0; i < rows; i += storage.index_granularity) + ``` 6. Вокруг бинарных операторов (+, -, *, /, %, ...), а также тернарного оператора ?: ставятся пробелы. - ```cpp - UInt16 year = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0'); - UInt8 month = (s[5] - '0') * 10 + (s[6] - '0'); - UInt8 day = (s[8] - '0') * 10 + (s[9] - '0'); - ``` - Если ставится перенос строки, то оператор пишется на новой строке, и перед ним увеличивается отступ. - ```cpp - if (elapsed_ns) - message << " (" - << rows_read_on_server * 1000000000 / elapsed_ns << " rows/s., " - << bytes_read_on_server * 1000.0 / elapsed_ns << " MB/s.) "; - ``` + ```cpp + UInt16 year = (s[0] - '0') * 1000 + (s[1] - '0') * 100 + (s[2] - '0') * 10 + (s[3] - '0'); + UInt8 month = (s[5] - '0') * 10 + (s[6] - '0'); + UInt8 day = (s[8] - '0') * 10 + (s[9] - '0'); + ``` + Если ставится перенос строки, то оператор пишется на новой строке, и перед ним увеличивается отступ. + ```cpp + if (elapsed_ns) + message << " (" + << rows_read_on_server * 1000000000 / elapsed_ns << " rows/s., " + << bytes_read_on_server * 1000.0 / elapsed_ns << " MB/s.) "; + ``` - 6.1. Внутри строки можно, при желании, выполнять выравнивание с помощью пробелов. - ```cpp - dst.ClickLogID = click.LogID; - dst.ClickEventID = click.EventID; - dst.ClickGoodEvent = click.GoodEvent; - ``` + 6.1. Внутри строки можно, при желании, выполнять выравнивание с помощью пробелов. + ```cpp + dst.ClickLogID = click.LogID; + dst.ClickEventID = click.EventID; + dst.ClickGoodEvent = click.GoodEvent; + ``` 7. Вокруг операторов `.`, `->` не ставятся пробелы. - При необходимости, оператор может быть перенесён на новую строку. В этом случае, перед ним увеличивается отступ. + При необходимости, оператор может быть перенесён на новую строку. В этом случае, перед ним увеличивается отступ. 8. Унарные операторы (`--, ++, *, &`, ...) не отделяются от аргумента пробелом. @@ -80,41 +80,41 @@ 10. Оператор `[]` не отделяется пробелами. 11. В выражении `template <...>`, между `template` и `<` ставится пробел; после `<` и до `>` - не ставится. - ```cpp - template - struct AggregatedStatElement - ``` + ```cpp + template + struct AggregatedStatElement + ``` 12. В классах и структурах, public, private, protected пишется на том же уровне, что и class/struct, а все остальные внутренности - глубже. - ```cpp - template > - class MultiVersion - { - public: - /// Конкретная версия объекта для использования. shared_ptr определяет время жизни версии. - using Version = Ptr; - ``` + ```cpp + template > + class MultiVersion + { + public: + /// Конкретная версия объекта для использования. shared_ptr определяет время жизни версии. + using Version = Ptr; + ``` 13. Если на весь файл один namespace и кроме него ничего существенного нет - то отступ внутри namespace не нужен. 14. Если блок для выражения if, for, while... состоит из одного statement-а, то фигурные скобки писать не обязательно. Вместо этого поместите statement на отдельную строку. Этим statement-ом также может быть вложенный if, for, while... Но если внутренний statement содержит фигурные скобки или else, то у внешнего блок следует писать в фигурных скобках. - ```cpp - /// Если файлы не открыты, то открываем их. - if (streams.empty()) - for (const auto & name : column_names) - streams.emplace(name, std::make_unique( - storage.files[name].data_file.path(), - storage.files[name].marks[mark_number].offset)); - ``` + ```cpp + /// Если файлы не открыты, то открываем их. + if (streams.empty()) + for (const auto & name : column_names) + streams.emplace(name, std::make_unique( + storage.files[name].data_file.path(), + storage.files[name].marks[mark_number].offset)); + ``` 15. Не должно быть пробелов на концах строк. 16. Исходники в кодировке UTF-8. 17. В строковых литералах можно использовать не-ASCII. - ```cpp - << ", " << (timer.elapsed() / chunks_stats.hits) << " μsec/hit."; - ``` + ```cpp + << ", " << (timer.elapsed() / chunks_stats.hits) << " μsec/hit."; + ``` 18. Не пишите несколько выражений в одной строке. @@ -123,78 +123,78 @@ 20. Функции, классы, и т. п. отделяются друг от друга минимум одной, максимум двумя пустыми строками. 21. const (относящийся к значению) пишется до имени типа. - ```cpp - const char * pos - ``` - ```cpp - const std::string & s - ``` - ~~char const * pos~~ + ```cpp + const char * pos + ``` + ```cpp + const std::string & s + ``` + ~~char const * pos~~ 22. При объявлении указателя или ссылки, символы * и & отделяются пробелами с обеих сторон. - ```cpp - const char * pos - ``` - ~~const char* pos~~ - ~~const char *pos~~ + ```cpp + const char * pos + ``` + ~~const char* pos~~ + ~~const char *pos~~ 23. При использовании шаблонных типов, пишите using (кроме, возможно, простейших случаев). - То есть, параметры шаблона указываются только в using-е и затем не повторяются в коде. - using может быть объявлен локально, например, внутри функции. - ```cpp - using FileStreams = std::map>; - FileStreams streams; - ``` - ~~std::map> streams;~~ + То есть, параметры шаблона указываются только в using-е и затем не повторяются в коде. + using может быть объявлен локально, например, внутри функции. + ```cpp + using FileStreams = std::map>; + FileStreams streams; + ``` + ~~std::map> streams;~~ 24. Нельзя объявлять несколько переменных разных типов в одном объявлении. - ~~int x, *y;~~ + ~~int x, *y;~~ 25. c-style cast не используется. - ~~std::cerr << (int)c << std::endl;~~ - ```cpp - std::cerr << static_cast(c) << std::endl; - ``` + ~~std::cerr << (int)c << std::endl;~~ + ```cpp + std::cerr << static_cast(c) << std::endl; + ``` 26. В классах и структурах, группируйте отдельно методы и отдельно члены, внутри каждой области видимости. 27. Для не очень большого класса/структуры, можно не отделять объявления методов от реализации. - Аналогично для маленьких методов в любых классах/структурах. - Для шаблонных классов/структур, лучше не отделять объявления методов от реализации (так как иначе они всё равно должны быть определены в той же единице трансляции). + Аналогично для маленьких методов в любых классах/структурах. + Для шаблонных классов/структур, лучше не отделять объявления методов от реализации (так как иначе они всё равно должны быть определены в той же единице трансляции). 28. Не обязательно умещать код по ширине в 80 символов. Можно в 140. 29. Всегда используйте префиксный инкремент/декремент, если постфиксный не нужен. - ```cpp - for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it) - ``` + ```cpp + for (Names::const_iterator it = column_names.begin(); it != column_names.end(); ++it) + ``` ## 2. Комментарии 1. Необходимо обязательно писать комментарии во всех нетривиальных местах. - Это очень важно. При написании комментария, можно успеть понять, что код не нужен вообще, или что всё сделано неверно. - ```cpp - /** Часть куска памяти, которую можно использовать. - * Например, если internal_buffer - 1MB, а из файла для чтения было загружено в буфер - * только 10 байт, то working_buffer будет иметь размер 10 байт - * (working_buffer.end() будет указывать на позицию сразу после тех 10 байт, которых можно прочитать). - */ - ``` + Это очень важно. При написании комментария, можно успеть понять, что код не нужен вообще, или что всё сделано неверно. + ```cpp + /** Часть куска памяти, которую можно использовать. + * Например, если internal_buffer - 1MB, а из файла для чтения было загружено в буфер + * только 10 байт, то working_buffer будет иметь размер 10 байт + * (working_buffer.end() будет указывать на позицию сразу после тех 10 байт, которых можно прочитать). + */ + ``` 2. Комментарии могут быть сколь угодно подробными. 3. Комментарии пишутся до соответствующего кода. В редких случаях - после, на той же строке. - ```cpp - /** Парсит и исполняет запрос. - */ - void executeQuery( - ReadBuffer & istr, /// Откуда читать запрос (а также данные для INSERT-а, если есть) - WriteBuffer & ostr, /// Куда писать результат - Context & context, /// БД, таблицы, типы данных, движки таблиц, функции, агрегатные функции... - BlockInputStreamPtr & query_plan, /// Сюда может быть записано описание, как выполнялся запрос - QueryProcessingStage::Enum stage = QueryProcessingStage::Complete); /// До какой стадии выполнять SELECT запрос. - ``` + ```cpp + /** Парсит и исполняет запрос. + */ + void executeQuery( + ReadBuffer & istr, /// Откуда читать запрос (а также данные для INSERT-а, если есть) + WriteBuffer & ostr, /// Куда писать результат + Context & context, /// БД, таблицы, типы данных, движки таблиц, функции, агрегатные функции... + BlockInputStreamPtr & query_plan, /// Сюда может быть записано описание, как выполнялся запрос + QueryProcessingStage::Enum stage = QueryProcessingStage::Complete); /// До какой стадии выполнять SELECT запрос. + ``` 4. Комментарии следует писать только на английском языке. @@ -202,8 +202,8 @@ 6. Нельзя писать комментарии, которые не дают дополнительной информации. В частности, нельзя писать пустые комментарии. - - /\*
+ + /\*
\* Procedure Name:
\* Original procedure name:
\* Author:
@@ -222,317 +222,321 @@ \* Purpose:
*/
- (пример взят отсюда: http://home.tamk.fi/~jaalto/course/coding-style/doc/unmaintainable-code/) + (пример взят отсюда: http://home.tamk.fi/~jaalto/course/coding-style/doc/unmaintainable-code/) 7. Нельзя писать мусорные комментарии (автор, дата создания...) в начале каждого файла. 8. Однострочные комментарии начинаются с трёх слешей: `///`, многострочные - с `/**`. Такие комментарии считаются "документрующими". - Замечание: такие комментарии могут использоваться для генерации документации с помощью Doxygen. Но, фактически, Doxygen не используется, так как для навигации по коду гораздо удобне использовать возможности IDE. + Замечание: такие комментарии могут использоваться для генерации документации с помощью Doxygen. Но, фактически, Doxygen не используется, так как для навигации по коду гораздо удобне использовать возможности IDE. 9. В начале и конце многострочного комментария, не должно быть пустых строк (кроме строки, на которой закрывается многострочный комментарий). 10. Для закомментированных кусков кода, используются обычные, не "документирующие" комментарии. - Удаляйте закомментированные куски кода перед коммитом. + Удаляйте закомментированные куски кода перед коммитом. 11. Не нужно писать нецензурную брань в комментариях. 12. Не нужно писать в комментариях слишком много восклицательных знаков или знаков вопроса, или выделять слишком много слов большими буквами. - ~~/// WHAT THE FAIL???~~ + ~~/// WHAT THE FAIL???~~ 13. Не нужно составлять из комментариев строки-разделители. - ~~/*******************************************************/~~ + ~~/*******************************************************/~~ 14. Не нужно писать в комментарии диалог (лучше сказать устно). - ~~/// Зачем ты сделал эту фигню?~~ + ~~/// Зачем ты сделал эту фигню?~~ 15. Не нужно писать комментарий в конце блока о том, что представлял собой этот блок. - ~~} /// for~~ + ~~} /// for~~ ## 3. Имена 1. Имена переменных и членов класса - маленькими буквами с подчёркиванием. - ```cpp - size_t max_block_size; - ``` + ```cpp + size_t max_block_size; + ``` 2. Имена функций (методов) - camelCase с маленькой буквы. - ```cpp - std::string getName() const override { return "Memory"; } - ``` + ```cpp + std::string getName() const override { return "Memory"; } + ``` 3. Имена классов (структур) - CamelCase с большой буквы. Префиксы кроме I для интерфейсов - не используются. - ```cpp - class StorageMemory : public IStorage - ``` + ```cpp + class StorageMemory : public IStorage + ``` 4. Имена using-ов - также, как классов, либо можно добавить _t на конце. 5. Имена типов - параметров шаблонов: в простых случаях - T; T, U; T1, T2. - В более сложных случаях - либо также, как имена классов, либо можно добавить в начало букву T. - ```cpp - template - struct AggregatedStatElement - ``` + В более сложных случаях - либо также, как имена классов, либо можно добавить в начало букву T. + ```cpp + template + struct AggregatedStatElement + ``` 6. Имена констант - параметров шаблонов: либо также, как имена переменных, либо N - в простом случае. - ```cpp - template - struct ExtractDomain - ``` + ```cpp + template + struct ExtractDomain + ``` 7. Для абстрактных классов (интерфейсов) можно добавить в начало имени букву I. - ```cpp - class IBlockInputStream - ``` + ```cpp + class IBlockInputStream + ``` 8. Если переменная используется достаточно локально, то можно использовать короткое имя. - В остальных случаях - используйте достаточно подробное имя, описывающее смысл. - ```cpp - bool info_successfully_loaded = false; - ``` + В остальных случаях - используйте достаточно подробное имя, описывающее смысл. + ```cpp + bool info_successfully_loaded = false; + ``` 9. define-ы - ALL_CAPS с подчёркиванием. Глобальные константы - тоже. - ```cpp - #define MAX_SRC_TABLE_NAMES_TO_STORE 1000 - ``` + ```cpp + #define MAX_SRC_TABLE_NAMES_TO_STORE 1000 + ``` 10. Имена файлов с кодом называйте по стилю соответственно тому, что в них находится. - Если в файле находится один класс - назовите файл, как класс - в CamelCase. - Если в файле находится одна функция - назовите файл, как функцию - в camelCase. + Если в файле находится один класс - назовите файл, как класс - в CamelCase. + Если в файле находится одна функция - назовите файл, как функцию - в camelCase. 11. Если имя содержит сокращение, то: - * для имён переменных, всё сокращение пишется маленькими буквами; - `mysql_connection` - ~~mySQL_connection~~ + * для имён переменных, всё сокращение пишется маленькими буквами; + `mysql_connection` + ~~mySQL_connection~~ - * для имён классов и функций, сохраняются большие буквы в сокращении. - `MySQLConnection` - ~~MySqlConnection~~ + * для имён классов и функций, сохраняются большие буквы в сокращении. + `MySQLConnection` + ~~MySqlConnection~~ 12. Параметры конструктора, использующиеся сразу же для инициализации соответствующих членов класса, следует назвать также, как и члены класса, добавив подчёркивание в конец. - ```cpp - FileQueueProcessor( - const std::string & path_, - const std::string & prefix_, - std::shared_ptr handler_) - : path(path_), - prefix(prefix_), - handler(handler_), - log(&Logger::get("FileQueueProcessor")) - { - } - ``` + ```cpp + FileQueueProcessor( + const std::string & path_, + const std::string & prefix_, + std::shared_ptr handler_) + : path(path_), + prefix(prefix_), + handler(handler_), + log(&Logger::get("FileQueueProcessor")) + { + } + ``` - Также можно называть параметры конструктора так же, как и члены класса (не добавлять подчёркивание), но только если этот параметр не используется в теле конструктора. + Также можно называть параметры конструктора так же, как и члены класса (не добавлять подчёркивание), но только если этот параметр не используется в теле конструктора. 13. Именование локальных переменных и членов класса никак не отличается (никакие префиксы не нужны). - `timer` - ~~m_timer~~ + `timer` + ~~m_timer~~ 15. Константы в enum-е - CamelCase с большой буквы. Также допустимо ALL_CAPS. Если enum не локален, то используйте enum class. - ```cpp - enum class CompressionMethod - { - QuickLZ = 0, - LZ4 = 1, - }; - ``` + ```cpp + enum class CompressionMethod + { + QuickLZ = 0, + LZ4 = 1, + }; + ``` 16. Все имена - по английски. Транслит с русского использовать нельзя. - ~~Stroka~~ + ~~Stroka~~ 17. Сокращения (из нескольких букв разных слов) в именах можно использовать только если они являются общепринятыми (если для сокращения можно найти расшифровку в английской википедии или сделав поисковый запрос). - `AST` `SQL` - ~~NVDH (неведомая х.)~~ - Сокращения в виде обрезанного слова можно использовать, только если такое сокращение является широко используемым. - Впрочем, сокращения также можно использовать, если расшифровка находится рядом в комментарии. + `AST` `SQL` + ~~NVDH (неведомая х.)~~ + Сокращения в виде обрезанного слова можно использовать, только если такое сокращение является широко используемым. + Впрочем, сокращения также можно использовать, если расшифровка находится рядом в комментарии. + +18. Имена файлов с исходниками на C++ должны иметь расширение только .cpp. Заголовочные файлы - только .h. + ~~.hpp~~ ~~.cc~~ ~~.C~~ ~~.inl~~ + Можно `.inl.h`, но не ~~.h.inl~~ ## 4. Как писать код 1. Управление памятью. - Ручное освобождение памяти (delete) можно использовать только в библиотечном коде. - В свою очередь, в библиотечном коде, оператор delete можно использовать только в деструкторах. - В прикладном коде следует делать так, что память освобождается каким-либо объектом, который владеет ей. - Примеры: - * проще всего разместить объект на стеке, или сделать его членом другого класса. - * для большого количества маленьких объектов используйте контейнеры. - * для автоматического освобождения маленького количества объектов, выделенных на куче, используйте shared_ptr/unique_ptr. + Ручное освобождение памяти (delete) можно использовать только в библиотечном коде. + В свою очередь, в библиотечном коде, оператор delete можно использовать только в деструкторах. + В прикладном коде следует делать так, что память освобождается каким-либо объектом, который владеет ей. + Примеры: + * проще всего разместить объект на стеке, или сделать его членом другого класса. + * для большого количества маленьких объектов используйте контейнеры. + * для автоматического освобождения маленького количества объектов, выделенных на куче, используйте shared_ptr/unique_ptr. 2. Управление ресурсами. - Используйте RAII и см. пункт выше. + Используйте RAII и см. пункт выше. 3. Обработка ошибок. - Используйте исключения. В большинстве случаев, нужно только кидать исключения, а ловить - не нужно (потому что RAII). - В программах offline обработки данных, зачастую, можно не ловить исключения. - В серверах, обрабатывающих пользовательские запросы, как правило, достаточно ловить исключения на самом верху обработчика соединения. - В функциях потока, следует ловить и запоминать все исключения, чтобы выкинуть их в основном потоке после join. - ```cpp - /// Если вычислений ещё не было - вычислим первый блок синхронно - if (!started) - { - calculate(); - started = true; - } - else /// Если вычисления уже идут - подождём результата - pool.wait(); + Используйте исключения. В большинстве случаев, нужно только кидать исключения, а ловить - не нужно (потому что RAII). + В программах offline обработки данных, зачастую, можно не ловить исключения. + В серверах, обрабатывающих пользовательские запросы, как правило, достаточно ловить исключения на самом верху обработчика соединения. + В функциях потока, следует ловить и запоминать все исключения, чтобы выкинуть их в основном потоке после join. + ```cpp + /// Если вычислений ещё не было - вычислим первый блок синхронно + if (!started) + { + calculate(); + started = true; + } + else /// Если вычисления уже идут - подождём результата + pool.wait(); - if (exception) - exception->rethrow(); - ``` - Ни в коем случае не "проглатывайте" исключения без разбора. Ни в коем случае, не превращайте все исключения без разбора в сообщения в логе. - ~~catch (...) {}~~ - Если вам нужно проигнорировать какие-то исключения, то игнорируйте только конкретные, а остальные - кидайте обратно. - ```cpp - catch (const DB::Exception & e) - { - if (e.code() == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION) - return nullptr; - else - throw; - } - ``` - При использовании функций, использующих коды возврата или errno - проверяйте результат и кидайте исключение. - ```cpp - if (0 != close(fd)) - throwFromErrno("Cannot close file " + file_name, ErrorCodes::CANNOT_CLOSE_FILE); - ``` - assert-ы не используются. + if (exception) + exception->rethrow(); + ``` + Ни в коем случае не "проглатывайте" исключения без разбора. Ни в коем случае, не превращайте все исключения без разбора в сообщения в логе. + ~~catch (...) {}~~ + Если вам нужно проигнорировать какие-то исключения, то игнорируйте только конкретные, а остальные - кидайте обратно. + ```cpp + catch (const DB::Exception & e) + { + if (e.code() == ErrorCodes::UNKNOWN_AGGREGATE_FUNCTION) + return nullptr; + else + throw; + } + ``` + При использовании функций, использующих коды возврата или errno - проверяйте результат и кидайте исключение. + ```cpp + if (0 != close(fd)) + throwFromErrno("Cannot close file " + file_name, ErrorCodes::CANNOT_CLOSE_FILE); + ``` + assert-ы не используются. 4. Типы исключений. - В прикладном коде не требуется использовать сложную иерархию исключений. Желательно, чтобы текст исключения был понятен системному администратору. + В прикладном коде не требуется использовать сложную иерархию исключений. Желательно, чтобы текст исключения был понятен системному администратору. 5. Исключения, вылетающие из деструкторов. - Использовать не рекомендуется, но допустимо. - Используйте следующие варианты: - * Сделайте функцию (done() или finalize()), которая позволяет заранее выполнить всю работу, в процессе которой может возникнуть исключение. Если эта функция была вызвана, то затем в деструкторе не должно возникать исключений. - * Слишком сложную работу (например, отправку данных по сети) можно вообще не делать в деструкторе, рассчитывая, что пользователь заранее позовёт метод для завершения работы. - * Если в деструкторе возникло исключение, желательно не "проглатывать" его, а вывести информацию в лог (если в этом месте доступен логгер). - * В простых программах, если соответствующие исключения не ловятся, и приводят к завершению работы с записью информации в лог, можно не беспокоиться об исключениях, вылетающих из деструкторов, так как вызов std::terminate (в случае noexcept по-умолчанию в C++11), является приемлимым способом обработки исключения. + Использовать не рекомендуется, но допустимо. + Используйте следующие варианты: + * Сделайте функцию (done() или finalize()), которая позволяет заранее выполнить всю работу, в процессе которой может возникнуть исключение. Если эта функция была вызвана, то затем в деструкторе не должно возникать исключений. + * Слишком сложную работу (например, отправку данных по сети) можно вообще не делать в деструкторе, рассчитывая, что пользователь заранее позовёт метод для завершения работы. + * Если в деструкторе возникло исключение, желательно не "проглатывать" его, а вывести информацию в лог (если в этом месте доступен логгер). + * В простых программах, если соответствующие исключения не ловятся, и приводят к завершению работы с записью информации в лог, можно не беспокоиться об исключениях, вылетающих из деструкторов, так как вызов std::terminate (в случае noexcept по-умолчанию в C++11), является приемлимым способом обработки исключения. 6. Отдельные блоки кода. - Внутри одной функции, можно создать отдельный блок кода, для того, чтобы сделать некоторые переменные локальными в нём, и для того, чтобы соответствующие деструкторы были вызваны при выходе из блока. - ```cpp - Block block = data.in->read(); + Внутри одной функции, можно создать отдельный блок кода, для того, чтобы сделать некоторые переменные локальными в нём, и для того, чтобы соответствующие деструкторы были вызваны при выходе из блока. + ```cpp + Block block = data.in->read(); - { - std::lock_guard lock(mutex); - data.ready = true; - data.block = block; - } + { + std::lock_guard lock(mutex); + data.ready = true; + data.block = block; + } - ready_any.set(); - ``` + ready_any.set(); + ``` 7. Многопоточность. - В программах offline обработки данных: - * cначала добейтесь более-менее максимальной производительности на одном процессорном ядре; - * потом можно распараллеливать код, но только если есть необходимость. - В программах - серверах: - * используйте пул потоков для обработки запросов; - * на данный момент, у нас не было задач, в которых была бы необходимость использовать userspace context switching. - Fork для распараллеливания не используется. + В программах offline обработки данных: + * cначала добейтесь более-менее максимальной производительности на одном процессорном ядре; + * потом можно распараллеливать код, но только если есть необходимость. + В программах - серверах: + * используйте пул потоков для обработки запросов; + * на данный момент, у нас не было задач, в которых была бы необходимость использовать userspace context switching. + Fork для распараллеливания не используется. 8. Синхронизация потоков. - Часто можно сделать так, чтобы отдельные потоки писали данные в разные ячейки памяти (лучше - в разные кэш-линии), и не использовать синхронизацию потоков (кроме joinAll). - Если синхронизация нужна, то в большинстве случаев, достаточно использовать mutex под lock_guard-ом. - В остальных случаях, используйте системные примитивы синхронизации. Не используйте busy wait. - Атомарные операции можно использовать только в простейших случаях. - Не нужно писать самостоятельно lock-free структуры данных, если вы не являетесь экспертом. + Часто можно сделать так, чтобы отдельные потоки писали данные в разные ячейки памяти (лучше - в разные кэш-линии), и не использовать синхронизацию потоков (кроме joinAll). + Если синхронизация нужна, то в большинстве случаев, достаточно использовать mutex под lock_guard-ом. + В остальных случаях, используйте системные примитивы синхронизации. Не используйте busy wait. + Атомарные операции можно использовать только в простейших случаях. + Не нужно писать самостоятельно lock-free структуры данных, если вы не являетесь экспертом. 9. Ссылки и указатели. - В большинстве случаев, предпочитайте ссылки. + В большинстве случаев, предпочитайте ссылки. 10. const. - Используйте константные ссылки, указатели на константу, const_iterator, константные методы. - Считайте, что const - вариант написания "по-умолчанию", а отсутствие const - только при необходимости. - Для переменных, передающихся по значению, использовать const обычно не имеет смысла. + Используйте константные ссылки, указатели на константу, const_iterator, константные методы. + Считайте, что const - вариант написания "по-умолчанию", а отсутствие const - только при необходимости. + Для переменных, передающихся по значению, использовать const обычно не имеет смысла. 11. unsigned. - Используйте unsigned, если нужно. + Используйте unsigned, если нужно. 12. Числовые типы. - Используйте типы UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, а также size_t, ssize_t, ptrdiff_t. - Не используйте для чисел типы signed/unsigned long, long long, short; signed char, unsigned char, а также char. + Используйте типы UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64, а также size_t, ssize_t, ptrdiff_t. + Не используйте для чисел типы signed/unsigned long, long long, short; signed char, unsigned char, а также char. 13. Передача аргументов. - Сложные значения передавайте по ссылке (включая std::string). - Если функция захватывает владение объектом, созданным на куче, то сделайте типом аргумента shared_ptr или unique_ptr. + Сложные значения передавайте по ссылке (включая std::string). + Если функция захватывает владение объектом, созданным на куче, то сделайте типом аргумента shared_ptr или unique_ptr. 14. Возврат значений. - В большинстве случаев, просто возвращайте значение с помощью return. Не пишите ~~return std::move(res)~~. - Если внутри функции создаётся объект на куче и отдаётся наружу, то возвращайте shared_ptr или unique_ptr. - В некоторых редких случаях, может потребоваться возвращать значение через аргумент функции. В этом случае, аргументом будет ссылка. - ```cpp - using AggregateFunctionPtr = std::shared_ptr; + В большинстве случаев, просто возвращайте значение с помощью return. Не пишите ~~return std::move(res)~~. + Если внутри функции создаётся объект на куче и отдаётся наружу, то возвращайте shared_ptr или unique_ptr. + В некоторых редких случаях, может потребоваться возвращать значение через аргумент функции. В этом случае, аргументом будет ссылка. + ```cpp + using AggregateFunctionPtr = std::shared_ptr; - /** Позволяет создать агрегатную функцию по её имени. - */ - class AggregateFunctionFactory - { - public: - AggregateFunctionFactory(); - AggregateFunctionPtr get(const String & name, const DataTypes & argument_types) const; - ``` + /** Позволяет создать агрегатную функцию по её имени. + */ + class AggregateFunctionFactory + { + public: + AggregateFunctionFactory(); + AggregateFunctionPtr get(const String & name, const DataTypes & argument_types) const; + ``` 15. namespace. - Для прикладного кода отдельный namespace использовать не нужно. - Для маленьких библиотек - не требуется. - Для не совсем маленьких библиотек - поместите всё в namespace. - Внутри библиотеки в .h файле можно использовать namespace detail для деталей реализации, не нужных прикладному коду. - В .cpp файле можно использовать static или анонимный namespace для скрытия символов. - Также, namespace можно использовать для enum, чтобы соответствующие имена не попали во внешний namespace (но лучше использовать enum class). + Для прикладного кода отдельный namespace использовать не нужно. + Для маленьких библиотек - не требуется. + Для не совсем маленьких библиотек - поместите всё в namespace. + Внутри библиотеки в .h файле можно использовать namespace detail для деталей реализации, не нужных прикладному коду. + В .cpp файле можно использовать static или анонимный namespace для скрытия символов. + Также, namespace можно использовать для enum, чтобы соответствующие имена не попали во внешний namespace (но лучше использовать enum class). 16. Отложенная инициализация. - Обычно, если для инициализации требуются аргументы, то не пишите конструктор по-умопчанию. - Если потом вам потребовалась отложенная инициализация, то вы можете дописать конструктор по-умолчанию (который создаст объект с некорректным состоянием). Или, для небольшого количества объектов, можно использовать shared_ptr/unique_ptr. - ```cpp - Loader(DB::Connection * connection_, const std::string & query, size_t max_block_size_); + Обычно, если для инициализации требуются аргументы, то не пишите конструктор по-умопчанию. + Если потом вам потребовалась отложенная инициализация, то вы можете дописать конструктор по-умолчанию (который создаст объект с некорректным состоянием). Или, для небольшого количества объектов, можно использовать shared_ptr/unique_ptr. + ```cpp + Loader(DB::Connection * connection_, const std::string & query, size_t max_block_size_); - /// Для отложенной инициализации - Loader() {} - ``` + /// Для отложенной инициализации + Loader() {} + ``` 17. Виртуальные функции. - Если класс не предназначен для полиморфного использования, то не нужно делать функции виртуальными зря. Это относится и к деструктору. + Если класс не предназначен для полиморфного использования, то не нужно делать функции виртуальными зря. Это относится и к деструктору. 17. Кодировки. - Везде используется UTF-8. Используется std::string, char *. Не используется std::wstring, wchar_t. + Везде используется UTF-8. Используется std::string, char *. Не используется std::wstring, wchar_t. 18. Логгирование. - См. примеры везде в коде. - Перед коммитом, удалите всё бессмысленное и отладочное логгирование, и другие виды отладочного вывода. - Не должно быть логгирования на каждую итерацию внутреннего цикла, даже уровня Trace. - При любом уровне логгирования, логи должно быть возможно читать. - Логгирование следует использовать, в основном, только в прикладном коде. - Сообщения в логе должны быть написаны на английском языке. - Желательно, чтобы лог был понятен системному администратору. - Не нужно писать ругательства в лог. - В логе используется кодировка UTF-8. Изредка можно использовать в логе не-ASCII символы. + См. примеры везде в коде. + Перед коммитом, удалите всё бессмысленное и отладочное логгирование, и другие виды отладочного вывода. + Не должно быть логгирования на каждую итерацию внутреннего цикла, даже уровня Trace. + При любом уровне логгирования, логи должно быть возможно читать. + Логгирование следует использовать, в основном, только в прикладном коде. + Сообщения в логе должны быть написаны на английском языке. + Желательно, чтобы лог был понятен системному администратору. + Не нужно писать ругательства в лог. + В логе используется кодировка UTF-8. Изредка можно использовать в логе не-ASCII символы. 19. Ввод-вывод. - Во внутренних циклах (в критичных по производительности участках программы) нельзя использовать iostreams (в том числе, ни в коем случае не используйте stringstream). - Вместо этого используйте библиотеку DB/IO. + Во внутренних циклах (в критичных по производительности участках программы) нельзя использовать iostreams (в том числе, ни в коем случае не используйте stringstream). + Вместо этого используйте библиотеку DB/IO. 20. Дата и время. - См. библиотеку DateLUT. + См. библиотеку DateLUT. 21. include. - В заголовочном файле используется только #pragma once, а include guard-ы писать не нужно. + В заголовочном файле используется только #pragma once, а include guard-ы писать не нужно. 22. using. - using namespace не используется. - using что-то конкретное - можно. Лучше локально - внутри класса или функции. + using namespace не используется. + using что-то конкретное - можно. Лучше локально - внутри класса или функции. 23. Не нужно использовать trailing return type для функций, если в этом нет необходимости. - ~~auto f() -> void;~~ + ~~auto f() -> void;~~ 24. Не нужно объявлять и инициализировать переменные так: - ~~auto s = std::string{"Hello"};~~ - Надо так: - `std::string s = "Hello";` - `std::string s{"Hello"};` + ~~auto s = std::string{"Hello"};~~ + Надо так: + `std::string s = "Hello";` + `std::string s{"Hello"};` 25. Для виртуальных функций, пишите virtual в базовом классе, а в классах-наследниках, пишите override и не пишите virtual. @@ -549,17 +553,17 @@ ## 6. Платформа 1. Мы пишем некроссплатформенный код (под конкретную платформу). - Хотя, при прочих равных условиях, предпочитается более-менее кроссплатформенный или легко портируемый код. + Хотя, при прочих равных условиях, предпочитается более-менее кроссплатформенный или легко портируемый код. 2. Язык - C++17. Возможно использование расширений GNU при необходимости. 3. Компилятор - gcc. На данный момент (апрель 2017), код собирается версией 6.3. (Также код может быть собран clang 4) - Используется стандартная библиотека от gcc. + Используется стандартная библиотека от gcc. 4. ОС - Linux Ubuntu, не более старая, чем Precise. 5. Код пишется под процессор с архитектурой x86_64. - Набор инструкций - минимальный поддерживаемый среди наших серверов. Сейчас это - SSE4.2. + Набор инструкций - минимальный поддерживаемый среди наших серверов. Сейчас это - SSE4.2. 6. Используются флаги компиляции -Wall -Werror. @@ -583,12 +587,12 @@ 6. Программы выкладываются с помощью deb пакетов. 7. Коммиты в master не должны ломать сборку проекта. - А работоспособность собранных программ гарантируется только для отдельных ревизий. + А работоспособность собранных программ гарантируется только для отдельных ревизий. 8. Коммитьте как можно чаще, в том числе и не рабочий код. - Для этого следует использовать бранчи. - Если ваш код в master-е ещё не собирается, перед push-ем - исключите его из сборки; - также вы будете должны его доработать или удалить в течение нескольких дней. + Для этого следует использовать бранчи. + Если ваш код в master-е ещё не собирается, перед push-ем - исключите его из сборки; + также вы будете должны его доработать или удалить в течение нескольких дней. 9. Для нетривиальных изменений, используются бранчи. Следует загружать бранчи на сервер. @@ -600,8 +604,8 @@ 1. Используются стандартная библиотека C++14 (допустимо использовать experimental расширения) а также фреймворки boost, Poco. 2. При необходимости, можно использовать любые известные библиотеки, доступные в ОС из пакетов. - Если есть хорошее готовое решение, то оно используется, даже если для этого придётся установить ещё одну библиотеку. - (Но будьте готовы к тому, что иногда вам придётся выкидывать плохие библиотеки из кода.) + Если есть хорошее готовое решение, то оно используется, даже если для этого придётся установить ещё одну библиотеку. + (Но будьте готовы к тому, что иногда вам придётся выкидывать плохие библиотеки из кода.) 3. Если в пакетах нет нужной библиотеки, или её версия достаточно старая, или если она собрана не так, как нужно, то можно использовать библиотеку, устанавливаемую не из пакетов. @@ -628,51 +632,51 @@ ## A. Дополнительно 1. Явное указание std:: для типов из stddef.h. - Рекомендуется не указывать. То есть, рекомендуется писать size_t вместо std::size_t - потому что это короче. - Но при желании, вы можете всё-таки приписать std:: - такой вариант тоже допустим. + Рекомендуется не указывать. То есть, рекомендуется писать size_t вместо std::size_t - потому что это короче. + Но при желании, вы можете всё-таки приписать std:: - такой вариант тоже допустим. 2. Явное указание std:: для функций из стандартной библиотеки C. - Не рекомендуется. То есть, пишите memcpy вместо std::memcpy. - Причина - существуют похожие нестандартные функции, например, memmem. Мы можем использовать и изредка используем эти функции. Эти функции отсутствуют в namespace std. - Если вы везде напишете std::memcpy вместо memcpy, то будет неудобно смотреться memmem без std::. - Тем не менее, указывать std:: тоже допустимо, если так больше нравится. + Не рекомендуется. То есть, пишите memcpy вместо std::memcpy. + Причина - существуют похожие нестандартные функции, например, memmem. Мы можем использовать и изредка используем эти функции. Эти функции отсутствуют в namespace std. + Если вы везде напишете std::memcpy вместо memcpy, то будет неудобно смотреться memmem без std::. + Тем не менее, указывать std:: тоже допустимо, если так больше нравится. 3. Использование функций из C при наличии аналогов в стандартной библиотеке C++. - Допустимо, если это использование эффективнее. - Для примера, для копирования длинных кусков памяти, используйте memcpy вместо std::copy. + Допустимо, если это использование эффективнее. + Для примера, для копирования длинных кусков памяти, используйте memcpy вместо std::copy. 4. Перенос длинных аргументов функций. - Допустимо использовать любой стиль переноса, похожий на приведённые ниже: + Допустимо использовать любой стиль переноса, похожий на приведённые ниже: - ``` - function( - T1 x1, - T2 x2) - ``` + ``` + function( + T1 x1, + T2 x2) + ``` - ``` - function( - size_t left, size_t right, - const & RangesInDataParts ranges, - size_t limit) - ``` + ``` + function( + size_t left, size_t right, + const & RangesInDataParts ranges, + size_t limit) + ``` - ``` - function(size_t left, size_t right, - const & RangesInDataParts ranges, - size_t limit) - ``` + ``` + function(size_t left, size_t right, + const & RangesInDataParts ranges, + size_t limit) + ``` - ``` - function(size_t left, size_t right, - const & RangesInDataParts ranges, - size_t limit) - ``` + ``` + function(size_t left, size_t right, + const & RangesInDataParts ranges, + size_t limit) + ``` - ``` - function( - size_t left, - size_t right, - const & RangesInDataParts ranges, - size_t limit) - ``` + ``` + function( + size_t left, + size_t right, + const & RangesInDataParts ranges, + size_t limit) + ``` diff --git a/doc/reference/en/agg_functions/index.rst b/doc/reference/en/agg_functions/index.rst index 17bef2c7669..d489aedacff 100644 --- a/doc/reference/en/agg_functions/index.rst +++ b/doc/reference/en/agg_functions/index.rst @@ -273,12 +273,12 @@ Examples: ``uniqArrayIf(arr, cond)``, ``quantilesTimingArrayIf(level1, level2)( -State combinator ------------ -If this combinator is used, the aggregate function returns a non-finished value (for example, in the case of the uniq function, the number of unique values), and the intermediate aggregation state (for example, in the case of the uniq function, a hash table for calculating the number of unique values) AggregateFunction (...) and can be used for further processing or can be stored in a table for subsequent pre-aggregation - see the sections "AggregatingMergeTree" and "functions for working with intermediate aggregation states". +If this combinator is used, the aggregate function returns a non-completed/non-finished value (for example, in the case of the ``uniq`` function, the number of unique values), and the intermediate aggregation state (for example, in the case of the ``uniq`` function, a hash table for calculating the number of unique values), which has type of ``AggregateFunction(...)`` and can be used for further processing or can be saved to a table for subsequent pre-aggregation - see the sections "AggregatingMergeTree" and "functions for working with intermediate aggregation states". -Merge combinator ------------ -In the case of using this combinator, the aggregate function will take as an argument the intermediate state of aggregation, pre-aggregate (combine together) these states, and return the finished value. +In the case of using this combinator, the aggregate function will take as an argument the intermediate state of an aggregation, pre-aggregate (combine together) these states, and return the finished/complete value. -MergeState combinator ---------------- -Merges the intermediate aggregation states, similar to the -Merge combo, but returns a non-ready value, and an intermediate aggregation state, similar to the -State combinator. +Merges the intermediate aggregation states, similar to the -Merge combinator, but returns a non-complete value, but an intermediate aggregation state, similar to the -State combinator. \ No newline at end of file diff --git a/doc/reference/en/table_engines/resharding.rst b/doc/reference/en/table_engines/resharding.rst index 6987d844453..5bb6b733d06 100644 --- a/doc/reference/en/table_engines/resharding.rst +++ b/doc/reference/en/table_engines/resharding.rst @@ -1,4 +1,4 @@ -Перешардирование +Resharding ---------------- .. code-block:: sql diff --git a/libs/libcommon/include/ext/bit_cast.h b/libs/libcommon/include/ext/bit_cast.h new file mode 100644 index 00000000000..78d96f88679 --- /dev/null +++ b/libs/libcommon/include/ext/bit_cast.h @@ -0,0 +1,42 @@ +#pragma once + +#include + + +namespace ext +{ + template + union bit_cast_helper_t + { + using dst = std::decay_t; + using src = std::decay_t; + + static_assert(std::is_copy_constructible::value, "destination type must be CopyConstructible"); + static_assert(std::is_copy_constructible::value, "source type must be CopyConstructible"); + + /** value-initialize member `to` first in case destination type is larger than source */ + dst to{}; + src from; + + bit_cast_helper_t(const From & from) : from{from} {} + + operator dst() const { return to; } + }; + + /** \brief Returns value `from` converted to type `To` while retaining bit representation. + * `To` and `From` must satisfy `CopyConstructible`. */ + template + std::decay_t bit_cast(const From & from) + { + return bit_cast_helper_t{from}; + }; + + /** \brief Returns value `from` converted to type `To` while retaining bit representation. + * `To` and `From` must satisfy `CopyConstructible`. */ + template + std::decay_t safe_bit_cast(const From & from) + { + static_assert(sizeof(To) == sizeof(From), "bit cast on types of different width"); + return bit_cast_helper_t{from}; + }; +} diff --git a/libs/libcommon/include/ext/bit_cast.hpp b/libs/libcommon/include/ext/bit_cast.hpp deleted file mode 100644 index f0fcfb92924..00000000000 --- a/libs/libcommon/include/ext/bit_cast.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - - -namespace ext -{ - template - union bit_cast_helper_t - { - using dst = std::decay_t; - using src = std::decay_t; - - static_assert(std::is_copy_constructible::value, "destination type must be CopyConstructible"); - static_assert(std::is_copy_constructible::value, "source type must be CopyConstructible"); - - /** value-initialize member `to` first in case destination type is larger than source */ - dst to{}; - src from; - - bit_cast_helper_t(const From & from) : from{from} {} - - operator dst() const { return to; } - }; - - /** \brief Returns value `from` converted to type `To` while retaining bit representation. - * `To` and `From` must satisfy `CopyConstructible`. */ - template - std::decay_t bit_cast(const From & from) - { - return bit_cast_helper_t{from}; - }; - - /** \brief Returns value `from` converted to type `To` while retaining bit representation. - * `To` and `From` must satisfy `CopyConstructible`. */ - template - std::decay_t safe_bit_cast(const From & from) - { - static_assert(sizeof(To) == sizeof(From), "bit cast on types of different width"); - return bit_cast_helper_t{from}; - }; -} diff --git a/libs/libcommon/include/ext/collection_cast.h b/libs/libcommon/include/ext/collection_cast.h new file mode 100644 index 00000000000..5b10e7d72e5 --- /dev/null +++ b/libs/libcommon/include/ext/collection_cast.h @@ -0,0 +1,23 @@ +#pragma once + + +namespace ext +{ + /** \brief Returns collection of specified container-type. + * Retains stored value_type, constructs resulting collection using iterator range. */ + template