ktx/docs-site/content/docs/cli-reference/ktx-sql.mdx
Andrey Avtomonov ece0dfb2c8 feat(connections): add execute-only warehouses; stop silent full-project scans
A configured warehouse was always a scan/ingest target. The only way to use a
connection purely for SQL execution (ktx sql / sql_execution) was the leaky
workaround of an empty setup.database_connection_ids — which actually re-includes
every warehouse via the 'fall back to all' branch — so e.g. a BigQuery connection
meant only for read-only queries triggered a full-billing-project scan.

- Add a per-connection scan_enabled flag (default true) to warehouse connections.
  scan_enabled: false registers the connection for execution only and never as a
  scan target.
- Route every scan-target selection path through one predicate
  (isScanTargetWarehouse): both ingest (primaryWarehouseConnectionIds, including
  the all-warehouses fallback) and setup (configuredPrimaryConnectionIds) now
  exclude execute-only connections. Setup validates the credential but skips
  scope discovery and scan for them. Execution paths are untouched — the warehouse
  descriptor still resolves, so ktx sql / sql_execution keep working.
- Scripted setup with no --database-schema no longer silently scopes the scan to
  every discovered schema/dataset: it warns with the count and names how to narrow
  (--database-schema) or opt out (scan_enabled: false).
2026-06-09 13:05:15 +02:00

107 lines
3 KiB
Text

---
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...>
```
`ktx sql` runs against any configured connection, whether or not it is a scan or
ingest target. Connections marked `scan_enabled: false` (execute-only) work here
too — see [execute-only connections](/docs/configuration/ktx-yaml#execute-only-connections).
## 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. |