Skip to content

fix(python): push down namespace full reads#3516

Merged
BubbleCal merged 1 commit into
mainfrom
yang/gen540-arrow
Jun 8, 2026
Merged

fix(python): push down namespace full reads#3516
BubbleCal merged 1 commit into
mainfrom
yang/gen540-arrow

Conversation

@BubbleCal

Copy link
Copy Markdown
Contributor

Bug Fix

What is the bug?

Namespace-backed LanceTable.to_arrow() full-table reads bypassed the existing QueryTable server-side query path and called the lower-level table to_arrow() implementation directly. In Geneva/Sophon this could fail while parsing the Arrow IPC response for hist.get_table().to_arrow() / to_pandas(), even though hist.get_table().search().to_arrow() worked.

What issues or incorrect behavior does the bug cause?

Full-table reads on namespace-backed tables with QueryTable pushdown could fail with Arrow IPC parse errors, while query/search reads on the same table succeeded. Since to_pandas() delegates through to_arrow() for non-blob/native cases, pandas export was affected too.

How does this PR fix the problem?

When QueryTable pushdown is enabled, sync and async table to_arrow() now construct a plain no-filter, no-limit, all-columns query and execute it through the table-level _execute_query() path. AsyncTable now preserves namespace context from async namespace connections so async full reads can make the same pushdown decision. Non-namespace tables and namespace tables without QueryTable pushdown keep their existing behavior.

Tests

  • uv run --extra tests --extra dev --no-sync ruff check python/lancedb/table.py python/lancedb/namespace.py python/tests/test_namespace.py
  • uv run --extra tests --extra dev --no-sync ruff format python/lancedb/table.py python/lancedb/namespace.py python/tests/test_namespace.py
  • uv run --extra tests --extra dev --no-sync pytest python/tests/test_namespace.py::TestPushdownOperations::test_lance_table_to_arrow_uses_query_pushdown python/tests/test_namespace.py::TestAsyncPushdownOperations::test_async_table_to_arrow_uses_query_pushdown python/tests/test_namespace.py::test_local_table_to_arrow_and_to_pandas_are_unchanged -q
  • uv run --extra tests --extra dev --no-sync pytest python/tests/test_namespace.py -q

@github-actions github-actions Bot added bug Something isn't working Python Python SDK labels Jun 8, 2026
@BubbleCal
BubbleCal marked this pull request as ready for review June 8, 2026 09:58

@claude claude Bot 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.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.

Tip: disable this comment in your organization's Code Review settings.

@Xuanwo Xuanwo left a comment

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.

This needs one correctness fix before merging.

if _should_push_down_query_table(
self._namespace_client, self._pushdown_operations
):
return self._execute_query(Query()).read_all()

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.

This changes full-table reads into a QueryTable request built from an empty Query(), but _query_to_namespace_request() maps limit=None to k=10. That means namespace-backed to_arrow() / non-blob to_pandas() can silently return only 10 rows instead of the full table. We need a request/path that preserves unbounded plain-scan semantics, plus a >10 row regression test through the real request conversion layer.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in a041f48. _query_to_namespace_request() now maps plain non-vector/non-FTS queries with limit=None to sys.maxsize, matching the existing remote-table unbounded sentinel, while vector/FTS queries keep the existing default k=10. The namespace regression now goes through the real _execute_server_side_query() / request conversion layer with 12 rows and asserts both to_arrow() and to_pandas() send k == sys.maxsize.

@BubbleCal
BubbleCal force-pushed the yang/gen540-arrow branch from e3a2628 to a041f48 Compare June 8, 2026 10:35
@BubbleCal
BubbleCal merged commit 3e25f58 into main Jun 8, 2026
16 checks passed
@BubbleCal
BubbleCal deleted the yang/gen540-arrow branch June 8, 2026 11:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Python Python SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants