mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-11 17:02:25 +00:00
more types in ASOF JOIN (#11301)
This commit is contained in:
parent
c22e8f6b9b
commit
9028a25f3c
@ -333,6 +333,17 @@ void ColumnDecimal<T>::getExtremes(Field & min, Field & max) const
|
||||
max = NearestFieldType<T>(cur_max, scale);
|
||||
}
|
||||
|
||||
TypeIndex columnDecimalDataType(const IColumn * column)
|
||||
{
|
||||
if (checkColumn<ColumnDecimal<Decimal32>>(column))
|
||||
return TypeIndex::Decimal32;
|
||||
else if (checkColumn<ColumnDecimal<Decimal64>>(column))
|
||||
return TypeIndex::Decimal64;
|
||||
else if (checkColumn<ColumnDecimal<Decimal128>>(column))
|
||||
return TypeIndex::Decimal128;
|
||||
return TypeIndex::Nothing;
|
||||
}
|
||||
|
||||
template class ColumnDecimal<Decimal32>;
|
||||
template class ColumnDecimal<Decimal64>;
|
||||
template class ColumnDecimal<Decimal128>;
|
||||
|
@ -197,4 +197,6 @@ ColumnPtr ColumnDecimal<T>::indexImpl(const PaddedPODArray<Type> & indexes, size
|
||||
return res;
|
||||
}
|
||||
|
||||
TypeIndex columnDecimalDataType(const IColumn * column);
|
||||
|
||||
}
|
||||
|
@ -517,6 +517,33 @@ void ColumnVector<T>::getExtremes(Field & min, Field & max) const
|
||||
max = NearestFieldType<T>(cur_max);
|
||||
}
|
||||
|
||||
TypeIndex columnVectorDataType(const IColumn * column)
|
||||
{
|
||||
if (checkColumn<ColumnVector<UInt8>>(column))
|
||||
return TypeIndex::UInt8;
|
||||
else if (checkColumn<ColumnVector<UInt16>>(column))
|
||||
return TypeIndex::UInt16;
|
||||
else if (checkColumn<ColumnVector<UInt32>>(column))
|
||||
return TypeIndex::UInt32;
|
||||
else if (checkColumn<ColumnVector<UInt64>>(column))
|
||||
return TypeIndex::UInt64;
|
||||
else if (checkColumn<ColumnVector<Int8>>(column))
|
||||
return TypeIndex::Int8;
|
||||
else if (checkColumn<ColumnVector<Int16>>(column))
|
||||
return TypeIndex::Int16;
|
||||
else if (checkColumn<ColumnVector<Int32>>(column))
|
||||
return TypeIndex::Int32;
|
||||
else if (checkColumn<ColumnVector<Int64>>(column))
|
||||
return TypeIndex::Int64;
|
||||
else if (checkColumn<ColumnVector<Int128>>(column))
|
||||
return TypeIndex::Int128;
|
||||
else if (checkColumn<ColumnVector<Float32>>(column))
|
||||
return TypeIndex::Float32;
|
||||
else if (checkColumn<ColumnVector<Float64>>(column))
|
||||
return TypeIndex::Float64;
|
||||
return TypeIndex::Nothing;
|
||||
}
|
||||
|
||||
/// Explicit template instantiations - to avoid code bloat in headers.
|
||||
template class ColumnVector<UInt8>;
|
||||
template class ColumnVector<UInt16>;
|
||||
|
@ -320,4 +320,6 @@ ColumnPtr ColumnVector<T>::indexImpl(const PaddedPODArray<Type> & indexes, size_
|
||||
return res;
|
||||
}
|
||||
|
||||
TypeIndex columnVectorDataType(const IColumn * column);
|
||||
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public:
|
||||
|
||||
ASTTableJoin::Kind getKind() const { return kind; }
|
||||
ASTTableJoin::Strictness getStrictness() const { return strictness; }
|
||||
AsofRowRefs::Type getAsofType() const { return *asof_type; }
|
||||
TypeIndex getAsofType() const { return *asof_type; }
|
||||
ASOF::Inequality getAsofInequality() const { return asof_inequality; }
|
||||
bool anyTakeLastRow() const { return any_take_last_row; }
|
||||
|
||||
@ -344,7 +344,7 @@ private:
|
||||
bool nullable_right_side; /// In case of LEFT and FULL joins, if use_nulls, convert right-side columns to Nullable.
|
||||
bool nullable_left_side; /// In case of RIGHT and FULL joins, if use_nulls, convert left-side columns to Nullable.
|
||||
bool any_take_last_row; /// Overwrite existing values when encountering the same key again
|
||||
std::optional<AsofRowRefs::Type> asof_type;
|
||||
std::optional<TypeIndex> asof_type;
|
||||
ASOF::Inequality asof_inequality;
|
||||
|
||||
/// Right table data. StorageJoin shares it between many Join objects.
|
||||
|
@ -17,19 +17,25 @@ namespace
|
||||
|
||||
/// maps enum values to types
|
||||
template <typename F>
|
||||
void callWithType(AsofRowRefs::Type which, F && f)
|
||||
void callWithType(TypeIndex which, F && f)
|
||||
{
|
||||
switch (which)
|
||||
{
|
||||
case AsofRowRefs::Type::keyu32: return f(UInt32());
|
||||
case AsofRowRefs::Type::keyu64: return f(UInt64());
|
||||
case AsofRowRefs::Type::keyi32: return f(Int32());
|
||||
case AsofRowRefs::Type::keyi64: return f(Int64());
|
||||
case AsofRowRefs::Type::keyf32: return f(Float32());
|
||||
case AsofRowRefs::Type::keyf64: return f(Float64());
|
||||
case AsofRowRefs::Type::keyDecimal32: return f(Decimal32());
|
||||
case AsofRowRefs::Type::keyDecimal64: return f(Decimal64());
|
||||
case AsofRowRefs::Type::keyDecimal128: return f(Decimal128());
|
||||
case TypeIndex::UInt8: return f(UInt8());
|
||||
case TypeIndex::UInt16: return f(UInt16());
|
||||
case TypeIndex::UInt32: return f(UInt32());
|
||||
case TypeIndex::UInt64: return f(UInt64());
|
||||
case TypeIndex::Int8: return f(Int8());
|
||||
case TypeIndex::Int16: return f(Int16());
|
||||
case TypeIndex::Int32: return f(Int32());
|
||||
case TypeIndex::Int64: return f(Int64());
|
||||
case TypeIndex::Float32: return f(Float32());
|
||||
case TypeIndex::Float64: return f(Float64());
|
||||
case TypeIndex::Decimal32: return f(Decimal32());
|
||||
case TypeIndex::Decimal64: return f(Decimal64());
|
||||
case TypeIndex::Decimal128: return f(Decimal128());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
__builtin_unreachable();
|
||||
@ -38,7 +44,7 @@ void callWithType(AsofRowRefs::Type which, F && f)
|
||||
}
|
||||
|
||||
|
||||
AsofRowRefs::AsofRowRefs(Type type)
|
||||
AsofRowRefs::AsofRowRefs(TypeIndex type)
|
||||
{
|
||||
auto call = [&](const auto & t)
|
||||
{
|
||||
@ -50,7 +56,7 @@ AsofRowRefs::AsofRowRefs(Type type)
|
||||
callWithType(type, call);
|
||||
}
|
||||
|
||||
void AsofRowRefs::insert(Type type, const IColumn * asof_column, const Block * block, size_t row_num)
|
||||
void AsofRowRefs::insert(TypeIndex type, const IColumn * asof_column, const Block * block, size_t row_num)
|
||||
{
|
||||
auto call = [&](const auto & t)
|
||||
{
|
||||
@ -68,7 +74,7 @@ void AsofRowRefs::insert(Type type, const IColumn * asof_column, const Block * b
|
||||
callWithType(type, call);
|
||||
}
|
||||
|
||||
const RowRef * AsofRowRefs::findAsof(Type type, ASOF::Inequality inequality, const IColumn * asof_column, size_t row_num) const
|
||||
const RowRef * AsofRowRefs::findAsof(TypeIndex type, ASOF::Inequality inequality, const IColumn * asof_column, size_t row_num) const
|
||||
{
|
||||
const RowRef * out = nullptr;
|
||||
|
||||
@ -96,52 +102,56 @@ const RowRef * AsofRowRefs::findAsof(Type type, ASOF::Inequality inequality, con
|
||||
return out;
|
||||
}
|
||||
|
||||
std::optional<AsofRowRefs::Type> AsofRowRefs::getTypeSize(const IColumn * asof_column, size_t & size)
|
||||
std::optional<TypeIndex> AsofRowRefs::getTypeSize(const IColumn * asof_column, size_t & size)
|
||||
{
|
||||
if (typeid_cast<const ColumnVector<UInt32> *>(asof_column))
|
||||
TypeIndex idx = columnVectorDataType(asof_column);
|
||||
if (idx == TypeIndex::Nothing)
|
||||
idx = columnDecimalDataType(asof_column);
|
||||
|
||||
switch (idx)
|
||||
{
|
||||
case TypeIndex::UInt8:
|
||||
size = sizeof(UInt8);
|
||||
return idx;
|
||||
case TypeIndex::UInt16:
|
||||
size = sizeof(UInt16);
|
||||
return idx;
|
||||
case TypeIndex::UInt32:
|
||||
size = sizeof(UInt32);
|
||||
return Type::keyu32;
|
||||
}
|
||||
else if (typeid_cast<const ColumnVector<UInt64> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::UInt64:
|
||||
size = sizeof(UInt64);
|
||||
return Type::keyu64;
|
||||
}
|
||||
else if (typeid_cast<const ColumnVector<Int32> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::Int8:
|
||||
size = sizeof(Int8);
|
||||
return idx;
|
||||
case TypeIndex::Int16:
|
||||
size = sizeof(Int16);
|
||||
return idx;
|
||||
case TypeIndex::Int32:
|
||||
size = sizeof(Int32);
|
||||
return Type::keyi32;
|
||||
}
|
||||
else if (typeid_cast<const ColumnVector<Int64> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::Int64:
|
||||
size = sizeof(Int64);
|
||||
return Type::keyi64;
|
||||
}
|
||||
else if (typeid_cast<const ColumnVector<Float32> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
//case TypeIndex::Int128:
|
||||
case TypeIndex::Float32:
|
||||
size = sizeof(Float32);
|
||||
return Type::keyf32;
|
||||
}
|
||||
else if (typeid_cast<const ColumnVector<Float64> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::Float64:
|
||||
size = sizeof(Float64);
|
||||
return Type::keyf64;
|
||||
}
|
||||
else if (typeid_cast<const ColumnDecimal<Decimal32> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::Decimal32:
|
||||
size = sizeof(Decimal32);
|
||||
return Type::keyDecimal32;
|
||||
}
|
||||
else if (typeid_cast<const ColumnDecimal<Decimal64> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::Decimal64:
|
||||
size = sizeof(Decimal64);
|
||||
return Type::keyDecimal64;
|
||||
}
|
||||
else if (typeid_cast<const ColumnDecimal<Decimal128> *>(asof_column))
|
||||
{
|
||||
return idx;
|
||||
case TypeIndex::Decimal128:
|
||||
size = sizeof(Decimal128);
|
||||
return Type::keyDecimal128;
|
||||
return idx;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
size = 0;
|
||||
|
@ -216,8 +216,12 @@ public:
|
||||
};
|
||||
|
||||
using Lookups = std::variant<
|
||||
Entry<UInt8>::LookupPtr,
|
||||
Entry<UInt16>::LookupPtr,
|
||||
Entry<UInt32>::LookupPtr,
|
||||
Entry<UInt64>::LookupPtr,
|
||||
Entry<Int8>::LookupPtr,
|
||||
Entry<Int16>::LookupPtr,
|
||||
Entry<Int32>::LookupPtr,
|
||||
Entry<Int64>::LookupPtr,
|
||||
Entry<Float32>::LookupPtr,
|
||||
@ -226,29 +230,16 @@ public:
|
||||
Entry<Decimal64>::LookupPtr,
|
||||
Entry<Decimal128>::LookupPtr>;
|
||||
|
||||
enum class Type
|
||||
{
|
||||
keyu32,
|
||||
keyu64,
|
||||
keyi32,
|
||||
keyi64,
|
||||
keyf32,
|
||||
keyf64,
|
||||
keyDecimal32,
|
||||
keyDecimal64,
|
||||
keyDecimal128,
|
||||
};
|
||||
|
||||
AsofRowRefs() {}
|
||||
AsofRowRefs(Type t);
|
||||
AsofRowRefs(TypeIndex t);
|
||||
|
||||
static std::optional<Type> getTypeSize(const IColumn * asof_column, size_t & type_size);
|
||||
static std::optional<TypeIndex> getTypeSize(const IColumn * asof_column, size_t & type_size);
|
||||
|
||||
// This will be synchronized by the rwlock mutex in Join.h
|
||||
void insert(Type type, const IColumn * asof_column, const Block * block, size_t row_num);
|
||||
void insert(TypeIndex type, const IColumn * asof_column, const Block * block, size_t row_num);
|
||||
|
||||
// This will internally synchronize
|
||||
const RowRef * findAsof(Type type, ASOF::Inequality inequality, const IColumn * asof_column, size_t row_num) const;
|
||||
const RowRef * findAsof(TypeIndex type, ASOF::Inequality inequality, const IColumn * asof_column, size_t row_num) const;
|
||||
|
||||
private:
|
||||
// Lookups can be stored in a HashTable because it is memmovable
|
||||
|
13
tests/queries/0_stateless/01139_asof_join_types.reference
Normal file
13
tests/queries/0_stateless/01139_asof_join_types.reference
Normal file
@ -0,0 +1,13 @@
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 1
|
||||
0 0000-00-00
|
||||
0 0000-00-00 00:00:00
|
18
tests/queries/0_stateless/01139_asof_join_types.sql
Normal file
18
tests/queries/0_stateless/01139_asof_join_types.sql
Normal file
@ -0,0 +1,18 @@
|
||||
select * from (select 0 as k, toInt8(1) as v) t1 asof join (select 0 as k, toInt8(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toInt16(1) as v) t1 asof join (select 0 as k, toInt16(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toInt32(1) as v) t1 asof join (select 0 as k, toInt32(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toInt64(1) as v) t1 asof join (select 0 as k, toInt64(0) as v) t2 using(k, v);
|
||||
|
||||
select * from (select 0 as k, toUInt8(1) as v) t1 asof join (select 0 as k, toUInt8(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toUInt16(1) as v) t1 asof join (select 0 as k, toUInt16(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toUInt32(1) as v) t1 asof join (select 0 as k, toUInt32(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toUInt64(1) as v) t1 asof join (select 0 as k, toUInt64(0) as v) t2 using(k, v);
|
||||
|
||||
select * from (select 0 as k, toDecimal32(1, 0) as v) t1 asof join (select 0 as k, toDecimal32(0, 0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toDecimal64(1, 0) as v) t1 asof join (select 0 as k, toDecimal64(0, 0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toDecimal128(1, 0) as v) t1 asof join (select 0 as k, toDecimal128(0, 0) as v) t2 using(k, v);
|
||||
|
||||
select * from (select 0 as k, toDate(0) as v) t1 asof join (select 0 as k, toDate(0) as v) t2 using(k, v);
|
||||
select * from (select 0 as k, toDateTime(0) as v) t1 asof join (select 0 as k, toDateTime(0) as v) t2 using(k, v);
|
||||
|
||||
select * from (select 0 as k, 'x' as v) t1 asof join (select 0 as k, 'x' as v) t2 using(k, v); -- { serverError 169 }
|
Loading…
Reference in New Issue
Block a user