Server-side pagination for large result sets

- ResultStore: execute query, store batches server-side, serve pages on demand
- POST /query/paged → returns query_id + total_rows + page count (no rows)
- GET /query/page/{id}/{page}?size=100 → returns one page of rows
- RecordBatch slicing for efficient page extraction from Arrow batches
- LRU eviction: keeps 50 most recent query results in memory
- Tested: 100K rows → 1,000 pages of 100, any page fetchable by number
- Supervisor pattern: chunk results, serve on demand, retry-safe (idempotent GET)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
root
2026-03-27 20:54:44 -05:00
co-authored by Claude Opus 4.6
parent ed17216005
commit 238cb84d26
18 changed files with 441 additions and 15 deletions
+3 -3
View File
@@ -1003,8 +1003,8 @@ fn ResultsTable(response: QueryResponse) -> Element {
if response.row_count == 0 {
div { class: "empty-sm", "no rows returned" }
} else if let Some(rows) = rows {
if rows.len() > 200 {
div { class: "results-info", "Showing first 200 of {response.row_count} rows" }
if rows.len() > 500 {
div { class: "results-info", "Showing first 500 of {response.row_count} rows (use SQL tab with LIMIT for larger)" }
}
div { class: "table-wrap",
table {
@@ -1016,7 +1016,7 @@ fn ResultsTable(response: QueryResponse) -> Element {
}
}
tbody {
for row in rows.iter().take(200) {
for row in rows.iter().take(500) {
tr {
for col in response.columns.iter() {
td { {format_cell(row.get(&col.name))} }