Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
619f011
Backport #95477 to 26.1: Revert "Revert "Fix schema mapping for dates""
robot-clickhouse Feb 10, 2026
ba8c99d
Merge pull request #96609 from ClickHouse/backport/26.1/95477
scanhex12 Feb 19, 2026
8efb1bd
Update autogenerated version to 26.1.3.52 and contributors
robot-clickhouse Feb 19, 2026
146dbcf
Backport #97282 to 26.1: Add additional validations of ColumnVariant …
robot-clickhouse Feb 19, 2026
fee8d65
Backport #97076 to 26.1: Fix partition pruning (indexes) for row poli…
robot-clickhouse Feb 19, 2026
1415fe6
Merge pull request #97409 from ClickHouse/backport/26.1/97076
clickhouse-gh[bot] Feb 19, 2026
f86e7fa
Merge pull request #97401 from ClickHouse/backport/26.1/97282
clickhouse-gh[bot] Feb 19, 2026
e81011d
Backport #97323 to 26.1: Remove TABLE_UUID_MISMATCH check for non-ana…
robot-clickhouse Feb 19, 2026
ac25e02
Backport #97264 to 26.1: Fix exception when reading .size subcolumn o…
robot-clickhouse Feb 20, 2026
dba26b8
Merge pull request #97440 from ClickHouse/backport/26.1/97323
clickhouse-gh[bot] Feb 20, 2026
67f798f
Merge pull request #97450 from ClickHouse/backport/26.1/97264
clickhouse-gh[bot] Feb 20, 2026
4b42cc9
Backport #97281 to 26.1: Fix SEGFAULT in supportsTrivialCountOptimiza…
robot-clickhouse Feb 20, 2026
389297a
Backport #96233 to 26.1: Do not try to load statistics when there is …
robot-clickhouse Feb 20, 2026
788c017
Merge pull request #97469 from ClickHouse/backport/26.1/97281
pamarcos Feb 20, 2026
7357fab
Merge pull request #97491 from ClickHouse/backport/26.1/96233
clickhouse-gh[bot] Feb 20, 2026
785bdd6
Backport #97484 to 26.1: Fix `ACCESS_DENIED` error for users when `op…
robot-clickhouse Feb 21, 2026
0ec9bbf
Merge pull request #97580 from ClickHouse/backport/26.1/97484
clickhouse-gh[bot] Feb 21, 2026
127fa3f
Backport #97583 to 26.1: Fix null pointer dereference in applyPatches…
robot-clickhouse Feb 22, 2026
9233026
Merge pull request #97603 from ClickHouse/backport/26.1/97583
clickhouse-gh[bot] Feb 22, 2026
23592f0
Backport #97493 to 26.1: Make convertToFullIfNeeded recursive for com…
robot-clickhouse Feb 22, 2026
e72d662
Backport #97647 to 26.1: Fix incorrect getSerializedValueSize for Col…
robot-clickhouse Feb 23, 2026
c95cf44
Backport #97413 to 26.1: Related to Nullable Tuples: Fix exception in…
robot-clickhouse Feb 23, 2026
0668747
Merge pull request #97697 from ClickHouse/backport/26.1/97413
clickhouse-gh[bot] Feb 23, 2026
ee0643d
Merge pull request #97689 from ClickHouse/backport/26.1/97647
nihalzp Feb 23, 2026
03016cb
Backport #97585 to 26.1: Fix crash in BaseSettings::readBinary
robot-clickhouse Feb 23, 2026
241f048
Backport #97582 to 26.1: Fix isNull/isNotNull exception with nested N…
robot-clickhouse Feb 23, 2026
a21643c
Merge pull request #97720 from ClickHouse/backport/26.1/97585
clickhouse-gh[bot] Feb 23, 2026
3509ba7
Merge pull request #97739 from ClickHouse/backport/26.1/97582
clickhouse-gh[bot] Feb 23, 2026
b654d40
Backport #97698 to 26.1: Correct the check for RPN length in skip ind…
robot-clickhouse Feb 23, 2026
e5c40a1
Backport #97620 to 26.1: fix filterPartsByVirtualColumns for constant…
robot-clickhouse Feb 23, 2026
18640d5
Backport #97019 to 26.1: Fix ColumnConst not materialized before squa…
robot-clickhouse Feb 23, 2026
629b488
Merge pull request #97757 from ClickHouse/backport/26.1/97620
clickhouse-gh[bot] Feb 23, 2026
6a9ef93
Merge pull request #97755 from ClickHouse/backport/26.1/97698
clickhouse-gh[bot] Feb 23, 2026
b661a5c
Merge pull request #97765 from ClickHouse/backport/26.1/97019
clickhouse-gh[bot] Feb 23, 2026
2ed3008
Backport #97654 to 26.1: Fix exception in concat with Variant contain…
robot-clickhouse Feb 23, 2026
5e197d3
Backport #97515 to 26.1: Fix reading Sparse column and its subcolumn …
robot-clickhouse Feb 23, 2026
71ac40a
Backport #97422 to 26.1: Fix applying setting type_json_allow_duplica…
robot-clickhouse Feb 23, 2026
db48a12
Merge pull request #97791 from ClickHouse/backport/26.1/97654
clickhouse-gh[bot] Feb 23, 2026
a5eb70b
Merge pull request #97809 from ClickHouse/backport/26.1/97422
Avogar Feb 24, 2026
0a2ebb5
Merge pull request #97799 from ClickHouse/backport/26.1/97515
Avogar Feb 24, 2026
b507e15
Merge pull request #97631 from ClickHouse/backport/26.1/97493
Avogar Feb 24, 2026
2cf5946
Backport #97538 to 26.1: Consider row policy for read in order optimi…
robot-clickhouse Feb 24, 2026
619d924
Merge pull request #97879 from ClickHouse/backport/26.1/97538
clickhouse-gh[bot] Feb 24, 2026
6c6f31c
Backport #97866 to 26.1: Handle unprocessed left blocks in `GraceHash…
robot-clickhouse Feb 25, 2026
46d34b4
Merge pull request #97917 from ClickHouse/backport/26.1/97866
clickhouse-gh[bot] Feb 25, 2026
1bba43c
Backport #97523 to 26.1: Fix logical error about missing stream durin…
robot-clickhouse Feb 25, 2026
b4533e7
Backport #97831 to 26.1: Fix LOGICAL_ERROR exceptions from recursive …
robot-clickhouse Feb 25, 2026
1e56ba7
Backport #97411 to 26.1: Fix: possible race condition on EXCHANGE TAB…
robot-clickhouse Feb 25, 2026
9fd224a
Merge pull request #97983 from ClickHouse/backport/26.1/97831
clickhouse-gh[bot] Feb 25, 2026
ce01a38
Merge pull request #97994 from ClickHouse/backport/26.1/97411
clickhouse-gh[bot] Feb 25, 2026
ba2a37a
Backport #97884 to 26.1: return user_name within AuthResult from the …
robot-clickhouse Feb 26, 2026
89172e8
Merge pull request #98008 from ClickHouse/backport/26.1/97884
clickhouse-gh[bot] Feb 26, 2026
27d27c0
Backport #97887 to 26.1: Fix data race in ZooKeeper client between se…
robot-clickhouse Feb 26, 2026
c3b41f0
Merge pull request #98061 from ClickHouse/backport/26.1/97887
pamarcos Feb 26, 2026
4bf2b7a
Backport #97832 to 26.1: Attribute the thread of Iceberg Iterator to …
robot-clickhouse Feb 26, 2026
8dc8299
Backport #97374 to 26.1: Add deferred filters info to EXPLAIN (in cas…
robot-clickhouse Feb 26, 2026
cce7173
Merge pull request #98090 from ClickHouse/backport/26.1/97832
clickhouse-gh[bot] Feb 26, 2026
13df364
Merge pull request #98110 from ClickHouse/backport/26.1/97374
clickhouse-gh[bot] Feb 26, 2026
4d3a06f
Backport #97987 to 26.1: Fix Keeper data loss using Azure Blob Storag…
robot-clickhouse Feb 27, 2026
d6e28c1
Backport #98147 to 26.1: Fix segfault in outer-to-inner join optimiza…
robot-clickhouse Feb 27, 2026
79d77e0
Merge pull request #98174 from ClickHouse/backport/26.1/97987
antonio2368 Feb 27, 2026
1edaeb2
Merge pull request #97958 from ClickHouse/backport/26.1/97523
Avogar Feb 27, 2026
18381fd
Backport #97778 to 26.1: Fix reading empty granules in advanced share…
robot-clickhouse Feb 27, 2026
0d36524
Merge pull request #98223 from ClickHouse/backport/26.1/97778
clickhouse-gh[bot] Feb 27, 2026
49f3264
Merge pull request #98198 from ClickHouse/backport/26.1/98147
vdimir Feb 27, 2026
e59d9dd
Backport #98246 to 26.1: Skip changelog checks for release PRs in CI
robot-clickhouse Feb 27, 2026
2651c9b
Merge pull request #98260 from ClickHouse/backport/26.1/98246
clickhouse-gh[bot] Feb 27, 2026
ef66bd5
Backport #98097 to 26.1: Fix incorrect result of FINAL queries when m…
robot-clickhouse Feb 28, 2026
94d63f0
Merge pull request #98308 from ClickHouse/backport/26.1/98097
clickhouse-gh[bot] Feb 28, 2026
aa42c1a
merge 26.1.4
zvonand Mar 16, 2026
7c33346
fix build
zvonand Mar 16, 2026
585f70b
fix iceberg date32 type
zvonand Mar 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ci/jobs/scripts/workflow_hooks/pr_body_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ def check_changelog_entry(category, pr_body: str) -> str:
if not title or not body:
print("WARNING: Failed to get PR title or body, read from environment")
body = Info().pr_body
labels = Info().pr_labels

if "release" in labels or "release-lts" in labels:
print("NOTE: Release PR detected, skipping changelog entry check")
sys.exit(0)

error, category = get_category(body)
if error or not category:
Expand Down
3 changes: 3 additions & 0 deletions ci/jobs/scripts/workflow_hooks/pr_labels_and_category.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ def check_labels(category, info):

if __name__ == "__main__":
info = Info()
if Labels.RELEASE in info.pr_labels or Labels.RELEASE_LTS in info.pr_labels:
print("NOTE: Release PR detected, skipping changelog category check")
sys.exit(0)
error, category = get_category(info.pr_body)
if not category or error:
print(f"ERROR: {error}")
Expand Down
10 changes: 5 additions & 5 deletions cmake/autogenerated_versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

# NOTE: VERSION_REVISION has nothing common with DBMS_TCP_PROTOCOL_VERSION,
# only DBMS_TCP_PROTOCOL_VERSION should be incremented on protocol changes.
SET(VERSION_REVISION 54508)
SET(VERSION_REVISION 54509)
SET(VERSION_MAJOR 26)
SET(VERSION_MINOR 1)
SET(VERSION_PATCH 3)
SET(VERSION_GITHASH 53779390caa67a65a2368cdbb7533ed925608ba9)
SET(VERSION_DESCRIBE v26.1.3.20001.altinityantalya)
SET(VERSION_STRING 26.1.3.20001.altinityantalya)
SET(VERSION_PATCH 4)
SET(VERSION_GITHASH 5549f2acae95c6d627654f50e212a85d059a55f9)
SET(VERSION_DESCRIBE v26.1.4.20001.altinityantalya)
SET(VERSION_STRING 26.1.4.20001.altinityantalya)
# end of autochange

SET(VERSION_TWEAK 20001)
Expand Down
2 changes: 1 addition & 1 deletion src/Access/IAccessStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ std::optional<AuthResult> IAccessStorage::authenticateImpl(
{
if (auto user = tryRead<User>(*id))
{
AuthResult auth_result { .user_id = *id };
AuthResult auth_result { .user_id = *id, .user_name = credentials.getUserName() };
if (!isAddressAllowed(*user, address))
throwAddressNotAllowed(address);

Expand Down
3 changes: 3 additions & 0 deletions src/Access/IAccessStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ struct AuthResult
/// Session settings received from authentication server (if any)
SettingsChanges settings{};
AuthenticationData authentication_data {};
/// Username determined by the access storage during authentication,
/// should be treated as the authenticated user name
String user_name;
};

/// Contains entities, i.e. instances of classes derived from IAccessEntity.
Expand Down
2 changes: 1 addition & 1 deletion src/Access/LDAPAccessStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ std::optional<AuthResult> LDAPAccessStorage::authenticateImpl(
}

if (id)
return AuthResult{ .user_id = *id, .authentication_data = AuthenticationData(AuthenticationType::LDAP) };
return AuthResult{ .user_id = *id, .authentication_data = AuthenticationData(AuthenticationType::LDAP), .user_name = credentials.getUserName() };
return std::nullopt;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Access/TokenAccessStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ std::optional<AuthResult> TokenAccessStorage::authenticateImpl(
}

if (id)
return AuthResult{ .user_id = *id, .authentication_data = AuthenticationData(AuthenticationType::JWT) };
return AuthResult{ .user_id = *id, .authentication_data = AuthenticationData(AuthenticationType::JWT), .user_name = credentials.getUserName() };
return std::nullopt;
}

Expand Down
22 changes: 22 additions & 0 deletions src/Analyzer/Passes/FunctionToSubcolumnsPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,18 @@ std::map<std::pair<TypeIndex, String>, NodeToSubcolumnTransformer> node_transfor
NameAndTypePair column{ctx.column.name + ".null", std::make_shared<DataTypeUInt8>()};
if (sourceHasColumn(ctx.column_source, column.name) || !canOptimizeToSubcolumn(ctx.column_source, column.name))
return;

/// For nested Nullable types (e.g. Nullable(Tuple(... Nullable(T) ...))),
/// the .null subcolumn in storage is Nullable(UInt8), not UInt8.
/// Using it with a hardcoded UInt8 type causes a type mismatch at runtime.
if (auto * table_node = ctx.column_source->as<TableNode>())
{
auto actual = table_node->getStorageSnapshot()->tryGetColumn(
GetColumnsOptions(GetColumnsOptions::All).withRegularSubcolumns(), column.name);
if (actual && actual->type->isNullable())
return;
}

node = std::make_shared<ColumnNode>(column, ctx.column_source);
},
},
Expand All @@ -377,6 +389,16 @@ std::map<std::pair<TypeIndex, String>, NodeToSubcolumnTransformer> node_transfor
NameAndTypePair column{ctx.column.name + ".null", std::make_shared<DataTypeUInt8>()};
if (sourceHasColumn(ctx.column_source, column.name) || !canOptimizeToSubcolumn(ctx.column_source, column.name))
return;

/// Same guard as isNull above: nested Nullable .null subcolumn may itself be Nullable.
if (auto * table_node = ctx.column_source->as<TableNode>())
{
auto actual = table_node->getStorageSnapshot()->tryGetColumn(
GetColumnsOptions(GetColumnsOptions::All).withRegularSubcolumns(), column.name);
if (actual && actual->type->isNullable())
return;
}

auto & function_arguments_nodes = function_node.getArguments().getNodes();

function_arguments_nodes = {std::make_shared<ColumnNode>(column, ctx.column_source)};
Expand Down
8 changes: 8 additions & 0 deletions src/Analyzer/Passes/InverseDictionaryLookupPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

#include <Functions/FunctionsExternalDictionaries.h>

#include <Access/ContextAccess.h>
#include <Access/Common/AccessType.h>
#include <Core/Settings.h>
#include <Common/typeid_cast.h>

Expand Down Expand Up @@ -140,6 +142,12 @@ class InverseDictionaryLookupVisitor : public InDepthQueryTreeVisitorWithContext
if (getSettings()[Setting::rewrite_in_to_join])
return;

/// This rewrite turns `dictGet(...)` predicates into `IN (SELECT ... FROM dictionary(...))`.
/// The `dictionary()` table function requires `CREATE TEMPORARY TABLE`; if that grant is missing,
/// skip the optimization to avoid `ACCESS_DENIED`.
if (!getContext()->getAccess()->isGranted(AccessType::CREATE_TEMPORARY_TABLE))
return;

auto * node_function = node->as<FunctionNode>();

if (!node_function)
Expand Down
5 changes: 3 additions & 2 deletions src/Columns/ColumnConst.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,12 @@ class ColumnConst final : public COWHelper<IColumnHelper<ColumnConst>, ColumnCon
}

#if !defined(DEBUG_OR_SANITIZER_BUILD)
void insertRangeFrom(const IColumn &, size_t /*start*/, size_t length) override
void insertRangeFrom(const IColumn & src, size_t /*start*/, size_t length) override
#else
void doInsertRangeFrom(const IColumn &, size_t /*start*/, size_t length) override
void doInsertRangeFrom(const IColumn & src, size_t /*start*/, size_t length) override
#endif
{
chassert(!typeid_cast<const ColumnConst *>(&src) || data->compareAt(0, 0, *typeid_cast<const ColumnConst &>(src).data, -1) == 0);
s += length;
}

Expand Down
8 changes: 7 additions & 1 deletion src/Columns/ColumnDynamic.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class ColumnDynamic final : public COWHelper<IColumnHelper<ColumnDynamic>, Colum

ColumnPtr permute(const Permutation & perm, size_t limit) const override
{
return create(variant_column_ptr->permute(perm, limit), variant_info, max_dynamic_types, global_max_dynamic_types);
return create(variant_column_ptr->permute(perm, limit), variant_info, max_dynamic_types, global_max_dynamic_types, statistics);
}

ColumnPtr index(const IColumn & indexes, size_t limit) const override
Expand Down Expand Up @@ -332,6 +332,12 @@ class ColumnDynamic final : public COWHelper<IColumnHelper<ColumnDynamic>, Colum

void forEachSubcolumn(ColumnCallback callback) const override { callback(variant_column); }

/// Dynamic columns manage their own variant_info type metadata.
/// The default convertToFullIfNeeded recurses into subcolumns and strips LowCardinality
/// from variant columns, but cannot update variant_info, creating column/type mismatches.
/// Override to skip recursion — Dynamic is a self-contained typed container.
[[nodiscard]] IColumn::Ptr convertToFullIfNeeded() const override { return getPtr(); }

void forEachMutableSubcolumnRecursively(RecursiveMutableColumnCallback callback) override
{
callback(*variant_column);
Expand Down
5 changes: 5 additions & 0 deletions src/Columns/ColumnLowCardinality.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ char * ColumnLowCardinality::serializeValueIntoMemory(size_t n, char * memory, c
return getDictionary().serializeValueIntoMemory(getIndexes().getUInt(n), memory, settings);
}

std::optional<size_t> ColumnLowCardinality::getSerializedValueSize(size_t n, const IColumn::SerializationSettings * settings) const
{
return getDictionary().getSerializedValueSize(getIndexes().getUInt(n), settings);
}

void ColumnLowCardinality::collectSerializedValueSizes(PaddedPODArray<UInt64> & sizes, const UInt8 * is_null, const IColumn::SerializationSettings * settings) const
{
/// nullable is handled internally.
Expand Down
2 changes: 2 additions & 0 deletions src/Columns/ColumnLowCardinality.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ class ColumnLowCardinality final : public COWHelper<IColumnHelper<ColumnLowCardi
std::string_view serializeValueIntoArena(size_t n, Arena & arena, char const *& begin, const IColumn::SerializationSettings * settings) const override;
char * serializeValueIntoMemory(size_t n, char * memory, const IColumn::SerializationSettings * settings) const override;

std::optional<size_t> getSerializedValueSize(size_t n, const IColumn::SerializationSettings * settings) const override;

void collectSerializedValueSizes(PaddedPODArray<UInt64> & sizes, const UInt8 * is_null, const IColumn::SerializationSettings * settings) const override;

void deserializeAndInsertFromArena(ReadBuffer & in, const IColumn::SerializationSettings * settings) override;
Expand Down
2 changes: 1 addition & 1 deletion src/Columns/ColumnObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ ColumnPtr ColumnObject::permute(const Permutation & perm, size_t limit) const
permuted_dynamic_paths[path] = column->permute(perm, limit);

auto permuted_shared_data = shared_data->permute(perm, limit);
return ColumnObject::create(permuted_typed_paths, permuted_dynamic_paths, permuted_shared_data, max_dynamic_paths, global_max_dynamic_paths, max_dynamic_types);
return ColumnObject::create(permuted_typed_paths, permuted_dynamic_paths, permuted_shared_data, max_dynamic_paths, global_max_dynamic_paths, max_dynamic_types, statistics);
}

ColumnPtr ColumnObject::index(const IColumn & indexes, size_t limit) const
Expand Down
17 changes: 17 additions & 0 deletions src/Columns/ColumnUnique.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class ColumnUnique final : public COWHelper<IColumnUnique, ColumnUnique<ColumnTy
bool getBool(size_t n) const override { return getNestedColumn()->getBool(n); }
bool isNullAt(size_t n) const override { return is_nullable && n == getNullValueIndex(); }
void collectSerializedValueSizes(PaddedPODArray<UInt64> & sizes, const UInt8 * is_null, const IColumn::SerializationSettings * settings) const override;
std::optional<size_t> getSerializedValueSize(size_t n, const IColumn::SerializationSettings * settings) const override;
std::string_view serializeValueIntoArena(size_t n, Arena & arena, char const *& begin, const IColumn::SerializationSettings * settings) const override;
char * serializeValueIntoMemory(size_t n, char * memory, const IColumn::SerializationSettings * settings) const override;
void skipSerializedInArena(ReadBuffer & in) const override;
Expand Down Expand Up @@ -456,6 +457,22 @@ void ColumnUnique<ColumnType>::collectSerializedValueSizes(PaddedPODArray<UInt64
column_holder->collectSerializedValueSizes(sizes, nullptr, settings);
}

template <typename ColumnType>
std::optional<size_t> ColumnUnique<ColumnType>::getSerializedValueSize(
size_t n, const IColumn::SerializationSettings * settings) const
{
if (is_nullable)
{
if (n == getNullValueIndex())
return 1;
auto nested_size = column_holder->getSerializedValueSize(n, settings);
if (!nested_size)
return std::nullopt;
return 1 + *nested_size;
}
return column_holder->getSerializedValueSize(n, settings);
}

template <typename ColumnType>
std::string_view ColumnUnique<ColumnType>::serializeValueIntoArena(
size_t n, Arena & arena, char const *& begin, const IColumn::SerializationSettings * settings) const
Expand Down
32 changes: 32 additions & 0 deletions src/Columns/ColumnVariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ ColumnVariant::ColumnVariant(DB::MutableColumnPtr local_discriminators_, DB::Mut
global_to_local_discriminators[local_to_global_discriminators[i]] = i;
}
}

validateState();
}

namespace
Expand Down Expand Up @@ -1840,5 +1842,35 @@ void ColumnVariant::fixDynamicStructure()
variant->fixDynamicStructure();
}

void ColumnVariant::validateState() const
{
const auto & local_discriminators_data = getLocalDiscriminators();
const auto & offsets_data = getOffsets();
if (local_discriminators_data.size() != offsets_data.size())
throw Exception(ErrorCodes::LOGICAL_ERROR, "Size of discriminators and offsets should be equal, but {} and {} were given", local_discriminators_data.size(), offsets_data.size());

std::vector<size_t> actual_variant_sizes(variants.size());
for (size_t i = 0; i != variants.size(); ++i)
actual_variant_sizes[i] = variants[i]->size();

std::vector<size_t> expected_variant_sizes(variants.size(), 0);
for (size_t i = 0; i != local_discriminators_data.size(); ++i)
{
auto local_discr = local_discriminators_data[i];
if (local_discr != NULL_DISCRIMINATOR)
{
++expected_variant_sizes[local_discr];
if (offsets_data[i] >= actual_variant_sizes[local_discr])
throw Exception(ErrorCodes::LOGICAL_ERROR, "Offset at position {} is {}, but variant {} ({}) has size {}", i, offsets_data[i], static_cast<UInt32>(local_discr), variants[local_discr]->getName(), variants[local_discr]->size());
}
}

for (size_t i = 0; i != variants.size(); ++i)
{
if (variants[i]->size() != expected_variant_sizes[i])
throw Exception(ErrorCodes::LOGICAL_ERROR, "Variant {} ({}) has size {}, but expected {}", i, variants[i]->getName(), variants[i]->size(), expected_variant_sizes[i]);
}
}


}
8 changes: 8 additions & 0 deletions src/Columns/ColumnVariant.h
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@ class ColumnVariant final : public COWHelper<IColumnHelper<ColumnVariant>, Colum
void forEachMutableSubcolumnRecursively(RecursiveMutableColumnCallback callback) override;
void forEachSubcolumn(ColumnCallback callback) const override;
void forEachSubcolumnRecursively(RecursiveColumnCallback callback) const override;

/// Variant columns pair variant sub-columns with DataTypeVariant's sorted type list.
/// The default convertToFullIfNeeded recurses into sub-columns and strips LowCardinality
/// from variant columns, but cannot update the corresponding DataTypeVariant, creating
/// column/type position mismatches. Override to skip recursion.
[[nodiscard]] IColumn::Ptr convertToFullIfNeeded() const override { return getPtr(); }
bool structureEquals(const IColumn & rhs) const override;
ColumnPtr compress(bool force_compression) const override;
double getRatioOfDefaultRows(double sample_ratio) const override;
Expand Down Expand Up @@ -348,6 +354,8 @@ class ColumnVariant final : public COWHelper<IColumnHelper<ColumnVariant>, Colum
void takeDynamicStructureFromColumn(const ColumnPtr & source_column) override;
void fixDynamicStructure() override;

void validateState() const;

private:
void insertFromImpl(const IColumn & src_, size_t n, const std::vector<ColumnVariant::Discriminator> * global_discriminators_mapping);
void insertRangeFromImpl(const IColumn & src_, size_t start, size_t length, const std::vector<ColumnVariant::Discriminator> * global_discriminators_mapping, const Discriminator * skip_discriminator);
Expand Down
27 changes: 26 additions & 1 deletion src/Columns/IColumn.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,32 @@ class IColumn : public COW<IColumn>

[[nodiscard]] virtual Ptr convertToFullIfNeeded() const
{
return convertToFullColumnIfConst()->convertToFullColumnIfReplicated()->convertToFullColumnIfSparse()->convertToFullColumnIfLowCardinality();
Ptr converted = convertToFullColumnIfConst()
->convertToFullColumnIfReplicated()
->convertToFullColumnIfSparse()
->convertToFullColumnIfLowCardinality();

Columns new_subcolumns;
bool any_changed = false;

converted->forEachSubcolumn([&](const WrappedPtr & subcolumn)
{
auto new_sub = subcolumn->convertToFullIfNeeded();
any_changed |= (new_sub.get() != subcolumn.get());
new_subcolumns.push_back(std::move(new_sub));
});

if (!any_changed)
return converted;

auto mutable_column = IColumn::mutate(std::move(converted));
size_t i = 0;
mutable_column->forEachMutableSubcolumn([&](WrappedPtr & subcolumn)
{
subcolumn = std::move(new_subcolumns[i++]);
});

return std::move(mutable_column);
}

/// Creates empty column with the same type.
Expand Down
15 changes: 9 additions & 6 deletions src/Common/ZooKeeper/ZooKeeperImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,15 @@ void ZooKeeper::sendThread()
HistogramMetrics::KeeperClientQueueDuration,
std::chrono::duration_cast<std::chrono::milliseconds>(dequeue_ts - info.request->enqueue_ts).count());

if (info.watch)
info.request->has_watch = true;

if (info.request->add_root_path)
info.request->addRootPath(args.chroot);

/// Insert into operations AFTER mutating the request (has_watch, addRootPath)
/// to avoid a data race: receiveThread reads from operations concurrently,
/// and the request object is shared via shared_ptr.
if (info.request->xid != close_xid)
{
CurrentMetrics::add(CurrentMetrics::ZooKeeperRequest);
Expand All @@ -817,17 +826,11 @@ void ZooKeeper::sendThread()
operations[info.request->xid] = info;
}

if (info.watch)
info.request->has_watch = true;

if (requests_queue.isFinished())
{
break;
}

if (info.request->add_root_path)
info.request->addRootPath(args.chroot);

info.request->probably_sent = true;
info.request->write(getWriteBuffer(), use_xid_64);
flushWriteBuffer();
Expand Down
1 change: 1 addition & 0 deletions src/Common/setThreadName.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace DB
M(HASHED_DICT_DTOR, "HashedDictDtor") \
M(HASHED_DICT_LOAD, "HashedDictLoad") \
M(HTTP_HANDLER, "HTTPHandler") \
M(ICEBERG_ITERATOR, "IcebergIter") \
M(INTERSERVER_HANDLER, "IntersrvHandler") \
M(IO_URING_MONITOR, "IoUringMonitr") \
M(KEEPER_HANDLER, "KeeperHandler") \
Expand Down
2 changes: 1 addition & 1 deletion src/Coordination/KeeperContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ bool diskValidator(const Poco::Util::AbstractConfiguration & config, const std::
{
"s3"sv,
"s3_plain"sv,
"local"sv
"local"sv,
};

if (std::all_of(
Expand Down
4 changes: 4 additions & 0 deletions src/Core/BaseSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,10 @@ void BaseSettings<TTraits>::readBinary(ReadBuffer & in)
size_t index = accessor.find(name);

std::ignore = BaseSettingsHelpers::readFlags(in);

if (index == static_cast<size_t>(-1))
BaseSettingsHelpers::throwSettingNotFound(name);

accessor.readBinary(*this, index, in);
}
}
Expand Down
Loading
Loading