From 398d38eeadba0f9b5d4cd2bf82d7e53320a77528 Mon Sep 17 00:00:00 2001 From: VadimPE Date: Tue, 28 Aug 2018 16:57:31 +0300 Subject: [PATCH 01/18] CLICKHOUSE-3934 add join_default_strictness --- dbms/src/Common/ErrorCodes.cpp | 1 + dbms/src/Interpreters/ExpressionAnalyzer.cpp | 14 +++++++++++++- dbms/src/Interpreters/Settings.h | 2 ++ dbms/src/Parsers/ParserTablesInSelectQuery.cpp | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index 928d011fb75..407778bd8d6 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -389,6 +389,7 @@ namespace ErrorCodes extern const int NETLINK_ERROR = 412; extern const int CANNOT_SET_SIGNAL_HANDLER = 413; extern const int CANNOT_READLINE = 414; + extern const int EXPECT_ALL_OR_ANY = 415; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index b88c7e16da2..e33f36b0b49 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -96,6 +96,7 @@ namespace ErrorCodes extern const int CONDITIONAL_TREE_PARENT_NOT_FOUND; extern const int TYPE_MISMATCH; extern const int INVALID_JOIN_ON_EXPRESSION; + extern const int EXPECT_ALL_OR_ANY; } @@ -2483,7 +2484,18 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty ExpressionActionsChain::Step & step = chain.steps.back(); const auto & join_element = static_cast(*select_query->join()); - const auto & join_params = static_cast(*join_element.table_join); + auto & join_params = static_cast(*join_element.table_join); + + if (join_params.strictness == ASTTableJoin::Strictness::Unspecified) + { + if (settings.join_default_strictness.toString() == "ANY") + join_params.strictness = ASTTableJoin::Strictness::Any; + else if (settings.join_default_strictness.toString() == "ALL") + join_params.strictness = ASTTableJoin::Strictness::All; + else + throw Exception("Expected ANY or ALL, because setting (join_default_strictness) is empty.", DB::ErrorCodes::EXPECT_ALL_OR_ANY); + } + const auto & table_to_join = static_cast(*join_element.table_expression); getActionsFromJoinKeys(join_params, only_types, false, step.actions); diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index 342725b3902..7e3202f485b 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -173,6 +173,8 @@ struct Settings \ M(SettingBool, join_use_nulls, 0, "Use NULLs for non-joined rows of outer JOINs. If false, use default value of corresponding columns data type.") \ \ + M(SettingString, join_default_strictness, "", "If settings not empty use ANY or ALL in JOIN SELECT query.") \ + \ M(SettingUInt64, preferred_block_size_bytes, 1000000, "") \ \ M(SettingUInt64, max_replica_delay_for_distributed_queries, 300, "If set, distributed queries of Replicated tables will choose servers with replication delay in seconds less than the specified value (not inclusive). Zero means do not take delay into account.") \ diff --git a/dbms/src/Parsers/ParserTablesInSelectQuery.cpp b/dbms/src/Parsers/ParserTablesInSelectQuery.cpp index 6b28deeb227..5eb00858e7c 100644 --- a/dbms/src/Parsers/ParserTablesInSelectQuery.cpp +++ b/dbms/src/Parsers/ParserTablesInSelectQuery.cpp @@ -136,6 +136,8 @@ bool ParserTablesInSelectQueryElement::parseImpl(Pos & pos, ASTPtr & node, Expec table_join->strictness = ASTTableJoin::Strictness::Any; else if (ParserKeyword("ALL").ignore(pos)) table_join->strictness = ASTTableJoin::Strictness::All; + else + table_join->strictness = ASTTableJoin::Strictness::Unspecified; if (ParserKeyword("INNER").ignore(pos)) table_join->kind = ASTTableJoin::Kind::Inner; From 139f85523080a70a55cee7a328c2c40c4e5adac6 Mon Sep 17 00:00:00 2001 From: VadimPE Date: Tue, 28 Aug 2018 17:26:12 +0300 Subject: [PATCH 02/18] CLICKHOUSE-3934 add tests --- .../00701_join_default_strictness.reference | 12 ++++++++++ .../00701_join_default_strictness.sql | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00701_join_default_strictness.reference create mode 100644 dbms/tests/queries/0_stateless/00701_join_default_strictness.sql diff --git a/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference b/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference new file mode 100644 index 00000000000..3b7d0c49964 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference @@ -0,0 +1,12 @@ +1 1 +1 2 +1 3 +1 1 +1 1 +1 1 +1 2 +1 2 +1 2 +1 3 +1 3 +1 3 \ No newline at end of file diff --git a/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql b/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql new file mode 100644 index 00000000000..781fc45164f --- /dev/null +++ b/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql @@ -0,0 +1,22 @@ +CREATE DATABASE IF NOT EXISTS test; +DROP TABLE IF EXISTS test.a1; +DROP TABLE IF EXISTS test.a2; + +CREATE TABLE test.a1(a UInt8, b UInt8) ENGINE=Memory; +CREATE TABLE test.a2(a UInt8, b UInt8) ENGINE=Memory; + +INSERT INTO test.a1 VALUES (1, 1); +INSERT INTO test.a1 VALUES (1, 2); +INSERT INTO test.a1 VALUES (1, 3); +INSERT INTO test.a2 VALUES (1, 2); +INSERT INTO test.a2 VALUES (1, 3); +INSERT INTO test.a2 VALUES (1, 4); + +SELECT a, b FROM test.a1 LEFT JOIN (SELECT a, b FROM test.a2) USING a ORDER BY b; -- { serverError 417 } + +SELECT a, b FROM test.a1 LEFT JOIN (SELECT a, b FROM test.a2) USING a ORDER BY b SETTINGS join_default_strictness='ANY'; + +SELECT a, b FROM test.a1 LEFT JOIN (SELECT a, b FROM test.a2) USING a ORDER BY b SETTINGS join_default_strictness='ALL'; + +DROP TABLE IF EXISTS test.a1; +DROP TABLE IF EXISTS test.a2; \ No newline at end of file From 564ddbf8d82413f702d8e7201cbec868ae6f1bb8 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 28 Aug 2018 17:33:57 +0300 Subject: [PATCH 03/18] Update ExpressionAnalyzer.cpp --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index e33f36b0b49..36642bb6e9b 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -19,7 +19,7 @@ #include #include #include - +F #include #include @@ -2493,7 +2493,7 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty else if (settings.join_default_strictness.toString() == "ALL") join_params.strictness = ASTTableJoin::Strictness::All; else - throw Exception("Expected ANY or ALL, because setting (join_default_strictness) is empty.", DB::ErrorCodes::EXPECT_ALL_OR_ANY); + throw Exception("Expected ANY or ALL, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECT_ALL_OR_ANY); } const auto & table_to_join = static_cast(*join_element.table_expression); From 096b5e6a9d539ff028f322e9ad99d5f76beb1c17 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 28 Aug 2018 17:40:07 +0300 Subject: [PATCH 04/18] Update ExpressionAnalyzer.cpp --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 36642bb6e9b..b420db4cc36 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -19,7 +19,7 @@ #include #include #include -F + #include #include From 98abde84801c55c7af5e827fdb526942b9853d31 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 28 Aug 2018 17:41:15 +0300 Subject: [PATCH 05/18] Update ExpressionAnalyzer.cpp --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index b420db4cc36..15d003d63f4 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -2493,7 +2493,7 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty else if (settings.join_default_strictness.toString() == "ALL") join_params.strictness = ASTTableJoin::Strictness::All; else - throw Exception("Expected ANY or ALL, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECT_ALL_OR_ANY); + throw Exception("Expected ANY or ALL in JOIN section, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECT_ALL_OR_ANY); } const auto & table_to_join = static_cast(*join_element.table_expression); From 9a0802f5bd685ec67ac3494fa75ebd6a65d31ecf Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 28 Aug 2018 17:52:27 +0300 Subject: [PATCH 06/18] fix documentation --- dbms/src/Interpreters/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index cec0937228e..5cc90694c50 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -173,7 +173,7 @@ struct Settings \ M(SettingBool, join_use_nulls, 0, "Use NULLs for non-joined rows of outer JOINs. If false, use default value of corresponding columns data type.") \ \ - M(SettingString, join_default_strictness, "", "If settings not empty use ANY or ALL in JOIN SELECT query.") \ + M(SettingString, join_default_strictness, "", "Set default strictness in JOIN query. If empty, query without strictness will throw exception") \ \ M(SettingUInt64, preferred_block_size_bytes, 1000000, "") \ \ From 6a3d398a261eec6136d8d09268a2347ee8d4a771 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 28 Aug 2018 17:57:44 +0300 Subject: [PATCH 07/18] Update 00701_join_default_strictness.reference --- .../queries/0_stateless/00701_join_default_strictness.reference | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference b/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference index 3b7d0c49964..03c81dd223a 100644 --- a/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference +++ b/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference @@ -9,4 +9,4 @@ 1 2 1 3 1 3 -1 3 \ No newline at end of file +1 3 From 2bab5f941d63a14ff9759e3b51a1e426e3fd3c64 Mon Sep 17 00:00:00 2001 From: Vadim Date: Tue, 28 Aug 2018 17:58:08 +0300 Subject: [PATCH 08/18] Update 00701_join_default_strictness.sql --- .../tests/queries/0_stateless/00701_join_default_strictness.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql b/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql index 781fc45164f..42dc59ac3a7 100644 --- a/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql +++ b/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql @@ -19,4 +19,4 @@ SELECT a, b FROM test.a1 LEFT JOIN (SELECT a, b FROM test.a2) USING a ORDER BY b SELECT a, b FROM test.a1 LEFT JOIN (SELECT a, b FROM test.a2) USING a ORDER BY b SETTINGS join_default_strictness='ALL'; DROP TABLE IF EXISTS test.a1; -DROP TABLE IF EXISTS test.a2; \ No newline at end of file +DROP TABLE IF EXISTS test.a2; From f0c16900aa7df0ebd07497770238ad0991405b34 Mon Sep 17 00:00:00 2001 From: Vadim Plakhtinskiy Date: Wed, 29 Aug 2018 16:51:07 +0300 Subject: [PATCH 09/18] CLICKHOUSE-3934 fix bug with CROSS JOIN --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 15d003d63f4..f04a4d4261f 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -2486,12 +2486,14 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty const auto & join_element = static_cast(*select_query->join()); auto & join_params = static_cast(*join_element.table_join); - if (join_params.strictness == ASTTableJoin::Strictness::Unspecified) + if (join_params.strictness == ASTTableJoin::Strictness::Unspecified && join_params.kind != ASTTableJoin::Kind::Cross) { if (settings.join_default_strictness.toString() == "ANY") join_params.strictness = ASTTableJoin::Strictness::Any; else if (settings.join_default_strictness.toString() == "ALL") join_params.strictness = ASTTableJoin::Strictness::All; + else if (settings.join_default_strictness.toString() != "") + throw Exception("Unexcepted join_default_strictness value = " + settings.join_default_strictness.toString() + ". It can be an empty string, ANY or ALL"); else throw Exception("Expected ANY or ALL in JOIN section, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECT_ALL_OR_ANY); } From d626ae11a72bfa6b7bcbc641113d0eb29d4ef54f Mon Sep 17 00:00:00 2001 From: VadimPE Date: Wed, 29 Aug 2018 16:54:43 +0300 Subject: [PATCH 10/18] CLICKHOUSE-3934 --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index f04a4d4261f..5806e167509 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -2493,7 +2493,7 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty else if (settings.join_default_strictness.toString() == "ALL") join_params.strictness = ASTTableJoin::Strictness::All; else if (settings.join_default_strictness.toString() != "") - throw Exception("Unexcepted join_default_strictness value = " + settings.join_default_strictness.toString() + ". It can be an empty string, ANY or ALL"); + throw Exception("Unexcepted join_default_strictness = " + settings.join_default_strictness.toString() + ". It can be an empty string, ANY or ALL"); else throw Exception("Expected ANY or ALL in JOIN section, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECT_ALL_OR_ANY); } From 697067f207e6e76b157f14f639f18799f717ec3c Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 29 Aug 2018 17:59:08 +0300 Subject: [PATCH 11/18] Fix lifetime of Context reference in functions (first quick variant) [#CLICKHOUSE-2] --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index b88c7e16da2..1db54aaaf8d 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -2054,7 +2054,7 @@ void ExpressionAnalyzer::getActionsImpl(const ASTPtr & ast, bool no_subqueries, if (AggregateFunctionFactory::instance().isAggregateFunctionName(node->name)) return; - const FunctionBuilderPtr & function_builder = FunctionFactory::instance().get(node->name, context); + const FunctionBuilderPtr & function_builder = FunctionFactory::instance().get(node->name, context.getQueryContext()); auto projection_action = getProjectionAction(node->name, actions_stack, projection_manipulator, getColumnName(), context); Names argument_names; From f253719eac18119859c5def7163b4aa9a0e9cddd Mon Sep 17 00:00:00 2001 From: VadimPE Date: Wed, 29 Aug 2018 18:15:42 +0300 Subject: [PATCH 12/18] CLICKHOUSE-3934 add SettingsJoinStrictness --- dbms/src/Common/ErrorCodes.cpp | 3 +- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 6 +-- dbms/src/Interpreters/Settings.h | 2 +- dbms/src/Interpreters/SettingsCommon.cpp | 48 ++++++++++++++++++++ dbms/src/Interpreters/SettingsCommon.h | 31 +++++++++++++ 5 files changed, 84 insertions(+), 6 deletions(-) diff --git a/dbms/src/Common/ErrorCodes.cpp b/dbms/src/Common/ErrorCodes.cpp index 719775701d4..513a26987e0 100644 --- a/dbms/src/Common/ErrorCodes.cpp +++ b/dbms/src/Common/ErrorCodes.cpp @@ -391,7 +391,8 @@ namespace ErrorCodes extern const int CANNOT_READLINE = 414; extern const int ALL_REPLICAS_LOST = 415; extern const int REPLICA_STATUS_CHANGED = 416; - extern const int EXPECT_ALL_OR_ANY = 417; + extern const int EXPECTED_ALL_OR_ANY = 417; + extern const int UNKNOWN_JOIN_STRICTNESS = 418; extern const int KEEPER_EXCEPTION = 999; extern const int POCO_EXCEPTION = 1000; diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 5806e167509..7f7edaebaaf 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -96,7 +96,7 @@ namespace ErrorCodes extern const int CONDITIONAL_TREE_PARENT_NOT_FOUND; extern const int TYPE_MISMATCH; extern const int INVALID_JOIN_ON_EXPRESSION; - extern const int EXPECT_ALL_OR_ANY; + extern const int EXPECTED_ALL_OR_ANY; } @@ -2492,10 +2492,8 @@ bool ExpressionAnalyzer::appendJoin(ExpressionActionsChain & chain, bool only_ty join_params.strictness = ASTTableJoin::Strictness::Any; else if (settings.join_default_strictness.toString() == "ALL") join_params.strictness = ASTTableJoin::Strictness::All; - else if (settings.join_default_strictness.toString() != "") - throw Exception("Unexcepted join_default_strictness = " + settings.join_default_strictness.toString() + ". It can be an empty string, ANY or ALL"); else - throw Exception("Expected ANY or ALL in JOIN section, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECT_ALL_OR_ANY); + throw Exception("Expected ANY or ALL in JOIN section, because setting (join_default_strictness) is empty", DB::ErrorCodes::EXPECTED_ALL_OR_ANY); } const auto & table_to_join = static_cast(*join_element.table_expression); diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index 5cc90694c50..1bacccc2929 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -173,7 +173,7 @@ struct Settings \ M(SettingBool, join_use_nulls, 0, "Use NULLs for non-joined rows of outer JOINs. If false, use default value of corresponding columns data type.") \ \ - M(SettingString, join_default_strictness, "", "Set default strictness in JOIN query. If empty, query without strictness will throw exception") \ + M(SettingJoinStrictness, join_default_strictness, JoinStrictness::Unspecified, "Set default strictness in JOIN query. If empty, query without strictness will throw exception") \ \ M(SettingUInt64, preferred_block_size_bytes, 1000000, "") \ \ diff --git a/dbms/src/Interpreters/SettingsCommon.cpp b/dbms/src/Interpreters/SettingsCommon.cpp index dfc79fd86c5..ccf4cade6a1 100644 --- a/dbms/src/Interpreters/SettingsCommon.cpp +++ b/dbms/src/Interpreters/SettingsCommon.cpp @@ -22,6 +22,7 @@ namespace ErrorCodes extern const int UNKNOWN_COMPRESSION_METHOD; extern const int UNKNOWN_DISTRIBUTED_PRODUCT_MODE; extern const int UNKNOWN_GLOBAL_SUBQUERIES_METHOD; + extern const int UNKNOWN_JOIN_STRICTNESS; extern const int SIZE_OF_FIXED_STRING_DOESNT_MATCH; extern const int BAD_ARGUMENTS; } @@ -288,6 +289,53 @@ void SettingLoadBalancing::write(WriteBuffer & buf) const } +JoinStrictness SettingJoinStrictness::getJoinStrictness(const String & s) +{ + if (s == "") return JoinStrictness::Unspecified; + if (s == "ALL") return JoinStrictness::ALL; + if (s == "ANY") return JoinStrictness::ANY; + + throw Exception("Unknown join strictness mode: '" + s + "', must be one of '', 'ALL', 'ANY'", + ErrorCodes::UNKNOWN_JOIN_STRICTNESS); +} + +String SettingJoinStrictness::toString() const +{ + const char * strings[] = {"", "ALL", "ANY"}; + if (value < JoinStrictness::Unspecified || value > JoinStrictness::ANY) + throw Exception("Unknown join strictness mode", ErrorCodes::UNKNOWN_JOIN_STRICTNESS); + return strings[static_cast(value)]; +} + +void SettingJoinStrictness::set(JoinStrictness x) +{ + value = x; + changed = true; +} + +void SettingJoinStrictness::set(const Field & x) +{ + set(safeGet(x)); +} + +void SettingJoinStrictness::set(const String & x) +{ + set(getJoinStrictness(x)); +} + +void SettingJoinStrictness::set(ReadBuffer & buf) +{ + String x; + readBinary(x, buf); + set(x); +} + +void SettingJoinStrictness::write(WriteBuffer & buf) const +{ + writeBinary(toString(), buf); +} + + TotalsMode SettingTotalsMode::getTotalsMode(const String & s) { if (s == "before_having") return TotalsMode::BEFORE_HAVING; diff --git a/dbms/src/Interpreters/SettingsCommon.h b/dbms/src/Interpreters/SettingsCommon.h index fc441ea30c1..667912d01be 100644 --- a/dbms/src/Interpreters/SettingsCommon.h +++ b/dbms/src/Interpreters/SettingsCommon.h @@ -191,6 +191,37 @@ struct SettingLoadBalancing }; +enum class JoinStrictness +{ + Unspecified = 0, /// Query JOIN without strictness will throw Exception. + ALL, /// Query JOIN without strictness -> ALL JOIN ... + ANY, /// Query JOIN without strictness -> ANY JOIN ... +}; + + +struct SettingJoinStrictness +{ + JoinStrictness value; + bool changed = false; + + SettingJoinStrictness(JoinStrictness x) : value(x) {} + + operator JoinStrictness() const { return value; } + SettingJoinStrictness & operator= (JoinStrictness x) { set(x); return *this; } + + static JoinStrictness getJoinStrictness(const String & s); + + String toString() const; + + void set(JoinStrictness x); + void set(const Field & x); + void set(const String & x); + void set(ReadBuffer & buf); + + void write(WriteBuffer & buf) const; +}; + + /// Which rows should be included in TOTALS. enum class TotalsMode { From 3361247126688ec917f51e2c8c01cfefae9b0dd8 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 29 Aug 2018 18:36:24 +0300 Subject: [PATCH 13/18] Fix lifetime of Context reference in functions (first quick variant) [#CLICKHOUSE-2] --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 1db54aaaf8d..60ac051e2b3 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -2054,8 +2054,13 @@ void ExpressionAnalyzer::getActionsImpl(const ASTPtr & ast, bool no_subqueries, if (AggregateFunctionFactory::instance().isAggregateFunctionName(node->name)) return; - const FunctionBuilderPtr & function_builder = FunctionFactory::instance().get(node->name, context.getQueryContext()); - auto projection_action = getProjectionAction(node->name, actions_stack, projection_manipulator, getColumnName(), context); + /// Context object that we pass to function should live during query. + const Context & function_context = context.hasQueryContext() + ? context.getQueryContext() + : context; + + const FunctionBuilderPtr & function_builder = FunctionFactory::instance().get(node->name, function_context); + auto projection_action = getProjectionAction(node->name, actions_stack, projection_manipulator, getColumnName(), function_context); Names argument_names; DataTypes argument_types; From cf33608e62e451982aedf2dbd6a0f73d977d278f Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 29 Aug 2018 18:54:00 +0300 Subject: [PATCH 14/18] Enabled JEMALLOC_DEBUG in debug build [#CLICKHOUSE-2] --- CMakeLists.txt | 2 +- contrib/jemalloc-cmake/CMakeLists.txt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 226d255fd37..5cc6c342961 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ if (NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "None") set (CMAKE_BUILD_TYPE "RELWITHDEBINFO") endif () string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC) -message (STATUS "CMAKE_BUILD_TYPE: " ${CMAKE_BUILD_TYPE} ) +message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") set (CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Debug;Release;MinSizeRel" CACHE STRING "" FORCE) diff --git a/contrib/jemalloc-cmake/CMakeLists.txt b/contrib/jemalloc-cmake/CMakeLists.txt index d60d34604a9..696ea5fee10 100644 --- a/contrib/jemalloc-cmake/CMakeLists.txt +++ b/contrib/jemalloc-cmake/CMakeLists.txt @@ -50,3 +50,7 @@ target_include_directories(jemalloc PRIVATE ${JEMALLOC_SOURCE_DIR}/include) target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_NO_PRIVATE_NAMESPACE) + +if (CMAKE_BUILD_TYPE_UC STREQUAL "DEBUG") + target_compile_definitions(jemalloc PRIVATE -DJEMALLOC_DEBUG=1) +endif () From 48db3d4df8c716d052fe896d9ed677c8451ef692 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 29 Aug 2018 19:27:29 +0300 Subject: [PATCH 15/18] Added test #2989 --- .../queries/0_stateless/00701_context_use_after_free.reference | 1 + dbms/tests/queries/0_stateless/00701_context_use_after_free.sql | 1 + 2 files changed, 2 insertions(+) create mode 100644 dbms/tests/queries/0_stateless/00701_context_use_after_free.reference create mode 100644 dbms/tests/queries/0_stateless/00701_context_use_after_free.sql diff --git a/dbms/tests/queries/0_stateless/00701_context_use_after_free.reference b/dbms/tests/queries/0_stateless/00701_context_use_after_free.reference new file mode 100644 index 00000000000..573541ac970 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00701_context_use_after_free.reference @@ -0,0 +1 @@ +0 diff --git a/dbms/tests/queries/0_stateless/00701_context_use_after_free.sql b/dbms/tests/queries/0_stateless/00701_context_use_after_free.sql new file mode 100644 index 00000000000..c7e68fcdf5c --- /dev/null +++ b/dbms/tests/queries/0_stateless/00701_context_use_after_free.sql @@ -0,0 +1 @@ +SELECT (toDecimal128(materialize('1'), 0), toDecimal128('2', 0)) < (toDecimal128('1', 0), toDecimal128('2', 0)); From b0f66d15d2573e3f2bd32a511f2f88e736ee4b3b Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 29 Aug 2018 19:42:45 +0300 Subject: [PATCH 16/18] Update 00701_join_default_strictness.sql --- .../tests/queries/0_stateless/00701_join_default_strictness.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql b/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql index 42dc59ac3a7..a246ca68d45 100644 --- a/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql +++ b/dbms/tests/queries/0_stateless/00701_join_default_strictness.sql @@ -2,6 +2,8 @@ CREATE DATABASE IF NOT EXISTS test; DROP TABLE IF EXISTS test.a1; DROP TABLE IF EXISTS test.a2; +SET send_logs_level = 'none'; + CREATE TABLE test.a1(a UInt8, b UInt8) ENGINE=Memory; CREATE TABLE test.a2(a UInt8, b UInt8) ENGINE=Memory; From 59e494a78d4e964b3b780fa59e3ad9b6d32f2f06 Mon Sep 17 00:00:00 2001 From: Vadim Date: Wed, 29 Aug 2018 19:48:09 +0300 Subject: [PATCH 17/18] Update 00701_join_default_strictness.reference --- .../00701_join_default_strictness.reference | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference b/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference index 03c81dd223a..ae51f642911 100644 --- a/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference +++ b/dbms/tests/queries/0_stateless/00701_join_default_strictness.reference @@ -1,12 +1,12 @@ -1 1 -1 2 -1 3 -1 1 -1 1 -1 1 -1 2 -1 2 -1 2 -1 3 -1 3 -1 3 +1 1 +1 2 +1 3 +1 1 +1 1 +1 1 +1 2 +1 2 +1 2 +1 3 +1 3 +1 3 From b99bf0c558b93a60ccc7b0fb4c7326bea7f8502e Mon Sep 17 00:00:00 2001 From: alexey-milovidov Date: Wed, 29 Aug 2018 21:27:41 +0300 Subject: [PATCH 18/18] Update Settings.h --- dbms/src/Interpreters/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbms/src/Interpreters/Settings.h b/dbms/src/Interpreters/Settings.h index 1bacccc2929..57d5d71799a 100644 --- a/dbms/src/Interpreters/Settings.h +++ b/dbms/src/Interpreters/Settings.h @@ -173,7 +173,7 @@ struct Settings \ M(SettingBool, join_use_nulls, 0, "Use NULLs for non-joined rows of outer JOINs. If false, use default value of corresponding columns data type.") \ \ - M(SettingJoinStrictness, join_default_strictness, JoinStrictness::Unspecified, "Set default strictness in JOIN query. If empty, query without strictness will throw exception") \ + M(SettingJoinStrictness, join_default_strictness, JoinStrictness::Unspecified, "Set default strictness in JOIN query. Possible values: empty string, 'ANY', 'ALL'. If empty, query without strictness will throw exception.") \ \ M(SettingUInt64, preferred_block_size_bytes, 1000000, "") \ \