mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Improve implementation, add tests
This commit is contained in:
parent
5ae3aba4e3
commit
fba99d33bb
@ -2848,6 +2848,7 @@ ProjectionNames QueryAnalyzer::resolveFunction(QueryTreeNodePtr & node, Identifi
|
||||
if (function_in_arguments_nodes.size() != 2)
|
||||
throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, "Function '{}' expects 2 arguments", function_name);
|
||||
|
||||
auto & in_first_argument = function_in_arguments_nodes[0];
|
||||
auto & in_second_argument = function_in_arguments_nodes[1];
|
||||
auto * table_node = in_second_argument->as<TableNode>();
|
||||
auto * table_function_node = in_second_argument->as<TableFunctionNode>();
|
||||
@ -2911,15 +2912,29 @@ ProjectionNames QueryAnalyzer::resolveFunction(QueryTreeNodePtr & node, Identifi
|
||||
|
||||
resolveExpressionNode(in_second_argument, scope, false /*allow_lambda_expression*/, true /*allow_table_expression*/);
|
||||
|
||||
/// Rewrite X in EXPR, where EXPR is a non-const expression, to has(EXPR, X).
|
||||
if (auto * non_const_set_candidate = in_second_argument->as<FunctionNode>())
|
||||
{
|
||||
const auto & candidate_name = non_const_set_candidate->getFunctionName();
|
||||
if (candidate_name == "array")
|
||||
if (candidate_name == "array" && !isNullableOrLowCardinalityNullable(in_first_argument->getResultType()))
|
||||
{
|
||||
function_name = "has";
|
||||
is_special_function_in = false;
|
||||
auto & function_arguments = function_node.getArguments().getNodes();
|
||||
std::swap(function_arguments[0], function_arguments[1]);
|
||||
bool contains_nullable = false;
|
||||
for (const auto & array_elem : non_const_set_candidate->getArguments())
|
||||
{
|
||||
if (isNullableOrLowCardinalityNullable(array_elem->getResultType()))
|
||||
{
|
||||
contains_nullable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contains_nullable)
|
||||
{
|
||||
function_name = "has";
|
||||
is_special_function_in = false;
|
||||
auto & function_arguments = function_node.getArguments().getNodes();
|
||||
std::swap(function_arguments[0], function_arguments[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,3 +7,59 @@
|
||||
1
|
||||
6
|
||||
7
|
||||
-- MORE CASES --
|
||||
-- { echoOn }
|
||||
|
||||
SELECT null in [number % 3, number % 5] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT null in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT 5 in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT (1, 2) in [number % 3, number % 5] FROM numbers(2); -- { serverError NO_COMMON_TYPE }
|
||||
SELECT (1, 2) in (SELECT [0, 0] UNION ALL SELECT [1, 1]); -- { serverError TYPE_MISMATCH }
|
||||
SELECT (1, 2) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
0
|
||||
0
|
||||
SELECT (1, 2) in (SELECT (0, 0)), (1, 2) in (SELECT (1, 1));
|
||||
0 0
|
||||
SELECT (1, 1) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
0
|
||||
1
|
||||
SELECT (1, 1) in (SELECT (0, 0)), (1, 1) in (SELECT (1, 1));
|
||||
0 1
|
||||
SELECT (1, null) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
0
|
||||
0
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int))), (1, null) in (SELECT (1, 1::Nullable(Int)));
|
||||
0 0
|
||||
SELECT (1, null) in [(number % 3, number % 5), (1, null)] FROM numbers(2);
|
||||
1
|
||||
1
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int)) UNION ALL SELECT (1, null)), (1, null) in (SELECT (1, 1::Nullable(Int)) UNION ALL SELECT (1, null));
|
||||
1 1
|
||||
SELECT 'ANOTHER SETTING';
|
||||
ANOTHER SETTING
|
||||
set transform_null_in = 1;
|
||||
SELECT null in [number % 3, number % 5] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT null in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT 5 in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT (1, 2) in [number % 3, number % 5] FROM numbers(2); -- { serverError NO_COMMON_TYPE }
|
||||
SELECT (1, 2) in (SELECT [0, 0] UNION ALL SELECT [1, 1]); -- { serverError TYPE_MISMATCH }
|
||||
SELECT (1, 2) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
0
|
||||
0
|
||||
SELECT (1, 2) in (SELECT (0, 0)), (1, 2) in (SELECT (1, 1));
|
||||
0 0
|
||||
SELECT (1, 1) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
0
|
||||
1
|
||||
SELECT (1, 1) in (SELECT (0, 0)), (1, 1) in (SELECT (1, 1));
|
||||
0 1
|
||||
SELECT (1, null) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
0
|
||||
0
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int))), (1, null) in (SELECT (1, 1::Nullable(Int)));
|
||||
0 0
|
||||
SELECT (1, null) in [(number % 3, number % 5), (1, null)] FROM numbers(2);
|
||||
1
|
||||
1
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int)) UNION ALL SELECT (1, null)), (1, null) in (SELECT (1, 1::Nullable(Int)) UNION ALL SELECT (1, null));
|
||||
1 1
|
||||
|
@ -2,3 +2,50 @@ SELECT number FROM numbers(10) WHERE has([number % 3, number % 5], number % 2) O
|
||||
SELECT '-- IN --';
|
||||
SELECT number FROM numbers(10) WHERE number % 2 IN [number % 3, number % 5] ORDER BY number SETTINGS allow_experimental_analyzer = 1;
|
||||
SELECT number FROM numbers(10) WHERE number % 2 IN [number % 3, number % 5] ORDER BY number SETTINGS allow_experimental_analyzer = 0; -- { serverError UNKNOWN_IDENTIFIER }
|
||||
|
||||
SELECT '-- MORE CASES --';
|
||||
|
||||
-- { echoOn }
|
||||
|
||||
SELECT null in [number % 3, number % 5] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT null in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT 5 in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
|
||||
SELECT (1, 2) in [number % 3, number % 5] FROM numbers(2); -- { serverError NO_COMMON_TYPE }
|
||||
SELECT (1, 2) in (SELECT [0, 0] UNION ALL SELECT [1, 1]); -- { serverError TYPE_MISMATCH }
|
||||
|
||||
SELECT (1, 2) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
SELECT (1, 2) in (SELECT (0, 0)), (1, 2) in (SELECT (1, 1));
|
||||
|
||||
SELECT (1, 1) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
SELECT (1, 1) in (SELECT (0, 0)), (1, 1) in (SELECT (1, 1));
|
||||
|
||||
SELECT (1, null) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int))), (1, null) in (SELECT (1, 1::Nullable(Int)));
|
||||
|
||||
SELECT (1, null) in [(number % 3, number % 5), (1, null)] FROM numbers(2);
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int)) UNION ALL SELECT (1, null)), (1, null) in (SELECT (1, 1::Nullable(Int)) UNION ALL SELECT (1, null));
|
||||
|
||||
SELECT 'ANOTHER SETTING';
|
||||
|
||||
set transform_null_in = 1;
|
||||
|
||||
SELECT null in [number % 3, number % 5] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT null in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
SELECT 5 in [number % 3, number % 5, null] FROM numbers(2); -- { serverError UNSUPPORTED_METHOD }
|
||||
|
||||
SELECT (1, 2) in [number % 3, number % 5] FROM numbers(2); -- { serverError NO_COMMON_TYPE }
|
||||
SELECT (1, 2) in (SELECT [0, 0] UNION ALL SELECT [1, 1]); -- { serverError TYPE_MISMATCH }
|
||||
|
||||
SELECT (1, 2) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
SELECT (1, 2) in (SELECT (0, 0)), (1, 2) in (SELECT (1, 1));
|
||||
|
||||
SELECT (1, 1) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
SELECT (1, 1) in (SELECT (0, 0)), (1, 1) in (SELECT (1, 1));
|
||||
|
||||
SELECT (1, null) in [(number % 3, number % 5)] FROM numbers(2);
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int))), (1, null) in (SELECT (1, 1::Nullable(Int)));
|
||||
|
||||
SELECT (1, null) in [(number % 3, number % 5), (1, null)] FROM numbers(2);
|
||||
SELECT (1, null) in (SELECT (0, 0::Nullable(Int)) UNION ALL SELECT (1, null)), (1, null) in (SELECT (1, 1::Nullable(Int)) UNION ALL SELECT (1, null));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user