more types in ASOF JOIN (#11301)

This commit is contained in:
Artem Zuikov 2020-06-01 12:38:46 +03:00 committed by GitHub
parent c22e8f6b9b
commit 9028a25f3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 150 additions and 76 deletions

View File

@ -333,6 +333,17 @@ void ColumnDecimal<T>::getExtremes(Field & min, Field & max) const
max = NearestFieldType<T>(cur_max, scale); 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<Decimal32>;
template class ColumnDecimal<Decimal64>; template class ColumnDecimal<Decimal64>;
template class ColumnDecimal<Decimal128>; template class ColumnDecimal<Decimal128>;

View File

@ -197,4 +197,6 @@ ColumnPtr ColumnDecimal<T>::indexImpl(const PaddedPODArray<Type> & indexes, size
return res; return res;
} }
TypeIndex columnDecimalDataType(const IColumn * column);
} }

View File

@ -517,6 +517,33 @@ void ColumnVector<T>::getExtremes(Field & min, Field & max) const
max = NearestFieldType<T>(cur_max); 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. /// Explicit template instantiations - to avoid code bloat in headers.
template class ColumnVector<UInt8>; template class ColumnVector<UInt8>;
template class ColumnVector<UInt16>; template class ColumnVector<UInt16>;

View File

@ -320,4 +320,6 @@ ColumnPtr ColumnVector<T>::indexImpl(const PaddedPODArray<Type> & indexes, size_
return res; return res;
} }
TypeIndex columnVectorDataType(const IColumn * column);
} }

View File

@ -192,7 +192,7 @@ public:
ASTTableJoin::Kind getKind() const { return kind; } ASTTableJoin::Kind getKind() const { return kind; }
ASTTableJoin::Strictness getStrictness() const { return strictness; } 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; } ASOF::Inequality getAsofInequality() const { return asof_inequality; }
bool anyTakeLastRow() const { return any_take_last_row; } 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_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 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 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; ASOF::Inequality asof_inequality;
/// Right table data. StorageJoin shares it between many Join objects. /// Right table data. StorageJoin shares it between many Join objects.

View File

@ -17,19 +17,25 @@ namespace
/// maps enum values to types /// maps enum values to types
template <typename F> template <typename F>
void callWithType(AsofRowRefs::Type which, F && f) void callWithType(TypeIndex which, F && f)
{ {
switch (which) switch (which)
{ {
case AsofRowRefs::Type::keyu32: return f(UInt32()); case TypeIndex::UInt8: return f(UInt8());
case AsofRowRefs::Type::keyu64: return f(UInt64()); case TypeIndex::UInt16: return f(UInt16());
case AsofRowRefs::Type::keyi32: return f(Int32()); case TypeIndex::UInt32: return f(UInt32());
case AsofRowRefs::Type::keyi64: return f(Int64()); case TypeIndex::UInt64: return f(UInt64());
case AsofRowRefs::Type::keyf32: return f(Float32()); case TypeIndex::Int8: return f(Int8());
case AsofRowRefs::Type::keyf64: return f(Float64()); case TypeIndex::Int16: return f(Int16());
case AsofRowRefs::Type::keyDecimal32: return f(Decimal32()); case TypeIndex::Int32: return f(Int32());
case AsofRowRefs::Type::keyDecimal64: return f(Decimal64()); case TypeIndex::Int64: return f(Int64());
case AsofRowRefs::Type::keyDecimal128: return f(Decimal128()); 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(); __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) auto call = [&](const auto & t)
{ {
@ -50,7 +56,7 @@ AsofRowRefs::AsofRowRefs(Type type)
callWithType(type, call); 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) auto call = [&](const auto & t)
{ {
@ -68,7 +74,7 @@ void AsofRowRefs::insert(Type type, const IColumn * asof_column, const Block * b
callWithType(type, call); 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; const RowRef * out = nullptr;
@ -96,52 +102,56 @@ const RowRef * AsofRowRefs::findAsof(Type type, ASOF::Inequality inequality, con
return out; 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); size = sizeof(UInt32);
return Type::keyu32; return idx;
} case TypeIndex::UInt64:
else if (typeid_cast<const ColumnVector<UInt64> *>(asof_column))
{
size = sizeof(UInt64); size = sizeof(UInt64);
return Type::keyu64; return idx;
} case TypeIndex::Int8:
else if (typeid_cast<const ColumnVector<Int32> *>(asof_column)) size = sizeof(Int8);
{ return idx;
case TypeIndex::Int16:
size = sizeof(Int16);
return idx;
case TypeIndex::Int32:
size = sizeof(Int32); size = sizeof(Int32);
return Type::keyi32; return idx;
} case TypeIndex::Int64:
else if (typeid_cast<const ColumnVector<Int64> *>(asof_column))
{
size = sizeof(Int64); size = sizeof(Int64);
return Type::keyi64; return idx;
} //case TypeIndex::Int128:
else if (typeid_cast<const ColumnVector<Float32> *>(asof_column)) case TypeIndex::Float32:
{
size = sizeof(Float32); size = sizeof(Float32);
return Type::keyf32; return idx;
} case TypeIndex::Float64:
else if (typeid_cast<const ColumnVector<Float64> *>(asof_column))
{
size = sizeof(Float64); size = sizeof(Float64);
return Type::keyf64; return idx;
} case TypeIndex::Decimal32:
else if (typeid_cast<const ColumnDecimal<Decimal32> *>(asof_column))
{
size = sizeof(Decimal32); size = sizeof(Decimal32);
return Type::keyDecimal32; return idx;
} case TypeIndex::Decimal64:
else if (typeid_cast<const ColumnDecimal<Decimal64> *>(asof_column))
{
size = sizeof(Decimal64); size = sizeof(Decimal64);
return Type::keyDecimal64; return idx;
} case TypeIndex::Decimal128:
else if (typeid_cast<const ColumnDecimal<Decimal128> *>(asof_column))
{
size = sizeof(Decimal128); size = sizeof(Decimal128);
return Type::keyDecimal128; return idx;
default:
break;
} }
size = 0; size = 0;

View File

@ -216,8 +216,12 @@ public:
}; };
using Lookups = std::variant< using Lookups = std::variant<
Entry<UInt8>::LookupPtr,
Entry<UInt16>::LookupPtr,
Entry<UInt32>::LookupPtr, Entry<UInt32>::LookupPtr,
Entry<UInt64>::LookupPtr, Entry<UInt64>::LookupPtr,
Entry<Int8>::LookupPtr,
Entry<Int16>::LookupPtr,
Entry<Int32>::LookupPtr, Entry<Int32>::LookupPtr,
Entry<Int64>::LookupPtr, Entry<Int64>::LookupPtr,
Entry<Float32>::LookupPtr, Entry<Float32>::LookupPtr,
@ -226,29 +230,16 @@ public:
Entry<Decimal64>::LookupPtr, Entry<Decimal64>::LookupPtr,
Entry<Decimal128>::LookupPtr>; Entry<Decimal128>::LookupPtr>;
enum class Type
{
keyu32,
keyu64,
keyi32,
keyi64,
keyf32,
keyf64,
keyDecimal32,
keyDecimal64,
keyDecimal128,
};
AsofRowRefs() {} 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 // 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 // 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: private:
// Lookups can be stored in a HashTable because it is memmovable // Lookups can be stored in a HashTable because it is memmovable

View 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

View 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 }