From 9a9b681aaf26dcb32af45fc77d79cdbd49f46c6a Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Thu, 12 Nov 2026 00:49:00 +0800 Subject: [PATCH] docs(python): clarify refresh result row counts (#4963) ## Summary `RefreshColumnResult` exposed the canonical refresh counters without documenting their unit. This change describes them as logical rows planned for one refresh: `rows_assigned` counts successful rows written, `rows_failed` counts rows whose computation failed, and `rows_remaining` counts planned rows neither assigned nor terminally skipped. Rows already covered by `rows_failed` are not counted again as remaining. Retry attempts and user-code calls do not change that logical-row scope. The change also documents the source and published versions and the deprecated `rows_filled` alias. The existing skip-policy example is now explicit: a refresh over 2,001 logical rows with 1,891 assigned, 110 failed, and 0 remaining uses 2,001 as the failure-rate denominator. ## Behavior Documentation only. No field names, Python or native behavior, REST wire format, dependencies, or pins change. ## Validation - `git diff --check` - `uvx ruff format --check` - `uvx ruff check` - Imported this Python source with a compatible prebuilt ABI3 extension and asserted the public class and property documentation, the affected source version, and the native extension identity. --- python/python/lancedb/functions.py | 32 +++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/python/python/lancedb/functions.py b/python/python/lancedb/functions.py index 6d0c2ff52..737abc44e 100644 --- a/python/python/lancedb/functions.py +++ b/python/python/lancedb/functions.py @@ -873,17 +873,47 @@ class RefreshColumnResult(_RemoteValue): LanceDB Embedded jobs produce this value in process. LanceDB Enterprise decodes the same value from the durable server-job terminal payload. + + Row counters describe logical rows planned for this refresh, not user-code + calls or retry attempts. ``rows_assigned`` counts rows successfully written + with an output value, ``rows_failed`` counts rows whose computation failed, + and ``rows_remaining`` counts planned rows neither assigned nor terminally + skipped. Rows already counted in ``rows_failed`` are covered and are not + counted again in ``rows_remaining``. + + For example, a refresh over 2,001 logical rows that assigns 1,891 values and + fails 110 rows reports ``rows_assigned=1,891``, ``rows_failed=110``, and + ``rows_remaining=0``. Its failure-rate denominator is those 2,001 logical + rows, not the number of execution attempts. """ rows_assigned: _UInt64 + """Number of logical rows successfully assigned an output value by this + refresh. Each row counts once, regardless of retry attempts, and failed rows + are not included.""" + rows_failed: _UInt64 + """Number of logical rows whose computation failed. Rows deferred because + an input was not ready are not failures.""" + rows_remaining: _UInt64 + """Number of planned logical rows neither assigned nor terminally skipped. + Rows already counted in ``rows_failed`` are covered and are not counted + again.""" + source_version: _UInt64 + """Exact table version the refresh read.""" + published_version: Optional[_UInt64] = None + """Table version made visible by the refresh, when one was published.""" @property def rows_filled(self) -> int: - """Deprecated compatibility alias for :attr:`rows_assigned`.""" + """Deprecated compatibility alias for :attr:`rows_assigned`. + + The value is the same successful logical-row count; it does not count + execution attempts. + """ return self.rows_assigned @property