Added Field type AggregateFunctionState.

This commit is contained in:
Nikolai Kochetov 2019-02-11 14:19:56 +03:00
parent 17ec1b08e6
commit 9787b3a1ee
5 changed files with 91 additions and 7 deletions

View File

@ -260,9 +260,9 @@ MutableColumnPtr ColumnAggregateFunction::cloneEmpty() const
Field ColumnAggregateFunction::operator[](size_t n) const
{
Field field = String();
Field field = AggregateFunctionStateData();
{
WriteBufferFromString buffer(field.get<String &>());
WriteBufferFromString buffer(field.get<AggregateFunctionStateData &>().toUnderType());
func->serialize(data[n], buffer);
}
return field;
@ -272,7 +272,7 @@ void ColumnAggregateFunction::get(size_t n, Field & res) const
{
res = String();
{
WriteBufferFromString buffer(res.get<String &>());
WriteBufferFromString buffer(res.get<AggregateFunctionStateData &>().toUnderType());
func->serialize(data[n], buffer);
}
}
@ -343,7 +343,7 @@ void ColumnAggregateFunction::insert(const Field & x)
ensureOwnership();
Arena & arena = createOrGetArena();
pushBackAndCreateState(data, arena, func.get());
ReadBufferFromString read_buffer(x.get<const String &>());
ReadBufferFromString read_buffer(x.get<const AggregateFunctionStateData &>().toUnderType());
func->deserialize(data.back(), read_buffer, &arena);
}
@ -465,12 +465,12 @@ void ColumnAggregateFunction::getExtremes(Field & min, Field & max) const
AlignedBuffer place_buffer(func->sizeOfData(), func->alignOfData());
AggregateDataPtr place = place_buffer.data();
String serialized;
AggregateFunctionStateData serialized;
func->create(place);
try
{
WriteBufferFromString buffer(serialized);
WriteBufferFromString buffer(serialized.toUnderType());
func->serialize(place, buffer);
}
catch (...)

View File

@ -89,6 +89,12 @@ String FieldVisitorDump::operator() (const Tuple & x_def) const
return wb.str();
}
String FieldVisitorDump::operator() (const AggregateFunctionStateData & x) const
{
WriteBufferFromOwnString wb;
writeQuoted(x, wb);
return wb.str();
}
/** In contrast to writeFloatText (and writeQuoted),
* even if number looks like integer after formatting, prints decimal point nevertheless (for example, Float64(1) is printed as 1.).
@ -121,6 +127,7 @@ String FieldVisitorToString::operator() (const DecimalField<Decimal32> & x) cons
String FieldVisitorToString::operator() (const DecimalField<Decimal64> & x) const { return formatQuoted(x); }
String FieldVisitorToString::operator() (const DecimalField<Decimal128> & x) const { return formatQuoted(x); }
String FieldVisitorToString::operator() (const UInt128 & x) const { return formatQuoted(UUID(x)); }
String FieldVisitorToString::operator() (const AggregateFunctionStateData & x) const { return formatQuoted(x); }
String FieldVisitorToString::operator() (const Array & x) const
{
@ -231,5 +238,13 @@ void FieldVisitorHash::operator() (const DecimalField<Decimal128> & x) const
hash.update(x);
}
void FieldVisitorHash::operator() (const AggregateFunctionStateData & x) const
{
UInt8 type = Field::Types::AggregateFunctionState;
hash.update(type);
hash.update(x.toUnderType().size());
hash.update(x.toUnderType().data(), x.toUnderType().size());
}
}

View File

@ -138,6 +138,7 @@ public:
String operator() (const DecimalField<Decimal32> & x) const;
String operator() (const DecimalField<Decimal64> & x) const;
String operator() (const DecimalField<Decimal128> & x) const;
String operator() (const AggregateFunctionStateData & x) const;
};
@ -156,6 +157,7 @@ public:
String operator() (const DecimalField<Decimal32> & x) const;
String operator() (const DecimalField<Decimal64> & x) const;
String operator() (const DecimalField<Decimal128> & x) const;
String operator() (const AggregateFunctionStateData & x) const;
};
@ -201,6 +203,11 @@ public:
else
return x.getValue() / x.getScaleMultiplier();
}
T operator() (const AggregateFunctionStateData &) const
{
throw Exception("Cannot convert String to " + demangle(typeid(T).name()), ErrorCodes::CANNOT_CONVERT_TYPE);
}
};
@ -222,6 +229,7 @@ public:
void operator() (const DecimalField<Decimal32> & x) const;
void operator() (const DecimalField<Decimal64> & x) const;
void operator() (const DecimalField<Decimal128> & x) const;
void operator() (const AggregateFunctionStateData & x) const;
};
@ -321,6 +329,16 @@ public:
template <typename T> bool operator() (const Int64 & l, const DecimalField<T> & r) const { return DecimalField<Decimal128>(l, 0) == r; }
template <typename T> bool operator() (const Float64 & l, const DecimalField<T> & r) const { return cantCompare(l, r); }
template <typename T>
bool operator() (const AggregateFunctionStateData & l, const T & r) const
{
if constexpr (std::is_same_v<T, AggregateFunctionStateData>)
return l == r;
if constexpr (std::is_same_v<T, UInt128>)
return stringToUUID(l.toUnderType()) == r;
return cantCompare(l, r);
}
private:
template <typename T, typename U>
bool cantCompare(const T &, const U &) const
@ -419,6 +437,16 @@ public:
template <typename T> bool operator() (const Int64 & l, const DecimalField<T> & r) const { return DecimalField<Decimal128>(l, 0) < r; }
template <typename T> bool operator() (const Float64 &, const DecimalField<T> &) const { return false; }
template <typename T>
bool operator() (const AggregateFunctionStateData & l, const T & r) const
{
if constexpr (std::is_same_v<T, AggregateFunctionStateData>)
return l < r;
if constexpr (std::is_same_v<T, UInt128>)
return stringToUUID(l.toUnderType()) < r;
return cantCompare(l, r);
}
private:
template <typename T, typename U>
bool cantCompare(const T &, const U &) const
@ -447,6 +475,7 @@ public:
bool operator() (String &) const { throw Exception("Cannot sum Strings", ErrorCodes::LOGICAL_ERROR); }
bool operator() (Array &) const { throw Exception("Cannot sum Arrays", ErrorCodes::LOGICAL_ERROR); }
bool operator() (UInt128 &) const { throw Exception("Cannot sum UUIDs", ErrorCodes::LOGICAL_ERROR); }
bool operator() (AggregateFunctionStateData &) const { throw Exception("Cannot sum AggregateFunctionStates", ErrorCodes::LOGICAL_ERROR); }
template <typename T>
bool operator() (DecimalField<T> & x) const

View File

@ -75,6 +75,13 @@ namespace DB
x.push_back(value);
break;
}
case Field::Types::AggregateFunctionState:
{
AggregateFunctionStateData value;
DB::readStringBinary(value, buf);
x.push_back(value);
break;
}
}
}
}
@ -128,6 +135,11 @@ namespace DB
DB::writeBinary(get<Tuple>(*it), buf);
break;
}
case Field::Types::AggregateFunctionState:
{
DB::writeStringBinary(get<AggregateFunctionStateData>(*it), buf);
break;
}
}
}
}
@ -209,6 +221,13 @@ namespace DB
x.push_back(value);
break;
}
case Field::Types::AggregateFunctionState:
{
AggregateFunctionStateData value;
DB::readStringBinary(value, buf);
x.push_back(value);
break;
}
}
}
}
@ -262,6 +281,11 @@ namespace DB
DB::writeBinary(get<Tuple>(*it), buf);
break;
}
case Field::Types::AggregateFunctionState:
{
DB::writeStringBinary(get<AggregateFunctionStateData>(*it), buf);
break;
}
}
}
}

View File

@ -30,6 +30,9 @@ using Array = std::vector<Field>;
using TupleBackend = std::vector<Field>;
STRONG_TYPEDEF(TupleBackend, Tuple) /// Array and Tuple are different types with equal representation inside Field.
using AggregateFunctionStateDataBackend = String;
STRONG_TYPEDEF(AggregateFunctionStateDataBackend, AggregateFunctionStateData)
template <typename T> bool decimalEqual(T x, T y, UInt32 x_scale, UInt32 y_scale);
template <typename T> bool decimalLess(T x, T y, UInt32 x_scale, UInt32 y_scale);
template <typename T> bool decimalLessOrEqual(T x, T y, UInt32 x_scale, UInt32 y_scale);
@ -131,6 +134,7 @@ public:
Decimal32 = 19,
Decimal64 = 20,
Decimal128 = 21,
AggregateFunctionState = 22,
};
static const int MIN_NON_POD = 16;
@ -151,6 +155,7 @@ public:
case Decimal32: return "Decimal32";
case Decimal64: return "Decimal64";
case Decimal128: return "Decimal128";
case AggregateFunctionState: return "AggregateFunctionState";
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -325,6 +330,7 @@ public:
case Types::Decimal32: return get<DecimalField<Decimal32>>() < rhs.get<DecimalField<Decimal32>>();
case Types::Decimal64: return get<DecimalField<Decimal64>>() < rhs.get<DecimalField<Decimal64>>();
case Types::Decimal128: return get<DecimalField<Decimal128>>() < rhs.get<DecimalField<Decimal128>>();
case Types::AggregateFunctionState: return get<AggregateFunctionStateData>() < rhs.get<AggregateFunctionStateData>();
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -356,6 +362,7 @@ public:
case Types::Decimal32: return get<DecimalField<Decimal32>>() <= rhs.get<DecimalField<Decimal32>>();
case Types::Decimal64: return get<DecimalField<Decimal64>>() <= rhs.get<DecimalField<Decimal64>>();
case Types::Decimal128: return get<DecimalField<Decimal128>>() <= rhs.get<DecimalField<Decimal128>>();
case Types::AggregateFunctionState: return get<AggregateFunctionStateData>() <= rhs.get<AggregateFunctionStateData>();
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -385,6 +392,7 @@ public:
case Types::Decimal32: return get<DecimalField<Decimal32>>() == rhs.get<DecimalField<Decimal32>>();
case Types::Decimal64: return get<DecimalField<Decimal64>>() == rhs.get<DecimalField<Decimal64>>();
case Types::Decimal128: return get<DecimalField<Decimal128>>() == rhs.get<DecimalField<Decimal128>>();
case Types::AggregateFunctionState: return get<AggregateFunctionStateData>() == rhs.get<AggregateFunctionStateData>();
}
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
@ -398,7 +406,7 @@ public:
private:
std::aligned_union_t<DBMS_MIN_FIELD_SIZE - sizeof(Types::Which),
Null, UInt64, UInt128, Int64, Int128, Float64, String, Array, Tuple,
DecimalField<Decimal32>, DecimalField<Decimal64>, DecimalField<Decimal128>
DecimalField<Decimal32>, DecimalField<Decimal64>, DecimalField<Decimal128>, AggregateFunctionStateData
> storage;
Types::Which which;
@ -449,6 +457,7 @@ private:
case Types::Decimal32: f(field.template get<DecimalField<Decimal32>>()); return;
case Types::Decimal64: f(field.template get<DecimalField<Decimal64>>()); return;
case Types::Decimal128: f(field.template get<DecimalField<Decimal128>>()); return;
case Types::AggregateFunctionState: f(field.template get<AggregateFunctionStateData>()); return;
}
}
@ -501,6 +510,9 @@ private:
case Types::Tuple:
destroy<Tuple>();
break;
case Types::AggregateFunctionState:
destroy<AggregateFunctionStateData>();
break;
default:
break;
}
@ -531,6 +543,7 @@ template <> struct Field::TypeToEnum<Tuple> { static const Types::Which value
template <> struct Field::TypeToEnum<DecimalField<Decimal32>>{ static const Types::Which value = Types::Decimal32; };
template <> struct Field::TypeToEnum<DecimalField<Decimal64>>{ static const Types::Which value = Types::Decimal64; };
template <> struct Field::TypeToEnum<DecimalField<Decimal128>>{ static const Types::Which value = Types::Decimal128; };
template <> struct Field::TypeToEnum<AggregateFunctionStateData>{ static const Types::Which value = Types::AggregateFunctionState; };
template <> struct Field::EnumToType<Field::Types::Null> { using Type = Null; };
template <> struct Field::EnumToType<Field::Types::UInt64> { using Type = UInt64; };
@ -544,6 +557,7 @@ template <> struct Field::EnumToType<Field::Types::Tuple> { using Type = Tuple
template <> struct Field::EnumToType<Field::Types::Decimal32> { using Type = DecimalField<Decimal32>; };
template <> struct Field::EnumToType<Field::Types::Decimal64> { using Type = DecimalField<Decimal64>; };
template <> struct Field::EnumToType<Field::Types::Decimal128> { using Type = DecimalField<Decimal128>; };
template <> struct Field::EnumToType<Field::Types::AggregateFunctionState> { using Type = DecimalField<AggregateFunctionStateData>; };
template <typename T>
@ -616,6 +630,8 @@ template <> struct NearestFieldTypeImpl<Tuple> { using Type = Tuple; };
template <> struct NearestFieldTypeImpl<bool> { using Type = UInt64; };
template <> struct NearestFieldTypeImpl<Null> { using Type = Null; };
template <> struct NearestFieldTypeImpl<AggregateFunctionStateData> { using Type = AggregateFunctionStateData; };
template <typename T>
using NearestFieldType = typename NearestFieldTypeImpl<T>::Type;