Skip to content

Commit e6104bc

Browse files
Backport #72392 to 24.11: Fix data race in Squashing with LowCardinality
1 parent 2b4a4fe commit e6104bc

1 file changed

Lines changed: 20 additions & 0 deletions

File tree

src/Columns/ColumnLowCardinality.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,26 @@ class ColumnLowCardinality final : public COWHelper<IColumnHelper<ColumnLowCardi
190190
callback(dictionary.getColumnUniquePtr());
191191
}
192192

193+
void forEachSubcolumnRecursively(RecursiveColumnCallback callback) const override
194+
{
195+
/** It is important to have both const and non-const versions here.
196+
* The behavior of ColumnUnique::forEachSubcolumnRecursively differs between const and non-const versions.
197+
* The non-const version will update a field in ColumnUnique.
198+
* In the meantime, the default implementation IColumn::forEachSubcolumnRecursively uses const_cast,
199+
* so when the const version is called, the field will still be mutated.
200+
* This can lead to a data race if constness is expected.
201+
*/
202+
callback(*idx.getPositionsPtr());
203+
idx.getPositionsPtr()->forEachSubcolumnRecursively(callback);
204+
205+
/// Column doesn't own dictionary if it's shared.
206+
if (!dictionary.isShared())
207+
{
208+
callback(*dictionary.getColumnUniquePtr());
209+
dictionary.getColumnUniquePtr()->forEachSubcolumnRecursively(callback);
210+
}
211+
}
212+
193213
void forEachSubcolumnRecursively(RecursiveMutableColumnCallback callback) override
194214
{
195215
callback(*idx.getPositionsPtr());

0 commit comments

Comments
 (0)