mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 10:31:57 +00:00
Allow different types inside IN subquery
This commit is contained in:
parent
dff31e8de7
commit
f4b8e8ef99
@ -515,15 +515,23 @@ inline bool NO_SANITIZE_UNDEFINED convertNumeric(From value, To & result)
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Note that NaNs doesn't compare equal to anything, but they are still in range of any Float type.
|
||||
if (isNaN(value) && std::is_floating_point_v<To>)
|
||||
if constexpr (std::is_floating_point_v<From> && std::is_floating_point_v<To>) {
|
||||
/// Note that NaNs doesn't compare equal to anything, but they are still in range of any Float type.
|
||||
if (isNaN(value))
|
||||
{
|
||||
result = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (accurate::greaterOp(value, std::numeric_limits<To>::max())
|
||||
|| accurate::greaterOp(std::numeric_limits<To>::min(), value))
|
||||
{
|
||||
result = value;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
result = static_cast<To>(value);
|
||||
return equalsOp(value, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2897,8 +2897,6 @@ public:
|
||||
|
||||
ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; }
|
||||
|
||||
protected:
|
||||
|
||||
FunctionBaseImplPtr build(const ColumnsWithTypeAndName & arguments, const DataTypePtr & return_type) const override
|
||||
{
|
||||
DataTypes data_types(arguments.size());
|
||||
@ -2909,7 +2907,7 @@ protected:
|
||||
auto monotonicity = MonotonicityHelper::getMonotonicityInformation(arguments.front().type, return_type.get());
|
||||
return std::make_unique<FunctionCast>(name, std::move(monotonicity), data_types, return_type, std::optional<Diagnostic>(), true);
|
||||
}
|
||||
|
||||
protected:
|
||||
DataTypePtr getReturnType(const ColumnsWithTypeAndName & arguments) const override
|
||||
{
|
||||
const auto & column = arguments.back().column;
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include <DataTypes/DataTypeTuple.h>
|
||||
#include <DataTypes/DataTypeNullable.h>
|
||||
|
||||
#include <Functions/FunctionsConversion.h>
|
||||
|
||||
#include <Parsers/ASTExpressionList.h>
|
||||
#include <Parsers/ASTFunction.h>
|
||||
#include <Parsers/ASTLiteral.h>
|
||||
@ -30,6 +32,7 @@
|
||||
#include <ext/range.h>
|
||||
#include <DataTypes/DataTypeLowCardinality.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -254,8 +257,15 @@ ColumnPtr Set::execute(const Block & block, bool negative) const
|
||||
|
||||
for (size_t i = 0; i < num_key_columns; ++i)
|
||||
{
|
||||
checkTypesEqual(i, block.safeGetByPosition(i).type);
|
||||
materialized_columns.emplace_back(block.safeGetByPosition(i).column->convertToFullColumnIfConst());
|
||||
/// TODO: Optimize making cast only if types different
|
||||
/// TODO: This case SELECT '1' IN (SELECT 1); should not work but with AccurateCastOrNull it works
|
||||
auto & column_before_cast = block.safeGetByPosition(i);
|
||||
ColumnWithTypeAndName column
|
||||
= {column_before_cast.column->convertToFullColumnIfConst(), column_before_cast.type, column_before_cast.name};
|
||||
auto accurate_cast = AccurateCastOverloadResolver().build({column}, data_types[i]);
|
||||
auto accurate_cast_executable = accurate_cast->prepare({column});
|
||||
auto casted_column = accurate_cast_executable->execute({column}, data_types[i], column.column->size());
|
||||
materialized_columns.emplace_back() = casted_column;
|
||||
key_columns.emplace_back() = materialized_columns.back().get();
|
||||
}
|
||||
|
||||
|
@ -825,6 +825,8 @@ bool KeyCondition::tryPrepareSetIndex(
|
||||
|
||||
const ASTPtr & right_arg = args[1];
|
||||
|
||||
/// TODO: Check this place after cast introduced in Set
|
||||
|
||||
SetPtr prepared_set;
|
||||
if (right_arg->as<ASTSubquery>() || right_arg->as<ASTIdentifier>())
|
||||
{
|
||||
|
@ -0,0 +1,6 @@
|
||||
1
|
||||
1
|
||||
2
|
||||
2
|
||||
1
|
||||
1
|
@ -0,0 +1,28 @@
|
||||
-- SELECT 1 IN (SELECT -1)
|
||||
-- SELECT -1 IN (SELECT 1)
|
||||
|
||||
CREATE TABLE select_in_test(value UInt8) ENGINE=TinyLog;
|
||||
INSERT INTO select_in_test VALUES (1), (2), (3);
|
||||
|
||||
SELECT value FROM select_in_test WHERE value IN (-1);
|
||||
SELECT value FROM select_in_test WHERE value IN (SELECT -1);
|
||||
|
||||
SELECT value FROM select_in_test WHERE value IN (1);
|
||||
SELECT value FROM select_in_test WHERE value IN (SELECT 1);
|
||||
|
||||
DROP TABLE select_in_test;
|
||||
|
||||
CREATE TABLE select_in_test(value Int8) ENGINE=TinyLog;
|
||||
INSERT INTO select_in_test VALUES (-1), (2), (3);
|
||||
|
||||
SELECT value FROM select_in_test WHERE value IN (1);
|
||||
SELECT value FROM select_in_test WHERE value IN (SELECT 1);
|
||||
|
||||
SELECT value FROM select_in_test WHERE value IN (2);
|
||||
SELECT value FROM select_in_test WHERE value IN (SELECT 2);
|
||||
|
||||
DROP TABLE select_in_test;
|
||||
|
||||
SELECT 1 IN (1);
|
||||
-- Right now this working because of accurate cast. Need to discuss.
|
||||
SELECT '1' IN (SELECT 1);
|
Loading…
Reference in New Issue
Block a user