Skip to content

#857 Disable indexes when record_limit is below threshold and pass recordLimit to VRLRecordReader. - #861

Merged
yruslan merged 4 commits into
masterfrom
feature/857-limit-records
Jul 27, 2026
Merged

#857 Disable indexes when record_limit is below threshold and pass recordLimit to VRLRecordReader.#861
yruslan merged 4 commits into
masterfrom
feature/857-limit-records

Conversation

@yruslan

@yruslan yruslan commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added record_limit support to cap decoded output rows for variable-length reads, including nested and hierarchical iteration.
    • record_limit = 0 returns no rows; omitting the limit reads all available records.
    • If record_limit is present and <= 100,000, indexing is automatically disabled for bounded reads.
  • Documentation
    • Reformatted the README “Modifier options” table for better readability without changing the listed options.
  • Tests
    • Added/expanded record-limit integration coverage (including a large-limit scenario) and updated unit test fixtures for the updated reader constructor wiring.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c78c000-12b3-447d-ba7e-2fe7aff97aec

📥 Commits

Reviewing files that changed from the base of the PR and between 673e509 and f971d87.

📒 Files selected for processing (2)
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala
🚧 Files skipped from review as they are similar to previous changes (2)
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala

Walkthrough

Adds end-to-end recordLimit propagation through Cobrix reader parameters and variable-length iterators, stops record fetching at the configured limit, adjusts index configuration for small limits, and adds RDW integration coverage plus README table reformatting.

Changes

Record limit flow

Layer / File(s) Summary
Record-limit configuration wiring
cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/parameters/..., spark-cobol/src/main/scala/za/co/absa/cobrix/spark/cobol/...
recordLimit is added to ReaderParameters, reordered in CobolParameters, and propagated through parser and Spark parameter wiring.
Variable-length iterator enforcement
cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/..., cobol-parser/src/test/scala/.../VRLRecordReaderSpec.scala
Variable-length iterators pass recordLimit to VRLRecordReader, which stops fetching when the configured limit is reached.
Index behavior and validation
cobol-parser/src/main/scala/.../CobolParametersParser.scala, spark-cobol/src/test/scala/.../Test43RecordLimitSpec.scala, README.md
A minimum index threshold is defined, RDW input and integration coverage are expanded, and the modifier-options table is reformatted.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CobolParametersParser
  participant ReaderParameters
  participant VarLenHierarchicalIterator
  participant VRLRecordReader
  CobolParametersParser->>ReaderParameters: pass recordLimit
  ReaderParameters->>VarLenHierarchicalIterator: provide readerProperties.recordLimit
  VarLenHierarchicalIterator->>VRLRecordReader: construct with recordLimit
  VRLRecordReader->>VRLRecordReader: stop fetching at the limit
Loading

Possibly related PRs

  • AbsaOSS/cobrix#806: Both modify reader/index parameter wiring involving enable_indexes.
  • AbsaOSS/cobrix#860: Both implement record_limit propagation and enforcement through the reader path.

Poem

A bunny counts records, one, two, three,
Then hops when the limit says “flee!”
RDW rows bloom in a tested view,
While tidy tables guide the crew.
Hip-hop, shipped today!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the two main changes: disabling indexes below the record_limit threshold and passing recordLimit into VRLRecordReader.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/857-limit-records

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

JaCoCo code coverage report - 'cobol-parser'

Overall Project 90.13% -0.05% 🍏
Files changed 72.58% 🍏

File Coverage
VRLRecordReader.scala 90.13% -4.16% 🍏
VarLenHierarchicalIterator.scala 71.97% -4.55% 🍏
VarLenNestedIterator.scala 68.68% 🍏

@github-actions

github-actions Bot commented Jul 27, 2026

Copy link
Copy Markdown

JaCoCo code coverage report - 'spark-cobol'

Overall Project 83.52% 🍏
Files changed 100% 🍏

File Coverage
SparkCobolProcessor.scala 96.4% 🍏
DefaultSource.scala 83.37% 🍏

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
cobol-parser/src/test/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReaderSpec.scala (1)

355-356: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Thread recordLimit through the test helper.

getUseCase hardcodes None, so the VRLRecordReaderSpec tests never exercise the new limit path. Add recordLimit: Option[Int] = None to the helper and cover zero, exact-N, and boundary cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@cobol-parser/src/test/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReaderSpec.scala`
around lines 355 - 356, Update the getUseCase test helper to accept a
recordLimit: Option[Int] = None parameter and pass it through instead of
hardcoding None. Extend VRLRecordReaderSpec coverage for zero, exact-N, and
boundary record-limit cases so the new limit path is exercised.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala`:
- Line 57: Move record-limit enforcement out of the raw-record readers and apply
it at decoded-row boundaries: in VarLenHierarchicalIterator.scala (line 57),
allow all segments of each root record to be extracted before counting the
completed hierarchical row; in VarLenNestedIterator.scala (line 55), apply the
limit only after segment filtering so filtered raw records do not consume the
decoded-row budget.

In
`@cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala`:
- Around line 77-78: The record-limit guard in VRLRecordReader’s fetchNext path
uses recordIndex before it is incremented, allowing prefetch beyond the
configured limit. Track the next emitted record index separately, check the
limit before fetching, and clear the cached record when the limit is reached so
recordLimit 0 yields no rows and positive N yields exactly N rows.

---

Nitpick comments:
In
`@cobol-parser/src/test/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReaderSpec.scala`:
- Around line 355-356: Update the getUseCase test helper to accept a
recordLimit: Option[Int] = None parameter and pass it through instead of
hardcoding None. Extend VRLRecordReaderSpec coverage for zero, exact-N, and
boundary record-limit cases so the new limit path is exercised.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1dbd664a-f69c-4ca9-8038-7c004ac7f67b

📥 Commits

Reviewing files that changed from the base of the PR and between 997d999 and bedc407.

📒 Files selected for processing (11)
  • README.md
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenNestedIterator.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/parameters/CobolParameters.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/parameters/CobolParametersParser.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/parameters/ReaderParameters.scala
  • cobol-parser/src/test/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReaderSpec.scala
  • spark-cobol/src/main/scala/za/co/absa/cobrix/spark/cobol/SparkCobolProcessor.scala
  • spark-cobol/src/main/scala/za/co/absa/cobrix/spark/cobol/source/DefaultSource.scala
  • spark-cobol/src/test/scala/za/co/absa/cobrix/spark/cobol/source/integration/Test43RecordLimitSpec.scala

type RawRecord = (String, Array[Byte])

private val rawRecordIterator = new VRLRecordReader(cobolSchema, dataStream, readerProperties, recordHeaderParser, rawRecordExtractor, startRecordId, startingFileOffset)
private val rawRecordIterator = new VRLRecordReader(cobolSchema, dataStream, readerProperties, recordHeaderParser, rawRecordExtractor, startRecordId, startingFileOffset, readerProperties.recordLimit)

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Apply the output limit at decoded-row boundaries, not raw-record boundaries.

  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala#L57-L57: enforce the limit after complete hierarchical rows are extracted; do not truncate a root record’s segments.
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenNestedIterator.scala#L55-L55: enforce the limit after segment filtering so filtered raw records do not consume the decoded-row budget.
📍 Affects 2 files
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala#L57-L57 (this comment)
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenNestedIterator.scala#L55-L55
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala`
at line 57, Move record-limit enforcement out of the raw-record readers and
apply it at decoded-row boundaries: in VarLenHierarchicalIterator.scala (line
57), allow all segments of each root record to be extracted before counting the
completed hierarchical row; in VarLenNestedIterator.scala (line 55), apply the
limit only after segment filtering so filtered raw records do not consume the
decoded-row budget.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala`:
- Line 87: Update the extractor-record handling in VRLRecordReader so
recordNextToFetch is incremented exactly once for each accepted payload. Remove
the duplicate increment across the paths around extractor.next() and the later
accepted-record handling, while preserving the configured record limit and
non-extractor behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8e3fadaa-7146-482e-a593-967f33b40861

📥 Commits

Reviewing files that changed from the base of the PR and between bedc407 and f7aedb7.

📒 Files selected for processing (1)
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala`:
- Around line 102-105: Update the record-limit early-return branch in
VarLenHierarchicalIterator to clear cachedValue before closing dataStream and
returning. Ensure cachedValue is set to the empty Option state so hasNext() does
not dereference an uninitialized value or repeatedly expose the final cached
row.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ca4f087c-4221-416c-9acb-265d536f9dec

📥 Commits

Reviewing files that changed from the base of the PR and between f7aedb7 and 673e509.

📒 Files selected for processing (3)
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VarLenHierarchicalIterator.scala
  • spark-cobol/src/test/scala/za/co/absa/cobrix/spark/cobol/source/integration/Test43RecordLimitSpec.scala
🚧 Files skipped from review as they are similar to previous changes (2)
  • cobol-parser/src/main/scala/za/co/absa/cobrix/cobol/reader/iterator/VRLRecordReader.scala
  • spark-cobol/src/test/scala/za/co/absa/cobrix/spark/cobol/source/integration/Test43RecordLimitSpec.scala

@yruslan
yruslan merged commit 8f1c26b into master Jul 27, 2026
7 checks passed
@yruslan
yruslan deleted the feature/857-limit-records branch July 27, 2026 12:18
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.

1 participant