Skip to content

Fix accurate casts from an unsigned integer to IPv4 and IPv6 - #113040

Open
groeneai wants to merge 2 commits into
ClickHouse:masterfrom
groeneai:groeneai/fix-ipv4-key-in-nullable-uint32-set-index
Open

Fix accurate casts from an unsigned integer to IPv4 and IPv6#113040
groeneai wants to merge 2 commits into
ClickHouse:masterfrom
groeneai:groeneai/fix-ipv4-key-in-nullable-uint32-set-index

Conversation

@groeneai

@groeneai groeneai commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Related: #111418

Changelog category (leave one):

  • Bug Fix (user-visible misbehavior in an official stable release)

Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):

Fix accurateCast, accurateCastOrNull and accurateCastOrDefault from an unsigned integer to IPv4, and from UInt128 to IPv6: they never converted the value even though the plain CAST of it succeeds. Because the MergeTree set index builds its pruning set with accurateCastOrNull, an IPv4 primary key with IN over a UInt32 subquery returned no rows.

Description

accurateCastOrNull(x, 'IPv4') returned NULL for every unsigned integer, accurateCast threw, and accurateCastOrDefault returned 0.0.0.0 - while CAST(x, 'IPv4') converts it. Same for UInt128 to IPv6:

CREATE TABLE ip2 (a IPv4) ENGINE = MergeTree ORDER BY a PARTITION BY a;
INSERT INTO ip2 VALUES ('1.2.3.4'), ('1.2.3.5'), ('8.8.8.8');
-- 1) set index prunes every part; ENGINE = Memory returns 1.2.3.4:
SELECT a FROM ip2 WHERE a IN (SELECT CAST(16909060, 'Nullable(UInt32)')) SETTINGS transform_null_in = 1;
-- 2) runtime IN, no index: returned 0, while `=` on the same pair returns 1:
SELECT CAST(16909060, 'UInt32') IN (SELECT toIPv4('1.2.3.4'));
-- 3) query 2 under transform_null_in = 1 threw Code: 70. 16909060 = toUInt32(toIPv4('1.2.3.4')).

FunctionCast::createWrapper enters its accurate branch for any integer source, then dispatches into a lambda whose value-producing arms are guarded by IsDataTypeNumber<RightDataType>. That trait is specialized only for DataTypeNumber<T>, which DataTypeIPv4/DataTypeIPv6 are not: their field type is a StrongTypedef. No arm matched, so the wrapper fell through to an all-NULL column or a throw without examining the value. Plain CAST reaches ConvertImpl, which already supports integer to IPv4.

This adds the missing dispatcher arm plus an accurate integer-to-IPv4 conversion that range-checks against IPv4::UnderlyingType, mirroring convertFieldToType. That check is load-bearing: the existing helper truncates, so reusing it would replace NULL with a silently wrong value. UInt128 to IPv6 needs only the dispatcher arm. Fixing the conversion layer corrects every consumer at once; a KeyCondition-only fix would leave symptoms 2 and 3.

Plain CAST keeps its behaviour, including truncation above 2^32. Out-of-range values are now rejected rather than truncated, and the set index still prunes (Parts: 1/3, asserted). 03212_variant_dynamic_cast_or_default is updated because toIPv4OrDefault/toIPv6OrDefault build on the accurate cast, as in #110459 for Date32.

How the scope was established (702-pair cast sweep)

Consumers corrected by the single change: Set (runtime IN), KeyCondition (the set index),
castOrDefault, KVStorageUtils, FunctionsJSON, evaluateConstantExpression.

All 702 ordered pairs over 27 types were swept against the invariant "plain CAST succeeds, so the
accurate cast must not return NULL". Exactly 6 pairs violated it, and all 6 are fixed here with no
residue:

from to plain CAST accurateCastOrNull before
UInt8 IPv4 0.0.0.1 NULL
UInt16 IPv4 0.0.0.1 NULL
UInt32 IPv4 0.0.0.1 NULL
UInt64 IPv4 0.0.0.1 NULL
Bool IPv4 0.0.0.1 NULL
UInt128 IPv6 ::1 NULL

Bool needs no special handling, being DataTypeUInt8. UUID and the Int*/Float*/UInt256
sources stay out of scope: plain CAST throws for those too, so NULL is already consistent, and
making them convertible would be a new capability rather than a bug fix. The new test pins them as
negative controls, together with the 4294967295 / 4294967296 boundary pair and the
Nullable/LowCardinality/Const wrapper matrix.

accurateCast, accurateCastOrNull and accurateCastOrDefault never converted an
unsigned integer to IPv4, nor UInt128 to IPv6, even though the plain CAST of the
same value succeeds. accurateCastOrNull returned NULL, accurateCast threw
CANNOT_CONVERT_TYPE, and accurateCastOrDefault returned 0.0.0.0.

Because the MergeTree set index builds its pruning set with
castColumnAccurateOrNull, this silently returned wrong results: an IPv4 primary
key compared with IN against a UInt32 subquery pruned every part, since every
set element became NULL. Set also uses the accurate casts, so a runtime IN over
the same cross-type pair returned 0 while = returned 1, and under
transform_null_in = 1 the same query threw instead.

FunctionCast::createWrapper enters its accurate branch for any integer source,
then dispatches into a lambda whose value-producing arms are guarded by
IsDataTypeNumber<RightDataType>. That trait is specialized only for
DataTypeNumber<T>, and DataTypeIPv4/DataTypeIPv6 are not, because their field
type is a StrongTypedef. No arm matched, so the wrapper fell through to an
all-NULL column or a throw without ever examining the value. The plain CAST was
unaffected because it reaches ConvertImpl, which already whitelists
UInt8/UInt16/UInt32/UInt64 as IPv4 sources.

This adds the missing dispatcher arm plus an accurate integer-to-IPv4
conversion. The conversion range-checks against IPv4::UnderlyingType rather than
the StrongTypedef itself, mirroring convertFieldToType, which converts a UInt64
field to IPv4 through UInt32; accurate::convertNumeric cannot be instantiated
for a StrongTypedef target at all. The check is load-bearing: the existing
convertFromUInt64ToIPv4 truncates, so reusing it would have replaced NULL with a
silently wrong value. UInt128 to IPv6 needs only the dispatcher arm, since that
conversion already handles accurate additions; it is left untouched because IPv6
is stored big-endian and its helper byte-swaps both limbs.

Fixing the conversion layer corrects every consumer at once: Set, KeyCondition,
castOrDefault, KVStorageUtils, FunctionsJSON and evaluateConstantExpression.
Plain CAST keeps its behaviour, including truncating values above 2^32, because
the new ConvertImpl arm is selected only for the accurate additions types.

Scope was established by sweeping all 702 ordered pairs over 27 types against
the invariant "plain CAST succeeds, so the accurate cast must not return NULL".
Exactly 6 pairs violated it (UInt8/UInt16/UInt32/UInt64/Bool to IPv4, UInt128 to
IPv6) and all 6 are fixed with no residue. UUID and the Int*, Float* and UInt256
sources are deliberately out of scope: plain CAST throws for those too, so
returning NULL is consistent, and making them convertible would be a new
capability rather than a bug fix. The new test pins them as negative controls.

03212_variant_dynamic_cast_or_default is updated because toIPv4OrDefault and
toIPv6OrDefault over a Dynamic column build on the accurate cast, so values that
previously fell to the type default now convert, matching what plain CAST
returns for the same inputs. Its diagnostic allow-list is widened for the same
reason rather than removed. This is the same update c9e6de1 made to that
reference when the accurate cast to Date32 became strict.

Related: ClickHouse#111418
@groeneai

groeneai commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author
Internal second-model review (0 blockers, 0 majors)

Reviewed independently of the author: a cold read of the resulting code first (carriers enumerated
from scratch before comparing against the fix plan), then a second-model full-scope review, then
adjudication against the recorded evidence.

Result: 0 blockers, 0 majors. The second-model pass returned no findings. Five nits from the
cold read, adjudicated below.

# Finding Verdict
💡 1 PR body exceeded the internal concision budget, and the Related: provenance link sat inside the HTML comment where it does not render Fixed before publishing: condensed, link made visible
💡 2 04708 creates ip_key with no DROP TABLE IF EXISTS (257 of 268 recent tests use that idiom) Disagreed after measuring: tests/clickhouse-test:2159-2180 creates a fresh test_<random> database per test, so a leftover table cannot collide unless --database is passed
💡 3 NO_SANITIZE_UNDEFINED on the new helper is a no-op, since its only cast is preceded by an exact range check Disagreed: every sibling helper in the file carries it; local consistency wins
⚠️ 4 Two accurate-cast consumers change behaviour untested: FunctionsJSON.cpp:320 (JSON-object subcolumn) and evaluateConstantExpression.cpp:601 Agreed as noted-not-blocking. Both move from NULL/default toward the value plain CAST gives, so neither can produce a wrong result. 04121_json_extract_types_edges is provably unaffected: JSONExtract over a String JSON takes JSONExtractTree::IPv4Node, which requires element.isString() and never reaches the cast
💡 5 One comment clause states motivation rather than a local invariant Agreed, not worth a rebuild: 5 added comment lines against 73 added code lines, max 3 lines per block

Independently verified during the cold read, rather than taken from the author's notes:

  • Arm order is load-bearing and correct. The new ConvertImpl arm precedes the truncating
    UInt64 -> IPv4 arm and both sit in the same if constexpr chain, so the accurate additions
    select the new arm while the default additions still reach the old one. Plain CAST truncation
    above 2^32 is therefore preserved, and the test pins it.
  • The range check against IPv4::UnderlyingType is exact, not approximate:
    accurate::convertNumeric reduces to a bound test plus a strict round-trip comparison for an
    unsigned source, so 4294967295 converts and 4294967296 is rejected instead of truncated.
  • One carrier the fix plan did not list is genuinely unreachable rather than missed:
    convertColumnToType.cpp gates on isNativeNumber, which is isNativeInteger() || isNativeFloat()
    and excludes both IP types, so that consumer needs no test.
  • Test liveness traced rather than assumed: reverting the fix reddens 04708 at three independent
    layers (the direct cast assertions, the runtime IN versus its = oracle in the same query, and
    the set-index row plus Parts: 1/3 and the 0-element set count). The negative controls pin the
    scope, so a future over-broad widening also reddens.
  • The 03212 reference update has the precedent it claims: commit c9e6de1458b95e9 updated that
    same reference for the strict accurate cast to Date32. Three other tests that could plausibly
    have moved were checked and do not: 03595_funcs_on_zero asserts the zero cases, which are
    unchanged, and 03593/02531 use only string sources.
  • Test number 04708 re-verified free at publish time against master, open PRs of any author, and
    every live local worktree.
  • No durability or serialization surface, so no crash-recovery obligation and no
    SettingsChangesHistory.cpp entry.

Session id: cron:clickhouse-review-slot-48:20260802-220600

@groeneai

groeneai commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author
Pre-PR validation gate (click to expand)
# Question Answer
a Deterministic repro? Yes, 100%, no randomization: one clickhouse local run of a 3-statement script (the CREATE/INSERT/SELECT in the description). Pre-fix signature: zero rows for query 1, 0 for query 2, Code: 70 for query 3.
b Root cause explained? FunctionCast::createWrapper takes its accurate branch for any integer source, then dispatches through callOnIndexAndDataType into a lambda whose value-producing arms are guarded by IsDataTypeNumber<RightDataType>. That trait is specialized only for DataTypeNumber<T>, and DataTypeIPv4/DataTypeIPv6 are not, since their field type is a StrongTypedef. No arm matched, the lambda returned false, and the tail produced an all-NULL column (accurateOrNull) or threw CANNOT_CONVERT_TYPE (accurate) without examining the value. The set index then built its pruning set from all-NULL elements, dropped every one, and declared no part could match a predicate that does match.
c Fix matches root cause? Yes: it widens the dispatch to reach the conversion, and adds the range check that conversion needs to be accurate. No guard at the failure site, no disabled optimization, no widened bound. The index still prunes (Parts: 1/3, asserted in the test), so a fix that "worked" by declining to prune would fail this test.
d Test intent preserved / new tests added? New 04708_accurate_cast_integer_to_ip covers all 6 fixed pairs, both accurate variants, the boundary, the wrapper matrix, negative controls, and both the runtime IN and the set index. 03212_variant_dynamic_cast_or_default's diagnostic tripwire was widened rather than deleted, and re-proved silent; its ids come from a server-global sequence, so they cannot be pinned in a reference.
e Both directions demonstrated? Yes, by reverting the source in the same worktree and rebuilding: pristine Build ID 9c078030221103d2... gives FAIL, fix Build ID efa2ad4db2f400ff... gives PASS. Each run asserted buildId() on the server against the binary. Re-applying the patch reproduced the same Build ID byte for byte.
f Fix is general across code paths? Fixed in the conversion layer, so every consumer is corrected at once: Set (runtime IN), KeyCondition (set index), castOrDefault, KVStorageUtils, FunctionsJSON, evaluateConstantExpression. A KeyCondition-only fix would have left the runtime wrong result and the spurious exception standing, which is why that option was rejected.
g Fix generalizes across inputs (params/datatypes/wrappers)? All 702 ordered pairs over 27 types were swept against "plain CAST succeeds, so the accurate cast must not return NULL": 6 violations before, 0 after. Wrappers Nullable, LowCardinality, Const and a multi-row column all asserted; boundaries 0, 1, 2^32-2, 2^32-1, 2^32 and UInt128 max covered; Int32/Float64/UInt256/UUID pinned as still-NULL negative controls so the fix cannot silently widen.
h Backward compatible? Yes. Only pairs that previously could not produce a value at all now produce one, so no result changes from one value to a different value. Plain CAST is byte-identical, including its truncation of values above 2^32, and the test asserts that. No setting default moved, so no SettingsChangesHistory.cpp entry is needed (confirmed by grep: the only settings tokens in the diff are pass-through parameters).
i Invariants and contracts preserved? accurate still throws for genuinely unrepresentable values and accurateOrNull still returns NULL; only the code path changed, never the rejection semantics, and the two variants are tested separately because they diverge in the wrapper tail. The null map is allocated input_rows_count wide up front and every row assigns both its value and its null flag, so no row is left uninitialized on any path. The new ConvertImpl arm is guarded on the accurate Additions types, so the non-accurate arms keep running exactly as before. IPv6 is stored big-endian and its existing conversion byte-swaps both limbs, so that arm was left untouched; the four 02935_ipv6_from_uint128_* tests pass.

Session id: cron:clickhouse-impl-slot-4:20260802-182400

@groeneai

groeneai commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

cc @Ergus @KochetovNicolai, could you review this? FunctionCast::createWrapper guards its value-producing arms with IsDataTypeNumber<RightDataType>, which is specialized only for DataTypeNumber<T>, so the StrongTypedef-backed DataTypeIPv4/DataTypeIPv6 matched no arm and the accurate casts returned an all-NULL column without examining the value, which made the MergeTree set index prune every part for an IPv4 key compared against a UInt32 subquery.

@alexey-milovidov alexey-milovidov added the can be tested Allows running workflows for external contributors label Aug 2, 2026
@clickhouse-gh

clickhouse-gh Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Workflow [PR], commit [3c46800]

Summary:

job_name test_name status info comment
Stateless tests (amd_llvm_coverage, ParallelReplicas, s3 storage, parallel) FAIL
02480_interval_casting_and_subquery ERROR cidb
Server died FAIL cidb
Logical error: Trying to lookup values in runtime filter before building it was finished (STID: 2210-500d) FAIL cidb

AI Review

Summary

This PR fixes the accurate-cast dispatcher so unsigned-integer to IPv4 and UInt128 to IPv6 conversions reach the existing value conversion logic instead of falling through to all-NULL / exception behavior, and it adds the strict UInt64 to IPv4 range check that accurateCast needs. I did not find any correctness, safety, or test-coverage problems in the current diff: the new stateless test covers the broken cast paths, IN behavior, and MergeTree set-index pruning regression, and the current Praktika report is green.

Final Verdict

✅ No blockers or majors found in the current version.

LLVM Coverage Report

Metric Baseline Current Δ
Lines 86.50% 86.40% -0.10%
Functions 91.90% 91.80% -0.10%
Branches 78.70% 78.60% -0.10%

Changed lines: Changed C/C++ lines covered: 43/46 (93.48%) · Uncovered code

Full report · Diff report

@clickhouse-gh clickhouse-gh Bot added the pr-bugfix Pull request with bugfix, not backported by default label Aug 2, 2026
Build (arm_tidy) failed with cppcoreguidelines-init-variables, which is
enabled with -warnings-as-errors: the loop-local out-parameter passed to
accurate::convertNumeric was declared without an initializer. The header
is included by 35 translation units, so the single declaration produced 38
diagnostics and dropped the other 151 jobs of the workflow.

No behavior change: convertNumeric assigns the variable on every success
path, and the failure path never reads it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@clickhouse-gh

clickhouse-gh Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Build profile diff (arm_release)

Comparing 3c4680052 with master e7a96e5d3 (stripped binary size, per-symbol sizes and ThinLTO time; object sizes against the warmup build of 508dbed54; compile times per translation unit against the most recent warmup build that recompiled it).

⚠️ Significant changes: object file sizes, slowest function optimization changes (thinlto), symbol sizes.

Binary sizes
Binary Master PR Δ
programs/clickhouse-stripped 685.30 MiB 682.31 MiB -2.99 MiB (-0.44%)

Only the stripped binary is compared: the official master build keeps debug symbols while PR builds strip them, so the other binaries differ by construction.

Object file sizes ⚠️

3 object files changed (-40.12 MiB total), 0 added, 685 removed.

Object file Master PR Δ
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/ext/transport/chttp2/transport/cht… 960.56 KiB removed -960.56 KiB (-100.00%)
src/Common/ZooKeeper/CMakeFiles/clickhouse_common_zookeeper_no_log.dir/ZooKeeperImpl.cpp.o 804.97 KiB removed -804.97 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/server/server.cc.o 612.22 KiB removed -612.22 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/load_balancing/rls/rls.cc.o 611.36 KiB removed -611.36 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/client_channel/client_channel_filt… 548.04 KiB removed -548.04 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/client_channel/client_channel.cc.o 525.46 KiB removed -525.46 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/client_channel/retry_interceptor.c… 518.85 KiB removed -518.85 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/lib/channel/promise_based_filter.c… 482.91 KiB removed -482.91 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/load_balancing/grpclb/grpclb.cc.o 434.97 KiB removed -434.97 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/call/client_call.cc.o 433.89 KiB removed -433.89 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/call/server_call.cc.o 391.29 KiB removed -391.29 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc++_unsecure.dir/__/grpc/src/cpp/server/server_cc.cc.o 384.88 KiB removed -384.88 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/client_channel/retry_filter_legacy… 369.55 KiB removed -369.55 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/ext/transport/chttp2/transport/wri… 349.81 KiB removed -349.81 KiB (-100.00%)
contrib/google-cloud-cpp-cmake/CMakeFiles/google_cloud_cpp_grpc_utils.dir/__/google-cloud-cpp/googl… 346.93 KiB removed -346.93 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/ext/transport/inproc/legacy_inproc… 345.35 KiB removed -345.35 KiB (-100.00%)
contrib/google-cloud-cpp-cmake/CMakeFiles/google_cloud_cpp_longrunning_operations_protos.dir/google… 339.33 KiB removed -339.33 KiB (-100.00%)
contrib/google-cloud-cpp-cmake/CMakeFiles/google_cloud_cpp_iam_credentials_v1_iamcredentials_protos… 334.24 KiB removed -334.24 KiB (-100.00%)
contrib/google-protobuf-cmake/CMakeFiles/_libprotobuf-lite.dir/__/google-protobuf/src/google/protob… 316.58 KiB removed -316.58 KiB (-100.00%)
contrib/grpc-cmake/CMakeFiles/grpc_unsecure.dir/__/grpc/src/core/call/call_spine.cc.o 312.88 KiB removed -312.88 KiB (-100.00%)
Slowest function optimization changes (ThinLTO) ⚠️

Median per-function time ratio to the master baseline is ×1.11 (different machine and build flags); deltas below are relative to that ratio.

Binary Function Master PR Δ vs median
programs/clickhouse-keeper DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.11069338206770680048] new 18.4 s +18.4 s
programs/clickhouse DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.12487241783113815285] 9.0 s gone -10.0 s (-100%)
programs/clickhouse-keeper DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.12487241783113815285] 8.5 s gone -9.4 s (-100%)
programs/clickhouse DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.11069338206770680048] new 7.6 s +7.6 s
programs/clickhouse-keeper DB::registerFunctionConversion(DB::FunctionFactory&) 7.1 s 15.3 s +7.4 s (+95%)
programs/clickhouse-keeper _GLOBAL__sub_I_TargetLibraryInfo.cpp 5.8 s 12.1 s +5.6 s (+87%)
programs/clickhouse DB::Parquet::writeColumnChunkBody(DB::Parquet::ColumnChunkWriteState&, DB::Parquet::WriteOptions co… 5.5 s 3.4 s -2.7 s (-45%)
programs/clickhouse-keeper DB::ServerSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.54623650351436… new 2.7 s +2.7 s
programs/clickhouse-keeper DB::MergeTreeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.56540966842… new 2.5 s +2.5 s
programs/clickhouse-keeper _ZN2DB18FunctionArrayIndexINS_16CountEqualActionENS_14NameCountEqualEE15executeIntegralIJDutjmDB8_s… 1.9 s 4.5 s +2.4 s (+112%)
programs/clickhouse DB::getSettingsChangesHistory()::$_0::operator()() const 4.6 s 2.7 s -2.4 s (-46%)
programs/clickhouse-keeper DB::registerFunctionVectorFunctions(DB::FunctionFactory&) 2.3 s 4.9 s +2.3 s (+93%)
programs/clickhouse-keeper _GLOBAL__sub_I_sqid.cpp 1.7 s 4.3 s +2.3 s (+121%)
programs/clickhouse DB::ServerSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.17566710545920… 1.9 s gone -2.1 s (-100%)
programs/clickhouse DB::Aggregator::writeToTemporaryFile(DB::AggregatedDataVariants&, unsigned long) const 3.6 s 1.9 s -2.1 s (-53%)
Compile time of recompiled translation units

40 translation units recompiled, 268 s compile time in total, 40 of them have a recent master baseline.

Median compile-time ratio to the baselines is ×1.07 (machine-speed difference or a change affecting every TU); per-TU deltas below are relative to that ratio.
The matched translation units cost +22.0 s (+9%) in total before that adjustment.

Symbol sizes ⚠️
Binary Symbol Master PR Δ
programs/clickhouse DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.11069338206770680048] new 439.45 KiB +439.45 KiB
programs/clickhouse-keeper DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.11069338206770680048] new 439.45 KiB +439.45 KiB
programs/clickhouse DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.12487241783113815285] 439.45 KiB removed -439.45 KiB (-100.00%)
programs/clickhouse-keeper DB::SettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.12487241783113815285] 439.45 KiB removed -439.45 KiB (-100.00%)
programs/clickhouse DB::ServerSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.17566710545920… 114.16 KiB removed -114.16 KiB (-100.00%)
programs/clickhouse DB::ServerSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.54623650351436… new 114.16 KiB +114.16 KiB
programs/clickhouse-keeper DB::ServerSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.17566710545920… 114.16 KiB removed -114.16 KiB (-100.00%)
programs/clickhouse-keeper DB::ServerSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.54623650351436… new 114.16 KiB +114.16 KiB
programs/clickhouse-keeper DB::MergeTreeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.16712493492… 102.51 KiB removed -102.51 KiB (-100.00%)
programs/clickhouse-keeper DB::MergeTreeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.56540966842… new 102.51 KiB +102.51 KiB
programs/clickhouse DB::MergeTreeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.56540966842… new 102.51 KiB +102.51 KiB
programs/clickhouse DB::MergeTreeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.16712493492… 102.51 KiB removed -102.51 KiB (-100.00%)
programs/clickhouse DB::DatabaseDataLakeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.1111… new 97.41 KiB +97.41 KiB
programs/clickhouse DB::DatabaseDataLakeSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.9031… 97.41 KiB removed -97.41 KiB (-100.00%)
programs/clickhouse DB::ObjectStorageQueueSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.38… new 92.15 KiB +92.15 KiB
programs/clickhouse DB::ObjectStorageQueueSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.26… 92.15 KiB removed -92.15 KiB (-100.00%)
programs/clickhouse DB::KafkaSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.872715978862839… new 89.47 KiB +89.47 KiB
programs/clickhouse DB::KafkaSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.176316896530569… 89.47 KiB removed -89.47 KiB (-100.00%)
programs/clickhouse DB::DataLakeStorageSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.41967… 88.38 KiB removed -88.38 KiB (-100.00%)
programs/clickhouse DB::DataLakeStorageSettingsTraits::Accessor::instance()::$_0::operator()() const [clone .llvm.13841… new 88.38 KiB +88.38 KiB

Job report

@groeneai

groeneai commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

CI finish ledger - 3c46800

Every failure below has an owner: a fixing PR (mine or external), or a full-effort fix task
whose fixing-PR link will be posted here when it opens. Only CH Inc sync is exempt.

CI is fully finished on this head: 175 check-runs, 0 queued or in progress, Config Workflow
and Finish Workflow both success, and the CIDB ingestion buffer has elapsed. The Build (arm_tidy)
red and the consequent Finish Workflow / Post Hooks drop reported on the previous head
a050ee7def5d are both green here, and all three Bugfix validation legs that were dropped by
that failure now pass.

Check / test Reason Owner / fixing PR
Stateless tests (amd_llvm_coverage, ParallelReplicas, s3 storage, parallel) / Logical error: Trying to lookup values in runtime filter before building it was finished (STID 2210-500d), plus its two collateral rows Server died and 02480_interval_casting_and_subquery (the server is shutting down due to a fatal error) one abort event, not three failures. A JOIN runtime filter is probed before the last BuildRuntimeFilterTransform stream finished merging, so IRuntimeFilter::find raised a logical error. Not this PR: the diff is FunctionsConversion accurate-cast to IPv4/IPv6 plus two stateless tests, and the same signature predates it on 2 other carriers since 2026-07-06 #107108 (mine, open)

#107108 is the causal fix, not a coincidental same-area PR: it modifies
src/Processors/QueryPlan/RuntimeFilterLookup.{cpp,h} so find passes all rows through
(const-true) while the build side is unfinished instead of throwing, reorders finishInsert
so a concurrent find cannot observe a half-built filter, and adds
04337_runtime_filter_lookup_before_finished for exactly this signature. It is open, so there
is no merged fix to pick up onto this branch.

Session id: cron:our-pr-ci-monitor:20260803-053000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

can be tested Allows running workflows for external contributors pr-bugfix Pull request with bugfix, not backported by default

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants