feat(cli): add read-only sql command (#126)

* feat(cli): add read-only sql command

* fix(cli): rename sql connection flag
This commit is contained in:
Andrey Avtomonov 2026-05-17 10:29:07 +02:00 committed by GitHub
parent c89af7733a
commit 33a142f769
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 742 additions and 1 deletions

View file

@ -25,6 +25,7 @@ ktx
search <query>
validate <sourceName>
query
sql
status
mcp
start
@ -79,6 +80,9 @@ ktx ingest --all
ktx sl search "revenue"
ktx wiki search "revenue recognition"
# Execute read-only SQL
ktx sql --connection warehouse "select count(*) from public.orders"
# Start the local MCP server for agent clients
ktx mcp start
```

View file

@ -0,0 +1,103 @@
---
title: "ktx sql"
description: "Execute parser-validated read-only SQL against a configured connection."
---
Run read-only SQL against a database connection in your KTX project. The command
validates the statement before execution and only accepts a single `SELECT` or
`WITH` query.
## Command signature
Use `ktx sql` with a required connection id and positional SQL text.
```bash
ktx sql --connection <id> [options] <sql...>
```
## Options
Use output flags to choose between terminal display, TSV rows, and structured
JSON.
| Flag | Description | Default |
|------|-------------|---------|
| `-c`, `--connection <id>` | KTX database connection id. Required. | - |
| `--max-rows <n>` | Maximum rows to return. Must be between `1` and `10000`. | `1000` |
| `--output <mode>` | Output mode: `pretty`, `plain` (TSV), or `json`. | `pretty` |
| `--json` | Shortcut for `--output=json` (overrides `--output`). | `false` |
## Examples
Quote SQL in shell scripts and when the query contains spaces or punctuation.
```bash
# Count rows in a table
ktx sql --connection warehouse "select count(*) from public.orders"
# Return a small result set
ktx sql \
--connection warehouse \
--max-rows 25 \
"select id, status from public.orders order by created_at desc"
# Print JSON for agents or scripts
ktx sql \
--connection warehouse \
--json \
"select status, count(*) from public.orders group by status"
# Print TSV rows
ktx sql \
-c warehouse \
--output plain \
"select id, status from public.orders"
```
## Output
Pretty output prints aligned columns and a final row count.
```text
status count
------ -----
paid 42
open 7
2 rows
```
Plain output prints a TSV header row followed by TSV data rows.
```text
status count
paid 42
open 7
```
JSON output preserves connection id, headers, optional header types, rows, and
row count.
```json
{
"connectionId": "warehouse",
"headers": ["status", "count"],
"headerTypes": ["text", "bigint"],
"rows": [
["paid", 42],
["open", 7]
],
"rowCount": 2
}
```
## Common errors
Use the error text to distinguish validation failures from connection failures.
| Error | Cause | Recovery |
|-------|-------|----------|
| `Only one SQL statement can be executed.` | The SQL text contains multiple statements. | Run one query at a time. |
| `SQL contains read/write operation` | The statement is not read-only. | Use a single `SELECT` or `WITH` query. |
| `Connection "<id>" is not configured in ktx.yaml` | The connection id is wrong or missing from the project. | Run `ktx connection list` and retry with an exact id. |
| `does not support read-only SQL execution` | The connection type has no local SQL executor. | Use a supported database connection or query through MCP where available. |

View file

@ -7,6 +7,7 @@
"ktx-connection",
"ktx-ingest",
"ktx-sl",
"ktx-sql",
"ktx-wiki",
"ktx-status",
"ktx-mcp",