8000 feat: :limit N (#306 PR 1) by adityamukho · Pull Request #745 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

feat: :limit N (#306 PR 1) - #745

Merged
adityamukho merged 14 commits into
v3from
feat/306-limit-op
Oct 24, 2026
Merged

adityamukho merged 14 commits into
v3from
feat/306-limit-op

Conversation

@adityamukho
@adityamukho adityamukho commented Oct 24, 2026 •
Copy link
Copy Markdown
Collaborator

PR 1 of 2 for #306 (spec docs/superpowers/specs/2026-10-24-limit-order-by-design.md, plan steps 1–9). Part of #306, which stays open until PR 2 (:order-by, :offset, top-k Sort).

What

  • :limit N / :limit $n in a query vector, any section order. It returns at most N rows of the answer, after aggregates and windows, for rule queries, cursors, prepared queries and write-transaction reads. Without :order-by which rows is unspecified (spec decision 2); they are always a sub-bag of the unlimited answer.
  • Limit operator (src/query/engine/limit.rs): passes on at most N rows, then closes its child, so nothing below reads more. Planned after Builder::finish, so no step can land after it. :limit 0 pulls nothing.
  • New PRS-115 for a value that is not an integer >= 0 or a slot; a repeated :limit is INT-012 and a missing value INT-013, as for the other query options. A prepared slot takes BindValue::Val(Value::Integer(n)); n < 0 → PRS-115, another bind value → API-024, missing → API-022, unbound in execute → API-010.
  • Grammar: limit_section in tests/grammar/grammar.pest, docs/GRAMMAR.md regenerated, corpus files; verifier TOKENS gains :limit (filler counts 20,686 / 565,267 at bounds 3 / 4) and SEMANTIC witnesses for INT-012 and PRS-115.

Numbers (idle 88-vCPU server, one NUMA node)

100K 1M 10M
envelope limit p50 / p99 307 / 502 µs 317 / 348 µs 318 / 391 µs
attribute_scan (same pattern, no limit) p50 43 ms 462 ms 4.83 s

Acceptance (moved from #473, nightly in smoke.yml): :limit 10 over 10M facts in 0.8 ms under a 64 KiB query_memory_limit, adding 132 KiB of RSS. The fixture is written with LogWriter (5.2 min); building it with transact took 42 min, over the job's 30-minute timeout.

Tests

Bench machine (after merging v3): plain 1,760 passed / 14 ignored, test-hooks 1,783 / 15; with #743 merged in, 1,789 / 1,813 tests listed; grammar verifier at bound 4 clean. cargo clippy --all-features -- -D warnings clean; wasm32 browser build OK. Release binary +3.2 KB (1,188 → 1,191 KiB locally, gate 1,200 KiB).

Deviations from the plan / spec

  1. Operator counters are not public, so the acceptance test checks time and RSS; the "the scan reads one batch" check is a cursor unit test (src/cursor.rs), and Limit unit tests count the rows the child sends.
  2. Spec §3.1 says PreparedQuery::slot_names reports a :limit slot; that is a private field, not an API. The slot is collected (collect_slot_names), so execute rejects it unbound with API-010, which the tests check.
  3. :limit :kw is INT-013 (no value: the section ends at the next keyword), not PRS-115; the grammar rejects it either way.
  4. The PRS-115 text has no backticks (registry_matches_error_reference_doc_bidirectionally reads the doc's text between backticks).
  5. After post-1.0: expose PreparedQuery over UniFFI #181, a :limit $n slot bound to the wrong kind is API-024 and an unbound one API-022 (the spec says INT-035/INT-033, now deprecated); a negative integer is still PRS-115.

Codex review: no findings.

🤖 Generated with Claude Code

https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW

adityamukho and others added 12 commits October 24, 2026 09:33
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW
Conflicts: PRS-115 beside #316's PRS-119–121; verifier TOKENS gains both
:limit and #316's #{ (34 tokens, filler counts 23,020 / 651,806); test counts.
:limit slot mistakes follow #181: API-022 / API-024 instead of INT-033 / INT-035.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169pNQsLcCEn48te9X9WuZW
# Conflicts:
#	CLAUDE.md
#	docs/TEST_COVERAGE.md
@codecov
codecov Bot commented Oct 24, 2026
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.86585% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/query/datalog/parser.rs 96.87% 2 Missing ⚠️
src/query/engine/filter.rs 0.00% 2 Missing ⚠️
src/query/datalog/types.rs 50.00% 1 Missing ⚠️
src/query/engine/limit.rs 99.31% 1 Missing ⚠️
src/query/engine/plan.rs 85.71% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

# Conflicts:
#	CLAUDE.md
#	docs/TEST_COVERAGE.md
#	src/query/engine/filter.rs
# Conflicts:
#	CLAUDE.md
#	docs/TEST_COVERAGE.md
@adityamukho
adityamukho merged commit 59ce7f2 into v3 Oct 24, 2026
20 checks passed
@adityamukho
adityamukho deleted the feat/306-limit-op branch October 24, 2026 22:13
adityamukho added a commit that referenced this pull request Oct 24, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Urda7FD9CYYoxdeGGJa11x
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

0