DEV-1810: MCP query row cap — default 20 rows, LIMIT push-down, truncation notice - #369
Conversation
…sponse-row-cap-with-a-truncation
…sponse-row-cap-with-a-truncation
|
Warning Review limit reachedNext included review available in 15 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. Your 53 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Review configuration: ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Essentials Run ID: 📒 Files selected for processing (11)
Comment |
Field attributes were appended after _format_output, which for markdown already carries the trailing Warnings block, so a truncated response with labeled/formatted fields no longer ended with the notice. Render the attributes footer before the markdown warnings via a new _format_output footer param; add a regression test.
|
@coderabbitai review |
|
|



Fixes DEV-1810.
What
querytool caps returned rows at 20 when the caller passes nolimit; an explicitlimitis trusted verbatim — no ceiling, no response-side truncation, even forexplainplan rows.LIMIT 21(cap + 1), so truncation is detectable without fetching the full result; a post-execution slice guards the paths push-down can't reach (run-by-name stored queries, explain plans). Run-by-name stored SQL is never modified.query_nestedapplies the same rule keyed on the ROOT (last) stage'slimitonly; the pushed-down limit goes into a copy of the root dict, so caller input is never mutated. Non-root limits neither lift nor lower the cap.ResponseTruncationWarning(kind"truncated",returned_rows,hint) added to theAnySlayerWarningunion inslayer/core/warnings.py. It rides the existing warnings machinery, so all three formats stay in sync by construction: markdown trailingWarnings:block, csv leading#comment line, json{"data", "warnings"}shape. It coexists with engine warnings and is appended last. The engine never emits it — additive schema only from the REST API's perspective.docs/reference/mcp.md(cap, root-stage rule, per-format warnings rendering incl. the json shape change) and.claude/skills/slayer-query.md(one-line cap mention);limitdocstrings updated on both tools, so the rendered tool schema mentions the cap.Tests
tests/test_mcp_row_cap.py(25 tests, one class per spec requirement): default cap boundary cases (20 / 21 rows) against a live sqlite datasource; explicit limit trusted verbatim (incl. mocked engine returning more rows than the limit — no slice, no notice);LIMIT 21push-down visible indry_run/show_sqland absent from run-by-name stored SQL; run-by-name capping at/above the cap;query_nestedroot-stage keying (non-root limit ignored, root limit trusted, caller dicts not mutated); notice rendering in all three formats incl. coexistence ordering with an engine warning; union round-trip ofResponseTruncationWarning; explain-plan capping anddry_runnever truncating.Spec surface (
openspec show dev-1810-mcp-query-tool-add-a-response-row-cap-with-a-truncation --diff)mcp/response-row-cap — seven added requirements
🤖 Generated with Claude Code
https://claude.ai/code/session_01JJT5gJBS5A4akHsisRomVC