Skip to content

Follow-up fixes from PR #18643 (OPEN_STRUCT storage layer) review comments - #19093

Open
tarun11Mavani wants to merge 3 commits into
apache:masterfrom
tarun11Mavani:open-struct-review-fixes
Open

Follow-up fixes from PR #18643 (OPEN_STRUCT storage layer) review comments#19093
tarun11Mavani wants to merge 3 commits into
apache:masterfrom
tarun11Mavani:open-struct-review-fixes

Conversation

@tarun11Mavani

Copy link
Copy Markdown
Contributor

Summary

Follow-up fixes from PR #18643 (OPEN_STRUCT storage layer) review comments.

Review-comment fixes:

  • OpenStructColumnSplitter: use computeIfAbsent instead of get+put; Utf8.encodedLength instead of allocating byte[] for length measurement
  • MutableOpenStructIndex: expanded volatile copy-on-write Javadoc; tryCoerce takes PinotDataType directly (avoids repeated conversion per ingested value)
  • MutableKeyColumn: cache PinotDataType destType at construction
  • MutableOpenStructDataSource: snapshot keyColumns before iteration (concurrent-modification guard)
  • MutableSegmentImpl: remove dead getOpenStructIndex() method
  • IndexLoadingConfig: persist _openStructSegmentMetadata so child configs survive refreshIndexConfigs() dirty rebuilds

Segment-lifecycle hardening:

  • ImmutableOpenStructDataSource: add getMapValue(docId) — reconstructs the original map from dense per-key DataSources + sparse JSON; used by PinotSegmentRecordReader and SegmentColumnarIndexCreator
  • ImmutableSegmentImpl: warn log when skipping OPEN_STRUCT parent due to missing/wrong FieldSpec
  • MutableSegmentImpl: Preconditions.checkState guard in toDataSource() for OPEN_STRUCT with disabled index

Test plan

  • ImmutableOpenStructDataSourceTest — 5 new tests for getMapValue(): dense-only, null doc, dense+sparse merge, sparse-only null, empty segment
  • Existing OPEN_STRUCT test suites pass unchanged

Review-comment fixes from the storage PR (apache#18643) that were not included
in the merged version:

- OpenStructColumnSplitter: computeIfAbsent instead of containsKey+put,
  Utf8.encodedLength instead of getBytes(UTF_8).length
- MutableOpenStructIndex: volatile copy-on-write Javadoc clarification,
  pass PinotDataType directly to tryCoerce instead of converting per call
- MutableKeyColumn: cache PinotDataType destType to avoid repeated
  ColumnDataType.fromDataTypeSV().toPinotDataType() conversion
- MutableOpenStructDataSource: snapshot keyColumns map before iterating
- MutableSegmentImpl: remove unused getOpenStructIndex() method
- IndexLoadingConfig: persist OPEN_STRUCT segment metadata so child
  configs survive refreshIndexConfigs() dirty rebuilds
…umns

- ImmutableSegmentImpl: warn log when an OPEN_STRUCT parent's schema/fieldSpec
  is missing or mismatched, so dense/sparse child data silently becomes
  unqueryable
- MutableSegmentImpl: checkState guard requiring the open_struct_index to be
  enabled when building a DataSource for an OPEN_STRUCT column
- ImmutableOpenStructDataSource: getMapValue()/readValue() to reconstruct the
  full key-value map (dense + sparse) for a doc, used by the seal path and
  minion tasks
@codecov-commenter

codecov-commenter commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.83333% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.50%. Comparing base (385e38a) to head (512978e).
⚠️ Report is 29 commits behind head on master.

Files with missing lines Patch % Lines
...ndex/openstruct/ImmutableOpenStructDataSource.java 59.09% 12 Missing and 6 partials ⚠️
...l/indexsegment/immutable/ImmutableSegmentImpl.java 0.00% 3 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19093      +/-   ##
============================================
+ Coverage     65.45%   65.50%   +0.05%     
  Complexity     1421     1421              
============================================
  Files          3428     3430       +2     
  Lines        216598   218039    +1441     
  Branches      34311    34657     +346     
============================================
+ Hits         141778   142835    +1057     
- Misses        63405    63638     +233     
- Partials      11415    11566     +151     
Flag Coverage Δ
custom-integration1 100.00% <ø> (ø)
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 65.50% <70.83%> (+0.05%) ⬆️
temurin 65.50% <70.83%> (+0.05%) ⬆️
unittests 65.50% <70.83%> (+0.05%) ⬆️
unittests1 56.80% <8.33%> (-0.11%) ⬇️
unittests2 37.88% <68.05%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

writeSparseJsonColumn() hand-built a partial PropertiesConfiguration for
the OPEN_STRUCT sparse ($__sparse__) column, hard-coding a subset of
keys instead of routing through the standard metadata writer. This
branch's ColumnMetadataImpl still tolerates missing bitsPerElement/
lengthOfEachEntry/maxNumberOfMultiValues via UNAVAILABLE defaults, so
it wasn't fatal here, but the metadata was still wrong (e.g. CARDINALITY
was approximated as a non-null doc count rather than the real distinct
value count), and a sibling branch's stricter reader throws
NoSuchElementException on this exact gap.

Route the sparse column through the same AbstractColumnStatisticsCollector
+ BaseSegmentCreator.addColumnMetadataInfo() path that writeDenseKeyColumn()
already uses, instead of a hand-rolled subset of keys that had drifted out
of sync with what the reader expects.

Extend testSparseJsonColumnWritten to round-trip the produced properties
through ColumnMetadataImpl.fromPropertiesConfiguration() as a regression
check.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants