diff --git a/src/AggregateFunctions/ReservoirSamplerDeterministic.h b/src/AggregateFunctions/ReservoirSamplerDeterministic.h index 3013a17e1ca..5cf97ae0f85 100644 --- a/src/AggregateFunctions/ReservoirSamplerDeterministic.h +++ b/src/AggregateFunctions/ReservoirSamplerDeterministic.h @@ -13,6 +13,7 @@ #include #include + namespace DB { namespace ErrorCodes @@ -162,6 +163,11 @@ public: sorted = false; } +#if !__clang__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wclass-memaccess" +#endif + void write(DB::WriteBuffer & buf) const { size_t size = samples.size(); @@ -169,9 +175,26 @@ public: DB::writeIntBinary(total_values, buf); for (size_t i = 0; i < size; ++i) - DB::writePODBinary(samples[i], buf); + { + /// There was a mistake in this function. + /// Instead of correctly serializing the elements, + /// it was writing them with uninitialized padding. + /// Here we ensure that padding is zero without changing the protocol. + /// TODO: After implementation of "versioning aggregate function state", + /// change the serialization format. + + Element elem; + memset(&elem, 0, sizeof(elem)); + elem = samples[i]; + + DB::writePODBinary(elem, buf); + } } +#if !__clang__ +#pragma GCC diagnostic pop +#endif + private: /// We allocate some memory on the stack to avoid allocations when there are many objects with a small number of elements. using Element = std::pair; diff --git a/tests/queries/0_stateless/01779_quantile_deterministic_msan.reference b/tests/queries/0_stateless/01779_quantile_deterministic_msan.reference new file mode 100644 index 00000000000..b432de6ddb3 --- /dev/null +++ b/tests/queries/0_stateless/01779_quantile_deterministic_msan.reference @@ -0,0 +1 @@ +11447494982455782708 diff --git a/tests/queries/0_stateless/01779_quantile_deterministic_msan.sql b/tests/queries/0_stateless/01779_quantile_deterministic_msan.sql new file mode 100644 index 00000000000..ef4234da306 --- /dev/null +++ b/tests/queries/0_stateless/01779_quantile_deterministic_msan.sql @@ -0,0 +1 @@ +SELECT cityHash64(toString(quantileDeterministicState(number, sipHash64(number)))) FROM numbers(8193);