mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
Fix nullable primary key with constant conversion
This commit is contained in:
parent
8f5b3f51b7
commit
8fac97692a
@ -1342,34 +1342,48 @@ bool KeyCondition::tryParseAtomFromAST(const ASTPtr & node, ContextPtr context,
|
||||
}
|
||||
}
|
||||
|
||||
key_expr_type = recursiveRemoveLowCardinality(key_expr_type);
|
||||
DataTypePtr key_expr_type_not_null;
|
||||
bool key_expr_type_is_nullable = false;
|
||||
if (const auto * nullable_type = typeid_cast<const DataTypeNullable *>(key_expr_type.get()))
|
||||
{
|
||||
key_expr_type_is_nullable = true;
|
||||
key_expr_type_not_null = nullable_type->getNestedType();
|
||||
}
|
||||
else
|
||||
key_expr_type_not_null = key_expr_type;
|
||||
|
||||
bool cast_not_needed = is_set_const /// Set args are already casted inside Set::createFromAST
|
||||
|| ((isNativeNumber(key_expr_type) || isDateTime(key_expr_type))
|
||||
|| ((isNativeNumber(key_expr_type_not_null) || isDateTime(key_expr_type_not_null))
|
||||
&& (isNativeNumber(const_type) || isDateTime(const_type))); /// Numbers and DateTime are accurately compared without cast.
|
||||
|
||||
if (!cast_not_needed && !key_expr_type->equals(*const_type))
|
||||
if (!cast_not_needed && !key_expr_type_not_null->equals(*const_type))
|
||||
{
|
||||
if (const_value.getType() == Field::Types::String)
|
||||
{
|
||||
const_value = convertFieldToType(const_value, *key_expr_type);
|
||||
const_value = convertFieldToType(const_value, *key_expr_type_not_null);
|
||||
if (const_value.isNull())
|
||||
return false;
|
||||
// No need to set is_constant_transformed because we're doing exact conversion
|
||||
}
|
||||
else
|
||||
{
|
||||
DataTypePtr common_type = getLeastSupertype({key_expr_type, const_type});
|
||||
DataTypePtr common_type = getLeastSupertype({key_expr_type_not_null, const_type});
|
||||
if (!const_type->equals(*common_type))
|
||||
{
|
||||
castValueToType(common_type, const_value, const_type, node);
|
||||
|
||||
// Need to set is_constant_transformed unless we're doing exact conversion
|
||||
if (!key_expr_type->equals(*common_type))
|
||||
if (!key_expr_type_not_null->equals(*common_type))
|
||||
is_constant_transformed = true;
|
||||
}
|
||||
if (!key_expr_type->equals(*common_type))
|
||||
if (!key_expr_type_not_null->equals(*common_type))
|
||||
{
|
||||
auto common_type_maybe_nullable
|
||||
= key_expr_type_is_nullable ? DataTypePtr(std::make_shared<DataTypeNullable>(common_type)) : common_type;
|
||||
ColumnsWithTypeAndName arguments{
|
||||
{nullptr, key_expr_type, ""}, {DataTypeString().createColumnConst(1, common_type->getName()), common_type, ""}};
|
||||
{nullptr, key_expr_type, ""},
|
||||
{DataTypeString().createColumnConst(1, common_type_maybe_nullable->getName()), common_type_maybe_nullable, ""}};
|
||||
FunctionOverloadResolverPtr func_builder_cast = CastInternalOverloadResolver<CastType::nonAccurate>::createImpl();
|
||||
auto func_cast = func_builder_cast->build(arguments);
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
21585718595728998
|
10
tests/queries/0_stateless/02023_nullable_int_uint_where.sql
Normal file
10
tests/queries/0_stateless/02023_nullable_int_uint_where.sql
Normal file
@ -0,0 +1,10 @@
|
||||
drop table if exists t1;
|
||||
|
||||
set allow_suspicious_low_cardinality_types = 1;
|
||||
create table t1 (id LowCardinality(Nullable(Int64))) engine MergeTree order by id settings allow_nullable_key = 1, index_granularity = 1;
|
||||
|
||||
insert into t1 values (21585718595728998), (null);
|
||||
|
||||
select * from t1 where id = 21585718595728998;
|
||||
|
||||
drop table t1;
|
Loading…
Reference in New Issue
Block a user