Skip to content

Add SQL execution and results to the frontend - #1499

Merged
thekevinbot merged 5 commits into
mainfrom
bot/1487-frontend-query-1011
Oct 13, 2026
Merged

thekevinbot merged 5 commits into
mainfrom
bot/1487-frontend-query-1011

Conversation

@thekevinbot

@thekevinbot thekevinbot commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #1487

The --frontend page can now run read-only SQL via POST /query and show the result.

Choices

  • Script is a separate embedded asset, /frontend.js (only with --frontend), so it is testable as a module. No framework, no build step.
  • Tests are Node's built-in runner (packages/rust/tests/frontend/query.test.mjs), run by the Rust integration test frontend_js.rs. The request-ordering and rendering logic is injected (fetch, clock, a small fake document that throws on innerHTML).
  • Request body is the JSON {"sql": ...} that /query takes. SQL is sent as written (the server trims it).
  • Starter query SELECT * FROM './' LIMIT 100. Nothing runs on load or while typing; Run button or Ctrl/Cmd+Enter.
  • Duplicate guard: an identical SQL submitted while it is in flight is ignored. A different SQL supersedes (aborts) the earlier request, and a sequence guard drops any late earlier response or failure.
  • Display cap of 1000 rows; the summary reads "N rows returned in X ms. Display limit: first 1000 shown." so truncation is separate from the returned count.
  • Zero rows: "0 rows returned ... Column names are not available for an empty result." and no table or headers.
  • Errors: HTTP 400 = "Query error" (read-only rejection and SQL errors), other statuses = "Server error (HTTP n)", fetch failure = "Could not reach the server". Rendered with role="alert".
  • All values and errors are set via textContent; NULL is a marked cell; objects as JSON text; multiline kept via white-space: pre-wrap.
  • Red commit's test sent the raw SQL as the body; hand testing showed /query takes JSON, so the test and script were corrected in the green push (the other 18 red tests are unchanged).

Hand exercise (real server, headless Chrome via agent-browser)

dirsql server --frontend --port 7351 in a dir with a.txt, b.html; page at http://localhost:7351/.

  • Run on the starter query: file rows rendered (no auto-run before click).
  • SELECT path, '<img src=x onerror=alert(1)>' AS h, NULL AS n, 'a\nb' AS m ... via Ctrl+Enter: img text shown literally, NULL cell, multiline value.
  • WHERE 0: "0 rows returned in 17 ms. Column names are not available for an empty result."
  • CREATE TABLE t (a): "Query error (HTTP 400): query() only accepts read-only statements; SQLite classified this statement as a write".
  • SELECT FROM: "Query error (HTTP 400): SQLite error: near "FROM": syntax error".
  • 1500-row recursive CTE: "1500 rows returned in 17 ms. Display limit: first 1000 shown."
  • Server killed, Run: "Could not reach the server: Failed to fetch".

Speed-of-light proposal (not implemented)

Add a case to the existing server-query baseline (packages/python/tests/e2e/server_speed_test.py): time POST /query for the starter query SELECT * FROM './' LIMIT 100 over a fixed fixture tree against the fastest native alternative, with the same ratio ratchet. That measures the path the page uses (server query plus JSON). Keep browser rendering out of it; if wanted, measure it separately with performance.now() around renderResult for 100 and 1000 rows in a headless run.

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: pass
  • TypeScript SDK e2e: pass
  • Rust core e2e: pass (cargo test --features cli --test cli_e2e --test frontend_js, plus router unit tests)
  • packages/python/e2e-attestations/bot-1487-frontend-query-1011.json receipt written
  • packages/ts/e2e-attestations/bot-1487-frontend-query-1011.json receipt written
  • Command(s) run: maturin develop --release; testing-conventions e2e attest 'uv run python -m pytest tests/e2e/cli_version_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/extension_package_test.py tests/e2e/server_speed_test.py -x -q' (14 passed); testing-conventions e2e attest 'pnpm test:e2e' (18 passed); gated just preflight (0 failing).
  • Result summary: all pass.

Changelog / Migrations

  • Changelog fragment added under packages/rust/changelog.d/
  • Migration fragment with the same slug added under packages/rust/migrations.d/

@thekevinbot
thekevinbot merged commit 7c070e6 into main Oct 13, 2026
90 checks passed
@thekevinbot
thekevinbot deleted the bot/1487-frontend-query-1011 branch October 13, 2026 21:17
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.

Add SQL execution and results to the frontend

1 participant