Skip to main content

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

OperatorSQLiteMySQLClickHousePostgreSQLDuckDBNotes
whereChained where clauses are ANDed
projectMapped to SELECT
project-awayRemoves named columns from SELECT
project-keepKeeps only named columns
project-renameColumn alias
project-reorderReorders SELECT list
extendAdds computed columns
summarizeMaps to GROUP BY
summarize (no by)Global aggregate, no GROUP BY
summarize (named by key)e.g. by Day = bin(T, 1d)SELECT <expr> AS Day … GROUP BY Day
order by
sort byAlias for order by
top N byMaps to ORDER BY + LIMIT
top-nested⚠️⚠️⚠️⚠️⚠️Hierarchical top-N via ROW_NUMBER(), up to 2 levels; 3+ levels and the with others= bucket are not supported
top-hittersLowered to GROUP BY … ORDER BY <metric> DESC LIMIT N
takeMaps to LIMIT
limitAlias for take
countWraps as subquery + COUNT(*)
distinctMaps to SELECT DISTINCT
unionUNION ALL
union withsource=Adds source column to each branch
joinSee Join Types
lookupDefaults to LEFT JOIN
asTable alias
let (expression)Inlined as expression
let (tabular query)Mapped to CTE
let (function)⚠️⚠️⚠️⚠️⚠️Inlined when invoked at the top levellet parser = (p){ … }; parser(…), the wrapped ASIM-parser shape — where its inner lets and query are visited in place. Called from inside an expression it is not substituted, and its parameters are never bound to the arguments
let (datatable)CREATE TEMP TABLE + INSERT
mv-expand🔄🔄ClickHouse ARRAY JOIN; PostgreSQL/DuckDB CROSS JOIN LATERAL unnest(); SQLite/MySQL unsupported
mv-apply🔄🔄Same per-dialect handling as mv-expand, with the per-element sub-pipeline applied
parse⚠️⚠️ClickHouse extractAll, DuckDB regexp_extract_all; SQLite/MySQL/PostgreSQL have no extract-all function. The named columns the pattern declares are not produced — the SELECT is replaced by a single unaliased array of every capture, so results have to be indexed positionally
parse-where⚠️⚠️Like parse plus a row filter, and it loses the column names the same way
parse-kvClickHouse extractKeyValuePairs; DuckDB per-key regexp_extract; others unsupported
forkNot implemented. One query cannot branch into several result sets in this transpiler
make-seriesGap-filled series: ClickHouse -Resample combinator; PostgreSQL/DuckDB explicit grid + LEFT JOIN + array fill; SQLite/MySQL unsupported
sampleORDER BY rand()/random() LIMIT N
sample-distinctSELECT DISTINCT <col> … LIMIT N
partition⚠️⚠️⚠️⚠️⚠️Only the summarize and top sub-forms are lowered; a general per-partition subquery is unsupported
searchNo SQL equivalent — emitted as UNSUPPORTED on all dialects
rangeClickHouse arrayJoin(range()); PostgreSQL generate_series(); DuckDB UNNEST(generate_series()); SQLite/MySQL unsupported
renderNo-op; chart type stored as hint only
serializeTreated as extend
printSELECT without FROM
consumeWraps as subquery + LIMIT 0
invokeNo SQL equivalent for plugins
evaluateNo SQL equivalent for plugins (except bag_unpack, below)
evaluate bag_unpack⚠️⚠️⚠️Keys inferred from static dynamic(...) literals; ClickHouse * EXCEPT, PostgreSQL/DuckDB * EXCLUDE; runtime-only bags, MySQL and SQLite unsupported
evaluate pivotNo SQL equivalent
externaldataExternal file source — no SQL equivalent
getschemaNot translated to SQL
scanStateful row-sequence operator — no set-based SQL equivalent
nulls first/lastExtra ORDER BY item injected
select (KQL alias)Mapped to project