Query Operators
Pipe operators form the backbone of any KQL query. Each operator corresponds to a SQL construct — for example, where maps to a WHERE clause, summarize maps to GROUP BY, and take maps to LIMIT. Chained operators are composed as nested subqueries when required by the target dialect.
Legend: ✅ Supported · ⚠️ Approximated · ❌ Not Supported · 🔄 Rewritten
| Operator | SQLite | MySQL | ClickHouse | PostgreSQL | Notes |
|---|---|---|---|---|---|
where | ✅ | ✅ | ✅ | ✅ | Chained where clauses are ANDed |
project | ✅ | ✅ | ✅ | ✅ | Mapped to SELECT |
project-away | ✅ | ✅ | ✅ | ✅ | Removes named columns from SELECT |
project-keep | ✅ | ✅ | ✅ | ✅ | Keeps only named columns |
project-rename | ✅ | ✅ | ✅ | ✅ | Column alias |
project-reorder | ✅ | ✅ | ✅ | ✅ | Reorders SELECT list |
extend | ✅ | ✅ | ✅ | ✅ | Adds computed columns |
summarize | ✅ | ✅ | ✅ | ✅ | Maps to GROUP BY |
summarize (no by) | ✅ | ✅ | ✅ | ✅ | Global aggregate, no GROUP BY |
order by | ✅ | ✅ | ✅ | ✅ | |
sort by | ✅ | ✅ | ✅ | ✅ | Alias for order by |
top N by | ✅ | ✅ | ✅ | ✅ | Maps to ORDER BY + LIMIT |
take | ✅ | ✅ | ✅ | ✅ | Maps to LIMIT |
limit | ✅ | ✅ | ✅ | ✅ | Alias for take |
count | ✅ | ✅ | ✅ | ✅ | Wraps as subquery + COUNT(*) |
distinct | ✅ | ✅ | ✅ | ✅ | Maps to SELECT DISTINCT |
union | ✅ | ✅ | ✅ | ✅ | UNION ALL |
union withsource= | ✅ | ✅ | ✅ | ✅ | Adds source column to each branch |
join | ✅ | ✅ | ✅ | ✅ | See Join Types |
lookup | ✅ | ✅ | ✅ | ✅ | Defaults to LEFT JOIN |
as | ✅ | ✅ | ✅ | ✅ | Table alias |
let (expression) | ✅ | ✅ | ✅ | ✅ | Inlined as expression |
let (tabular query) | ✅ | ✅ | ✅ | ✅ | Mapped to CTE |
let (function) | ⚠️ | ⚠️ | ⚠️ | ⚠️ | Stored as UDF stub only; function body not executed |
let (datatable) | ✅ | ✅ | ✅ | ✅ | CREATE TEMP TABLE + INSERT |
mv-expand | 🔄 | ❌ | ✅ | 🔄 | ClickHouse: ARRAY JOIN; Postgres: CROSS JOIN LATERAL unnest(); MySQL/SQLite: unsupported |
mv-apply | 🔄 | ❌ | ✅ | 🔄 | Same as mv-expand per dialect |
parse | ⚠️ | ⚠️ | ✅ | ⚠️ | Uses extractAll(); non-ClickHouse dialects emit unsupported warning |
parse-where | ⚠️ | ⚠️ | ✅ | ⚠️ | Like parse but also filters non-matching rows |
parse-kv | ❌ | ❌ | ✅ | ❌ | ClickHouse only via extractKeyValuePairs |
sample | ✅ | ✅ | ✅ | ✅ | ORDER BY rand() LIMIT N |
search | ⚠️ | ⚠️ | ⚠️ | ⚠️ | Approximated as LIKE %term%; no column-aware expansion |
range | ❌ | ❌ | ✅ | ✅ | ClickHouse: arrayJoin(range()); Postgres: generate_series() |
render | ✅ | ✅ | ✅ | ✅ | No-op; chart type stored as hint only |
serialize | ✅ | ✅ | ✅ | ✅ | Treated as extend |
print | ✅ | ✅ | ✅ | ✅ | SELECT without FROM |
consume | ✅ | ✅ | ✅ | ✅ | Wraps as subquery + LIMIT 0 |
invoke | ❌ | ❌ | ❌ | ❌ | No SQL equivalent for plugins |
evaluate | ❌ | ❌ | ❌ | ❌ | No SQL equivalent for plugins |
nulls first/last | ✅ | ✅ | ✅ | ✅ | Extra ORDER BY item injected |
select (KQL alias) | ✅ | ✅ | ✅ | ✅ | Mapped to project |