Skip to content

Commit 794f2b6

Browse files
authored
Update the README.md (#56)
1 parent 85b56f1 commit 794f2b6

1 file changed

Lines changed: 47 additions & 11 deletions

File tree

README.md

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ Query Kubernetes clusters using SQL or [PRQL](https://prql-lang.org). Powered by
44

55
## Features
66

7-
- **SQL and PRQL support** - Write queries in either language (auto-detected)
8-
- **Intuitive JSON paths** - Use `status.phase` instead of `status->>'phase'`
9-
- **Multi-cluster support** - Query across clusters with `_cluster` column
10-
- **Query optimizer** - Pushes filters to K8s API (namespaces, labels)
11-
- **Multiple interfaces** - Interactive REPL, batch mode, PostgreSQL wire protocol
12-
- **CRD support** - Automatically discovers and caches Custom Resource Definitions
7+
- **Dual query languages** Write SQL or [PRQL](https://prql-lang.org), auto-detected
8+
- **Intuitive JSON paths** Use `status.phase` instead of `status->>'phase'`
9+
- **Multi-cluster queries** Query across clusters with `_cluster = '*'`
10+
- **Smart optimization** — Filters pushed to K8s API (namespaces, labels, field selectors)
11+
- **Multiple interfaces** Interactive REPL, batch mode, PostgreSQL wire protocol
12+
- **Full CRD support** Automatically discovers Custom Resource Definitions
1313

1414
## Installation
1515

@@ -46,10 +46,24 @@ k8sql -q "from pods | filter status.phase == 'Running' | select {name, namespace
4646
# Multi-cluster query
4747
k8sql -c "prod-*" -q "SELECT _cluster, name FROM pods WHERE status.phase = 'Failed'"
4848

49-
# Output as JSON
49+
# Output as JSON (or YAML or CSV)
5050
k8sql -q "SELECT * FROM deployments" -o json
5151
```
5252

53+
## SQL vs PRQL
54+
55+
k8sql supports both SQL and [PRQL](https://prql-lang.org) — just write your query and it's auto-detected:
56+
57+
| Task | SQL | PRQL |
58+
|------|-----|------|
59+
| Basic query | `SELECT name FROM pods LIMIT 5` | `from pods \| select {name} \| take 5` |
60+
| Filter | `WHERE namespace = 'default'` | `filter namespace == "default"` |
61+
| Sort descending | `ORDER BY created DESC` | `sort {-created}` |
62+
| Aggregate | `COUNT(*) ... GROUP BY namespace` | `group namespace (aggregate {count this})` |
63+
| JSON field | `status.phase` or `status->>'phase'` | `status.phase` |
64+
| Regex match | `WHERE name ~ 'nginx.*'` | `filter name ~= "nginx.*"` |
65+
| Null coalesce | `COALESCE(namespace, 'default')` | `namespace ?? "default"` |
66+
5367
## CLI Options
5468

5569
```
@@ -81,9 +95,10 @@ SELECT * FROM pods WHERE _cluster IN ('prod', 'dev') -- Multiple clusters
8195
SELECT * FROM pods WHERE _cluster = '*' -- All clusters (parallel)
8296
```
8397

84-
### JSON Field Access
98+
### Intuitive JSON Access
99+
100+
Intuitive JSON path access vs the more verbose `->` operators.
85101

86-
k8sql provides intuitive dot notation for accessing nested JSON fields:
87102

88103
```sql
89104
-- Intuitive syntax (auto-converted)
@@ -120,7 +135,27 @@ SELECT json_get_str(spec, 'containers', 0, 'image') FROM pods
120135
SELECT json_get_int(spec, 'replicas') FROM deployments
121136
```
122137

123-
Available: `json_get_str`, `json_get_int`, `json_get_float`, `json_get_bool`, `json_get_json`, `json_get_array`, `json_length`, `json_keys`.
138+
Available JSON functions: `json_get_str`, `json_get_int`, `json_get_float`, `json_get_bool`, `json_get_json`, `json_get_array`, `json_length`, `json_keys`.
139+
140+
## Why PRQL?
141+
142+
[PRQL](https://prql-lang.org) (Pipelined Relational Query Language) offers a more readable alternative to SQL:
143+
144+
- **Readable pipelines** — Data flows left-to-right: `from pods | filter ... | select ...`
145+
- **Less repetition** — No need to repeat columns in GROUP BY
146+
- **Composable** — Build complex queries incrementally
147+
- **Same JSON paths** — Use `status.phase` just like in SQL
148+
149+
**PRQL-specific operators:**
150+
151+
| Operator | Meaning | Example |
152+
|----------|---------|---------|
153+
| `~=` | Regex match | `filter name ~= "nginx.*"` |
154+
| `??` | Null coalesce | `derive ns = namespace ?? "default"` |
155+
| `f"..."` | String interpolation | `derive full = f"{namespace}/{name}"` |
156+
| `-col` | Sort descending | `sort {-created}` |
157+
158+
PRQL is auto-detected when queries start with `from`, `let`, or `prql`.
124159

125160
## Query Optimization
126161

@@ -153,7 +188,8 @@ All resources share a consistent schema:
153188
| `spec` | json | Resource specification |
154189
| `status` | json | Resource status |
155190

156-
Special cases: ConfigMaps/Secrets have `data` instead of spec/status. Events have dedicated columns.
191+
Special cases: ConfigMaps/Secrets have `data` instead of spec/status. Events have dedicated columns, etc.
192+
CRDs have their top level fields discovered.
157193

158194
## REPL Commands
159195

0 commit comments

Comments
 (0)