Skip to content

GH-55295: [C++][Dataset] Reject negative num_rows in Scanner::Head - #55304

Open
siddiqueirshad wants to merge 1 commit into
apache:mainfrom
siddiqueirshad:fix/dataset-head-negative-rows
Open

siddiqueirshad wants to merge 1 commit into
apache:mainfrom
siddiqueirshad:fix/dataset-head-negative-rows

Conversation

@siddiqueirshad

Copy link
Copy Markdown

Rationale for this change

Fixes #55295. Currently, Dataset.head, Scanner.head, and Fragment.head accept negative num_rows (e.g. head(-1)). AsyncScanner::Head passes the negative count directly into RecordBatch::Slice(0, num_rows), producing invalid record batches with negative lengths that cause Table.validate() to fail with Array length is negative and len() in Python to fail with SystemError.

What changes are included in this PR?

  • In AsyncScanner::Head, check if (num_rows < 0) and return Status::Invalid("num_rows must be non-negative").
  • In C++ cpp/src/arrow/dataset/scanner_test.cc, add ASSERT_RAISES(Invalid, scanner->Head(-1)) to TestScanner.Head.
  • In Python python/pyarrow/tests/test_dataset.py, test that negative rows raise ValueError (as ArrowInvalid subclasses ValueError) for both dataset_reader.head(dataset, -1) and fragment.head(-1).

Are these changes tested?

Yes, added C++ unit test in scanner_test.cc and Python tests in test_dataset.py.

Are there any user-facing changes?

Yes, calling head() with a negative num_rows now returns an ArrowInvalid error instead of returning a malformed Table with negative row count.

Was AI used for this PR?

In accordance to the AI generation guidelines, please disclose below whether and how AI was used in this PR.

PR code and description written by:

  • Human
  • AI

Reviewed before submission by:

  • Human
  • AI
  • Not reviewed

Fixes apache#55295

Signed-off-by: siddiqui irshad <mohdirshad1306@gmail.com>
@github-actions github-actions Bot added the awaiting review Awaiting review label Oct 28, 2026
@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #55295 has been automatically assigned in GitHub to PR creator.

@github-actions

Copy link
Copy Markdown

⚠️ GitHub issue #55295 has no components, please add labels for components.

@chrikrah chrikrah left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@siddiqueirshad this fixes #55295 on all three entry points; from my perspective it can be merged.

# git archive 844133d (base b8079cd), Arrow C++ Release build with dataset+parquet, pyarrow built against it, Python 3.12
$ release/arrow-dataset-scanner-test --gtest_filter='*Head*'
[  PASSED  ] 4 tests.
$ python -m pytest pyarrow/tests/test_dataset.py -q -k test_head
2 passed, 360 deselected
$ python -I head_negative.py   # the #55295 script
dataset.head(-1)     raised ArrowInvalid: num_rows must be non-negative
scanner().head(-2)   raised ArrowInvalid: num_rows must be non-negative
fragment.head(-1)    raised ArrowInvalid: num_rows must be non-negative
dataset.head(0)      num_rows=0 valid

# scanner.cc from b8079cd, tests kept
Expected 'scanner->Head(-1)' to fail with Invalid, but got OK   # all 4 Head params
2 failed, 360 deselected
dataset.head(-1)     num_rows=-1 invalid: Column 0: In chunk 0: Invalid: Array length is negative
# not run: the rest of the C++ and Python suites

Non-blocking: should the Head doc in scanner.h say a negative num_rows returns Invalid?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Python] Dataset.head(-1) returns a Table with negative num_rows

2 participants