fix(base): TableRows.__len__ read a SELECT's rowcount (-1 on SQLite) - #8
Merged
Merged
Conversation
The same rowcount trap #4 fixed in SqlBaseKvReader.__len__ and #5 fixed in SqlBaseKvStore.__setitem__ was still in TableRows.__len__, so len() of a TableRows over SQLite raised "ValueError: __len__() should return >= 0". Ask the database for COUNT(*), honouring the row filter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Post-merge refute review of #5.
#5 fixed the SELECT-
rowcounttrap inSqlBaseKvStore.__setitem__(and #4 inSqlBaseKvReader.__len__), and the fix itself holds up. But the same trap remains in the exportedTableRows.__len__, which returnedresult.rowcountof aSELECT *: on SQLite (and any driver that does not pre-buffer) that is-1, solen(TableRows(...))raisesValueError: __len__() should return >= 0.Fix. Count with
SELECT count(*) ... [WHERE filt], honouring thefiltthe rows were built with.Tests.
sqldol/tests/test_table_rows_len.py: unfiltered and filteredlenagainst in-memory SQLite. Both fail on master with theValueError, pass here. Full suite + doctests: 104 passed locally (Python 3.10).Also checked in #5 and found fine:
.first()releases the SELECT before the UPDATE/INSERT on the same connection; duplicate rows for a key (from before #5) are all updated rather than adding another.Not changed (pre-existing, noted only):
sql_base.iter_rowsstops on a falsyrowcount, which is-1(truthy) on sqlite3, so without alimitit keeps issuing empty pages untillimit(default 1e12) -- the existing injection test already works around it with a bounded batch.Self-reviewed only (the dispatching run disallowed sub-agents).
🤖 Generated with Claude Code
https://claude.ai/code/session_011HSBVhDjRU4apSLcRkavv9