You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Bug report — upstream bug (still present on master) whose reach was widened by an Altinity PR, breaking the sanitizer CI.
Describe the situation
test_storage_iceberg_with_spark/test_schema_inference.py::test_schema_inference fails consistently on antalya-26.6 in the job Integration tests (amd_asan_ubsan, db disk, old analyzer, 4/8) — 12/12 params, every run since 2026-08-11, 0 failures in the previous 90 days. All other integration configs (msan, tsan, arm_binary) pass.
It is 1 real failure + 11 cascading: [s3-1-True] runs first and kills node1 on SELECT * FROM {TABLE_NAME}; the remaining 11 only get Connection refused because the server never comes back.
The cause is a signed integer overflow parsing Iceberg Decimal bounds with scale > 18 (10^30 computed in an int64_t). The test creates a decimal(38, 30) column. Reported upstream: ClickHouse#114929 — that issue has the minimal reproducer and the full analysis.
The faulty arithmetic is upstream code, present in master and in the 26.6 / 26.7 release branches. What is Altinity-specific is that we reach it: upstream only hits that path through pruning, so a query needs a WHERE. #2145 added a second caller in IDataLakeMetadata.cpp:157-158 that parses bounds for all columns unconditionally, so on our branch a plain SELECT * is enough.
UBSAN_OPTIONS=print_stacktrace=1 ./clickhouse local --path ../ \
--query "SELECT * FROM icebergLocal('lakehouses/dec_min')"
Note there is no WHERE: on our branch any query that reads a column is enough — SELECT *, or even SELECT id (the non-Decimal column) — the table only has to contain a Decimal column with scale > 18. The one query that does not reproduce is SELECT count(), which requests no columns.
The same SELECT *, on the same table, with the upstream master asan_ubsan binary (26.8.1.1445) returns 1 42 and does not abort — upstream only reaches this path through pruning, so it needs a filter.
The call site in IDataLakeMetadata.cpp was introduced by 81919f2b0c7 (cherry-pick of #1687), the only commit in that window touching it; it is absent from both green commits and present in both red ones.
Expected behavior
Test passes, as it did before #2145 and as it does upstream.
Actual behavior
FAILED test_schema_inference[s3-1-True]
test_schema_inference.py:81: instance.query(f"SELECT * FROM {TABLE_NAME}")
Code: 32. DB::Exception: Attempt to read after eof: while receiving packet from
172.16.1.8:9000 (ATTEMPT_TO_READ_AFTER_EOF)
FAILED test_schema_inference[s3-1-False] ... and 10 more
Code: 210. DB::NetException: Connection refused (172.16.1.8:9000). (NETWORK_ERROR)
Server side (reproduced locally with the same build):
src/Storages/ObjectStorage/DataLakes/Iceberg/IcebergFieldParseHelpers.cpp:147:24:
runtime error: signed integer overflow: -1000000000000000000 * 10 cannot be represented
in type 'long'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior
Note:allow_experimental_iceberg_read_optimization=0 does not mitigate this — the bounds are parsed while building the metadata, before that setting is consulted.
Worth reviewing separately: the new caller in IDataLakeMetadata.cpp:157-158 parses bounds for every column unconditionally. Besides exposing this bug, it is work done on every read regardless of whether the statistics are used.
Type of problem
Bug report — upstream bug (still present on master) whose reach was widened by an Altinity PR, breaking the sanitizer CI.
Describe the situation
test_storage_iceberg_with_spark/test_schema_inference.py::test_schema_inferencefails consistently onantalya-26.6in the jobIntegration tests (amd_asan_ubsan, db disk, old analyzer, 4/8)— 12/12 params, every run since 2026-08-11, 0 failures in the previous 90 days. All other integration configs (msan, tsan, arm_binary) pass.It is 1 real failure + 11 cascading:
[s3-1-True]runs first and kills node1 onSELECT * FROM {TABLE_NAME}; the remaining 11 only getConnection refusedbecause the server never comes back.The cause is a signed integer overflow parsing Iceberg
Decimalbounds with scale > 18 (10^30computed in anint64_t). The test creates adecimal(38, 30)column. Reported upstream: ClickHouse#114929 — that issue has the minimal reproducer and the full analysis.The faulty arithmetic is upstream code, present in
masterand in the26.6/26.7release branches. What is Altinity-specific is that we reach it: upstream only hits that path through pruning, so a query needs aWHERE. #2145 added a second caller inIDataLakeMetadata.cpp:157-158that parses bounds for all columns unconditionally, so on our branch a plainSELECT *is enough.How to reproduce
antalya-26.6(26.6.2.20000, shaa894ddeb080387b3798a6373e06abd9776b0e98c)build_amd_asan_ubsanbinary — no server, no object storage, no Spark:Note there is no
WHERE: on our branch any query that reads a column is enough —SELECT *, or evenSELECT id(the non-Decimalcolumn) — the table only has to contain aDecimalcolumn with scale > 18. The one query that does not reproduce isSELECT count(), which requests no columns.The same
SELECT *, on the same table, with the upstream masterasan_ubsanbinary (26.8.1.1445) returns1 42and does not abort — upstream only reaches this path through pruning, so it needs a filter.Does not depend on
db diskorold analyzer.Timeline:
213541c37f7a9d3433(merge of #2145)be5f3f6faa894ddeb0The call site in
IDataLakeMetadata.cppwas introduced by81919f2b0c7(cherry-pick of #1687), the only commit in that window touching it; it is absent from both green commits and present in both red ones.Expected behavior
Test passes, as it did before #2145 and as it does upstream.
Actual behavior
Server side (reproduced locally with the same build):
Suggested fix
IcebergFieldParseHelpers.cpp:143— returnstd::nulloptwhenscale > 18, before the multiplication. Should be behaviour-preserving (Decimal128/Decimal256already take that path a few lines below), but not compiled or tested.allow_experimental_iceberg_read_optimization=0does not mitigate this — the bounds are parsed while building the metadata, before that setting is consulted.IDataLakeMetadata.cpp:157-158parses bounds for every column unconditionally. Besides exposing this bug, it is work done on every read regardless of whether the statistics are used.