Skip to content

Fix missing stream exception for nested JSON in wide parts#100475

Merged
Avogar merged 1 commit intoClickHouse:masterfrom
Avogar:fix-nested-json-shared-data-missing-stream
Mar 24, 2026
Merged

Fix missing stream exception for nested JSON in wide parts#100475
Avogar merged 1 commit intoClickHouse:masterfrom
Avogar:fix-nested-json-shared-data-missing-stream

Conversation

@Avogar
Copy link
Copy Markdown
Member

@Avogar Avogar commented Mar 23, 2026

PR #97523 fixed ColumnObject::permute and ColumnDynamic::permute to propagate statistics, but left the same bug in filter, index, replicate, and scatter for both ColumnObject and ColumnDynamic.

When a top-level JSON column containing Array(JSON) is permuted during INSERT (e.g. MergeTree sorting with optimize_on_insert=0), the chain ColumnObject::permuteColumnArray::permuteindexImplColumnObject::index drops statistics on the inner JSON column. This causes a mismatch: enumerateStreams (stream creation) uses the block_sample column which retains statistics via cloneEmpty and chooses 1 bucket (empty shared data optimization), while serializeBinaryBulkStatePrefix (serialization) uses the permuted column without statistics and chooses N buckets. The subsequent write to bucket 1 fails with "Stream ... not found" (LOGICAL_ERROR).

Reported by customer on version 25.12.1.1459:

Code: 49. DB::Exception: Stream light_images.images.Array(JSON(max_dynamic_types=16, max_dynamic_paths=256)).object_shared_data.1.size1 not found. (LOGICAL_ERROR)

Changelog category (leave one):

  • Critical Bug Fix (crash, data loss, RBAC)

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

Fix LOGICAL_ERROR exception "Stream ... not found" when inserting into a table with nested Array(JSON) columns in wide parts with optimize_on_insert=0.

Documentation entry for user-facing changes

  • Documentation is written (mandatory for new features)

PR ClickHouse#97523 fixed `ColumnObject::permute` and `ColumnDynamic::permute` to
propagate `statistics`, but left the same bug in `filter`, `index`,
`replicate`, and `scatter` for both `ColumnObject` and `ColumnDynamic`.

When a top-level JSON column containing `Array(JSON)` is permuted during
INSERT (e.g. MergeTree sorting with `optimize_on_insert=0`), the chain
`ColumnObject::permute` -> `ColumnArray::permute` -> `indexImpl` ->
`ColumnObject::index` drops statistics on the inner JSON column.

This causes a mismatch: `enumerateStreams` (stream creation) uses the
`block_sample` column which retains statistics via `cloneEmpty` and
chooses 1 bucket (empty shared data optimization), while
`serializeBinaryBulkStatePrefix` (serialization) uses the permuted
column without statistics and chooses N buckets. The subsequent write
to bucket 1 fails with "Stream ... not found" (LOGICAL_ERROR).

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Mar 23, 2026

Workflow [PR], commit [0be0ba4]

Summary:

job_name test_name status info comment
AST fuzzer (amd_debug, targeted) failure
Logical error: Filter column for arrayRemove was not evaluated as ColumnUInt8 but as A (STID: 3494-613d) FAIL cidb, issue ISSUE EXISTS
Stress test (amd_tsan) failure
Logical error: 'ReadBuffer is canceled. Can't read from it.' (STID: 2508-2913) FAIL cidb, issue ISSUE CREATED
AST fuzzer (amd_debug) failure
Logical error: Bad cast from type A to B (STID: 4185-5b0d) FAIL cidb, issue ISSUE EXISTS

AI Review

Summary

This PR fixes a real correctness bug by preserving JSON path statistics through filter, index, replicate, and scatter for ColumnObject and ColumnDynamic, preventing Stream ... not found LOGICAL_ERROR during inserts with nested Array(JSON) into wide parts. The code changes themselves look consistent and low-risk, but test coverage is incomplete for all changed transform paths.

Findings

  • ⚠️ Majors
    • [tests/queries/0_stateless/04054_json_nested_shared_data_buckets_missing_stream_bug.sql:5] The new regression test validates the permute -> index failure path, but this PR also changes filter, replicate, and scatter in both ColumnObject and ColumnDynamic. Without dedicated assertions for these paths, regressions in the additional touched methods can slip through.
    • Suggested fix: extend this test (or add sibling tests) to trigger and validate statistics propagation through filter, replicate, and scatter code paths as well.

Tests

  • ⚠️ Add targeted regression coverage for filter, replicate, and scatter transformations on nested Array(JSON) data, because these methods were changed in this PR and currently are not directly exercised.

ClickHouse Rules

Item Status Notes
Deletion logging
Serialization versioning
Core-area scrutiny
No test removal
Experimental gate
No magic constants
Backward compatibility
SettingsChangesHistory.cpp
PR metadata quality
Safe rollout
Compilation time

Final Verdict

  • Status: ⚠️ Request changes
  • Minimum required actions:
    • Add regression coverage for the additional changed paths (filter, replicate, scatter) so all touched statistics-propagation paths are protected by tests.

@clickhouse-gh clickhouse-gh bot added pr-critical-bugfix pr-must-backport Pull request should be backported intentionally. Use this label with great care! labels Mar 23, 2026

SET allow_experimental_json_type = 1;

-- Regression test for a bug where ColumnObject::index (and filter/replicate/scatter)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The regression test reproduces the permute -> index path, but this PR also changes filter, replicate, and scatter in both ColumnObject and ColumnDynamic. Please add focused coverage for those transformed-column paths as well, otherwise future regressions in those methods will not be caught.

@clickhouse-gh
Copy link
Copy Markdown
Contributor

clickhouse-gh bot commented Mar 23, 2026

LLVM Coverage Report

Metric Baseline Current Δ
Lines 83.90% 83.90% +0.00%
Functions 24.50% 24.60% +0.10%
Branches 76.50% 76.50% +0.00%

PR changed lines: PR changed-lines coverage: 100.00% (33/33, 0 noise lines excluded)
Diff coverage report
Uncovered code

@scanhex12 scanhex12 self-assigned this Mar 23, 2026
@@ -0,0 +1,42 @@
-- Tags: long

SET allow_experimental_json_type = 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But let's keep it, I need this PR to be backported for a customer in cloud, so don't want to wait for CI rerun

@Avogar Avogar added this pull request to the merge queue Mar 24, 2026
Merged via the queue into ClickHouse:master with commit f94a13b Mar 24, 2026
292 of 300 checks passed
@Avogar Avogar deleted the fix-nested-json-shared-data-missing-stream branch March 24, 2026 13:19
@robot-ch-test-poll2 robot-ch-test-poll2 added the pr-must-backport-synced The `*-must-backport` labels are synced into the cloud Sync PR label Mar 24, 2026
@robot-ch-test-poll1 robot-ch-test-poll1 added the pr-synced-to-cloud The PR is synced to the cloud repo label Mar 24, 2026
robot-clickhouse added a commit that referenced this pull request Mar 24, 2026
robot-clickhouse added a commit that referenced this pull request Mar 24, 2026
robot-clickhouse added a commit that referenced this pull request Mar 24, 2026
robot-clickhouse added a commit that referenced this pull request Mar 24, 2026
robot-clickhouse added a commit that referenced this pull request Mar 24, 2026
robot-clickhouse added a commit that referenced this pull request Mar 24, 2026
@robot-ch-test-poll robot-ch-test-poll added the pr-backports-created Backport PRs are successfully created, it won't be processed by CI script anymore label Mar 24, 2026
clickhouse-gh bot added a commit that referenced this pull request Mar 24, 2026
Backport #100475 to 26.1: Fix missing stream exception for nested JSON in wide parts
clickhouse-gh bot added a commit that referenced this pull request Mar 24, 2026
Backport #100475 to 25.12: Fix missing stream exception for nested JSON in wide parts
clickhouse-gh bot added a commit that referenced this pull request Mar 24, 2026
Backport #100475 to 26.2: Fix missing stream exception for nested JSON in wide parts
Avogar added a commit that referenced this pull request Mar 24, 2026
Backport #100475 to 26.3: Fix missing stream exception for nested JSON in wide parts
Avogar added a commit that referenced this pull request Mar 24, 2026
Backport #100475 to 25.8: Fix missing stream exception for nested JSON in wide parts
Avogar added a commit that referenced this pull request Mar 24, 2026
Backport #100475 to 25.3: Fix missing stream exception for nested JSON in wide parts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-backports-created Backport PRs are successfully created, it won't be processed by CI script anymore pr-critical-bugfix pr-must-backport Pull request should be backported intentionally. Use this label with great care! pr-must-backport-synced The `*-must-backport` labels are synced into the cloud Sync PR pr-synced-to-cloud The PR is synced to the cloud repo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants