Readyset Docs

rdst ask

Turn a plain-English question into a validated, read-only SQL query against a target.

rdst ask takes a natural-language question and generates SQL that is safe to run against your database. It validates the query before executing (read-only, valid columns, required LIMIT), shows you the SQL for confirmation, runs it with a timeout, and renders the results.

Quality depends heavily on your semantic layer: with just table and column names the LLM is guessing, with descriptions and enum meanings it is informed.

Common usage

# Simple question
rdst ask "How many customers signed up last month?" --target prod-orders

# Generate SQL without running it
rdst ask "Average order value by segment" --target prod-orders --dry-run

# Agent mode for ambiguous or multi-step questions
rdst ask "Which suppliers are most at risk of losing their top customer?" \
  --target prod-orders --agent

# Non-interactive for scripts
rdst ask "Count of orders in the last 24h" --target prod-orders --no-interactive

Modes

ModeWhen to useBehavior
DefaultClear, schema-grounded questionsLinear flow: generate SQL → confirm → execute → show results
--agentAmbiguous or multi-step questionsThe LLM iteratively explores the schema, runs EXPLAIN checks, and drafts SQL over several turns

Example interaction

$ rdst ask "What were our top 10 customers by revenue last month?" --target prod-orders

Using semantic layer (34 tables annotated).

Generated SQL:
  SELECT c.id, c.name, SUM(o.total_cents) AS revenue_cents
  FROM   customers c
  JOIN   orders    o ON o.customer_id = c.id
  WHERE  o.created_at >= DATE_TRUNC('month', NOW() - INTERVAL '1 month')
    AND  o.created_at <  DATE_TRUNC('month', NOW())
    AND  o.status = 'paid'
  GROUP BY c.id, c.name
  ORDER BY revenue_cents DESC
  LIMIT 10;

Validation: OK
  ✓ Read-only
  ✓ All referenced columns exist
  ✓ LIMIT present (10)

Execute? [Y/n] y

Results (10 rows, 78 ms):
  id       name                    revenue_cents
  ─────── ────────────────────── ──────────────
  1023    Acme Manufacturing     4,820,135
  2118    Blue Orchid Foods       3,914,200
  745     Hendricks Retail        3,120,980
  ...

How it works

rdst ask runs every question through the same pipeline:

StepWhat happens
1. Load schemaPrefer the semantic layer (fast, annotated); fall back to live introspection if no layer is configured.
2. Clarify (optional)Detect ambiguity. For example: "last month" → prompt if you want calendar month or rolling 30 days.
3. Generate SQLLLM produces candidate SQL (temperature=0.0 for determinism).
4. ValidateRead-only? All columns exist? LIMIT present? If not, retry with the error as context, up to 3 times.
5. ConfirmShow the SQL. You can accept, reject, or edit before running.
6. ExecuteRun with --timeout (default 600s). Render results.

--agent inserts a schema-exploration loop before step 3 for questions where the model needs to learn about the schema before it can write good SQL.

Flags reference

FlagWhat it does
--target <name>Target database
--dry-runGenerate and show SQL without executing it
--timeout <seconds>Query timeout (default 600)
--verboseShow detailed reasoning and intermediate steps
--agentUse agent mode (iterative schema exploration)
--no-interactiveSkip confirmation prompts (for scripts)

Get better results

The single highest-impact thing you can do for rdst ask quality is configure a semantic layer:

rdst schema init      --target prod-orders
rdst schema annotate  --target prod-orders --use-llm   # AI-generated descriptions
rdst schema show      --target prod-orders             # review
rdst schema edit      --target prod-orders             # tweak enum meanings and business terms

Before:

The LLM sees status VARCHAR(16) and has to guess what values mean.

After:

The LLM sees that status is an enum with paid, refunded, shipped, cancelled, and that paid and shipped both represent completed orders in your business.

Semantic layers are per-target. If you have ten targets with identical schemas, you can export one and import it into the others with rdst schema export / rdst schema import.

Safety guarantees

rdst ask enforces three rules on every query it generates and will never let you execute one that violates them:

  1. Read-only. No INSERT, UPDATE, DELETE, DDL, or procedure calls.
  2. Columns must exist. The validator checks every referenced column against the actual schema before executing.
  3. LIMIT is required. Prevents accidentally running unbounded scans.

On top of this, the generated query is shown to you for confirmation before execution. --no-interactive bypasses the confirmation prompt but does not bypass the validation rules.

See also

  • rdst schema — how to build the semantic layer that powers ask
  • rdst analyze — when you already have a SQL query and want performance insights instead
  • Data agents — expose ask-style access to external clients with stricter safety policies