Commit b9d81bf
committed
fix: resolve double LIMIT bug in SQL pagination wrapping
The old `extract_order_by`/`remove_order_by` helpers used a naive
`rfind("ORDER BY")` that captured everything from ORDER BY to the end
of the query string — including any user-supplied LIMIT/OFFSET clauses.
When the pagination layer then appended its own LIMIT, the final SQL
contained duplicate LIMIT keywords, causing syntax errors on all
database engines.
Replace per-driver helpers with a shared, bracket-and-quote-aware SQL
tokenizer (`extract_trailing_clauses` + `build_paginated_query`) in
`drivers/common.rs` that correctly separates ORDER BY, LIMIT and OFFSET
from the base query before wrapping.
Key changes:
- Add `tokenize_sql` that respects single-quotes, double-quotes,
backticks, and parenthesized subqueries so keywords inside literals,
identifiers (e.g. table name `…_limit`), or subqueries are never
misidentified.
- `extract_trailing_clauses` returns a struct with the clean base query,
optional ORDER BY content, optional user LIMIT, and optional OFFSET.
- `build_paginated_query` uses `min(user_limit, page_size)` so user
intent is respected while the pagination +1 trick still works.
- Remove duplicated `extract_order_by`/`remove_order_by` from postgres,
mysql, and sqlite drivers.
- MCP `run_query` now accepts an optional `limit` parameter and its tool
description documents LIMIT-clause handling.
- 18 new unit tests covering all edge cases including table names
containing "limit", quoted identifiers, string literals with SQL
keywords, subqueries, multi-column ORDER BY, and semicolons.
Fixes: queries on tables like `tapp_appointment_message_event_limit`
with ORDER BY + LIMIT producing invalid SQL via MCP.
Made-with: Cursor1 parent 6ddc629 commit b9d81bf
5 files changed
Lines changed: 522 additions & 114 deletions
0 commit comments