Every operator in the pipe catalog. This file is generated from
pipe.Reference() — edit pipe/catalog.go and run make generate.
A pipe is an ordered chain of these operators applied to a stream of rows. They appear below in catalog order, which follows the shape of a typical pipe: source, filter, transform, aggregate, sort, side effect.
| Column | Meaning |
|---|---|
| Live-safe | Pure and deterministic with default config, so it can run on a live-updating result set. |
| Pushable | Can fold into the SQL prefix. The planner makes the final call from the field types. |
| Requires | Host services the operator needs in its OpContext. Blank means it works anywhere. |
| Operator | Summary | Live-safe | Pushable | Requires |
|---|---|---|---|---|
filter |
Keep rows that match a predicate | ✅ | ✅ | eval |
project |
Select / alias columns | ✅ | ✅ | |
rename |
Rename columns | ✅ | ✅ | |
drop |
Remove columns | ✅ | — | |
compute |
Add a computed column | ✅ | — | eval, formula |
sheet |
Evaluate a set of formulas in dependency order | ✅ | — | exprCompiler |
transform |
Compute multiple columns in one stage | ✅ | — | eval |
cast |
Convert column types | ✅ | — | |
dropNulls |
Drop rows with nulls in named columns | ✅ | ✅ | |
fillNulls |
Replace nulls in named columns | ✅ | — | |
flatten |
Unnest an array column | ✅ | — | |
unnestObject |
Spread an object column into root keys | ✅ | — | |
nest |
Group rows into nested arrays | ✅ | — | |
pivot |
Rows → columns | ✅ | — | |
unpivot |
Columns → rows | ✅ | — | |
distinct |
Deduplicate rows | ✅ | — | |
dedupe |
Keep one row per identity key | ✅ | — | |
sample |
Random subset of rows | ✅ | — | |
assert |
Fail the query when an expression is false | ✅ | — | eval |
timeBucket |
Bucket rows into fixed time intervals | ✅ | — | |
gapfill |
Fill missing time intervals | ✅ | — | |
sort |
Order rows | ✅ | ✅ | |
limit |
Cap row count | ✅ | ✅ | |
skip |
Drop the first N rows | ✅ | ✅ | |
topPerGroup |
Top N rows per partition | ✅ | — | |
groupBy |
Set keys for the next aggregate | ✅ | ✅ | |
aggregate |
Fold rows into groups | ✅ | ✅ | |
histogram |
Bucket numeric values into equal-width bins | ✅ | — | |
window |
Per-row computation within a partition | ✅ | — | |
lookup |
Hash-join with another dataset | ✅ | — | classic |
asofJoin |
Join on the closest timestamp | ✅ | — | classic |
crossJoin |
Cartesian product with another dataset | ✅ | — | classic |
intersect |
Rows present in every source | ✅ | — | classic |
except |
Rows in left but not in right | ✅ | — | classic |
callFunction |
Invoke a registered DTL function | — | — | functionRegistry |
callApp |
Invoke a managed app | — | — | appCaller |
algo |
Run a registered algorithm | — | — | algorithms |
branch |
Per-row conditional sub-pipes | ✅ | — | eval |
merge |
Fan-out then concat | ✅ | — | |
tap |
Pass-through with a debug label | ✅ | — |
Keep rows that match a predicate
Live-safe by default: yes Pushable: yes Requires: eval
Filters rows by a WHERE clause. Plain field/op/value forms push down to SQL; DTL expr forms run in-memory.
| Field | Type | Required | Description |
|---|---|---|---|
where |
any | yes | Conditions a row must satisfy to be kept. Use simple {field, op, value} shape for SQL-pushable filters, or {expr: "…"} for DTL expressions evaluated in-memory. |
Plain comparison
{
"op": "filter",
"where": {
"field": "level",
"op": "==",
"value": "ERROR"
}
}DTL expression
{
"op": "filter",
"where": {
"expr": "ts > now() - duration(\"1h\")"
}
}Select / alias columns
Live-safe by default: yes Pushable: yes
Reduces each row to a chosen subset of columns, optionally renaming them.
| Field | Type | Required | Description |
|---|---|---|---|
select |
array | Columns to keep, in order. Each entry is {field, as?} — set as to rename. |
|
drop |
array of string | Alternative to select — instead of listing what to keep, list what to remove. Mutually exclusive with select. |
Pick fields
{
"op": "project",
"select": [
{
"field": "id"
},
{
"field": "name"
}
]
}Rename columns
Live-safe by default: yes Pushable: yes
Rewrites column keys in-place. The map is from -> to.
| Field | Type | Required | Description |
|---|---|---|---|
map |
object | yes | Object whose keys are the existing column names and whose values are the new names. Pairs not listed are left untouched. (input: column-rename-map) |
id → key
{
"map": {
"id": "key"
},
"op": "rename"
}Remove columns
Live-safe by default: yes Pushable: no
Deletes the named columns from each row.
| Field | Type | Required | Description |
|---|---|---|---|
columns |
array of string | yes | Names of columns to remove from every row. |
Drop secrets
{
"columns": [
"password",
"secret"
],
"op": "drop"
}Add a computed column
Live-safe by default: yes Pushable: no Requires: eval, formula
Evaluates a DTL expression (kind:"expr") or Excel-style formula (kind:"formula") per row and stores the result under as.
| Field | Type | Required | Description |
|---|---|---|---|
as |
string | yes | Column to write the computed value into. Overwrites any existing column with the same name. (input: column-output) |
kind |
string | Which language expr / formula is in. Defaults to DTL expr. Default: expr. |
|
expr |
string | conditional {"kind":["expr",""]} | DTL expression evaluated against each row. Used when kind is expr. (input: dtl-expression) |
formula |
string | conditional {"kind":["formula"]} | Spreadsheet formula evaluated against each row. Used when kind is formula. (input: formula) |
DTL expr
{
"as": "doubled",
"expr": "value * 2",
"op": "compute"
}Formula
{
"as": "tax",
"formula": "price * 0.1",
"kind": "formula",
"op": "compute"
}Evaluate a set of formulas in dependency order
Live-safe by default: yes Pushable: no Requires: exprCompiler
Each formula sets either expr (one value per row) or reduce (one value for the whole stage). Formulas may reference each other by name and run in the order their references imply, not the order they are written in. A reduce is written into every row, so the next stage sees it as an ordinary column.
There are no window functions here on purpose. Put a window stage before the sheet and read its output column like any other — that keeps ordering and partitioning explicit, which an inline lag() would have to leave implicit.
| Field | Type | Required | Description |
|---|---|---|---|
formulas |
array of object | yes | Named calculations, ordered by what they reference. |
onError |
string | fail (default) aborts on the first evaluation error. null writes null into the failing cell and continues. Default: fail. |
|
columnBudgetBytes |
integer | Caps the bytes of materialised columns held at once, spilling the least recently used beyond it. Leave unset unless the sheet reduces over many distinct columns that cannot be delegated to the source. |
Profit share
{
"formulas": [
{
"as": "profit",
"expr": "revenue - cost"
},
{
"as": "total_profit",
"reduce": "sum(profit)"
},
{
"as": "share",
"expr": "profit / total_profit"
}
]
}Compute multiple columns in one stage
Live-safe by default: yes Pushable: no Requires: eval
Like compute but takes a list. Entries evaluate in order and can reference earlier results. Use from for plain column copies and replace: true to drop everything not produced.
| Field | Type | Required | Description |
|---|---|---|---|
compute |
array of object | yes | Ordered list of column definitions. Each entry uses expr (DTL) or from (column copy). |
drop |
array of string | Optional. Columns to remove from the output after computation. | |
replace |
boolean | When true, drop every column not produced by compute. Useful for reshape-and-rename in one step. Default: false. |
Add several columns
{
"compute": [
{
"as": "total",
"expr": "a + b"
},
{
"as": "ratio",
"expr": "a / b"
}
],
"op": "transform"
}Reshape
{
"compute": [
{
"as": "id",
"from": "_id"
},
{
"as": "score",
"expr": "wins / matches"
}
],
"op": "transform",
"replace": true
}Convert column types
Live-safe by default: yes Pushable: no
Coerce columns to int / float / bool / string / timestamp. onError chooses null (default) | skip | fail.
| Field | Type | Required | Description |
|---|---|---|---|
casts |
array of object | yes | List of {field, to, onError?} rules applied in order. |
Drop rows with nulls in named columns
Live-safe by default: yes Pushable: yes
When any is true (default) drops rows where ANY listed column is null; when false drops only when EVERY listed column is null.
| Field | Type | Required | Description |
|---|---|---|---|
columns |
array of string | Columns inspected for null. Empty means every column on each row. | |
any |
boolean | When true, drop a row if ANY listed column is null. When false, drop only when EVERY listed column is null. Default: true. |
Replace nulls in named columns
Live-safe by default: yes Pushable: no
Methods: zero, value, lastValue, nextValue, mean. lastValue/nextValue require partitionBy + orderBy for deterministic forward/backward fill.
| Field | Type | Required | Description |
|---|---|---|---|
method |
string | value uses the literal value; zero uses 0; lastValue carries the previous non-null forward; nextValue carries the next non-null backward; mean uses the column mean. Default: value. |
|
value |
any | conditional {"method":["value"]} | Used when method is value. Any JSON scalar. |
columns |
array of string | Columns whose null cells are replaced. Empty means every column on each row. | |
partitionBy |
array of string | conditional {"method":["lastValue","nextValue"]} | Required for lastValue / nextValue. Within each partition, ordering and carry semantics apply independently. |
orderBy |
array | conditional {"method":["lastValue","nextValue"]} | Required for lastValue / nextValue to define what "previous" / "next" means within a partition. |
Unnest an array column
Live-safe by default: yes Pushable: no
Emits one row per array element. When as is set, the element is stored under that key and the original field is preserved.
| Field | Type | Required | Description |
|---|---|---|---|
field |
string | yes | Column whose array values are exploded into separate rows. (input: column) |
as |
string | Optional. Column name to store each element under. When unset, the element replaces the array column on each row. (input: column-output) | |
indexAs |
string | Optional. Column name to store the element's 0-based index in the source array. (input: column-output) | |
preserveEmpty |
boolean | When true, rows whose array is empty or null still produce one output row (with the element column nil). Default drops them. Default: false. |
Unnest tags
{
"field": "tags",
"op": "flatten"
}Spread an object column into root keys
Live-safe by default: yes Pushable: no
Useful for JSONB/metadata blobs whose nested keys you want as top-level columns.
| Field | Type | Required | Description |
|---|---|---|---|
field |
string | yes | Column whose object value's keys are spread onto the root row. (input: column) |
prefix |
string | Optional. Prepended to every spread key (e.g. m_ produces m_owner). (input: prefix) |
|
drop |
boolean | When true, the original object column is removed after spreading. Default: false. |
Group rows into nested arrays
Live-safe by default: yes Pushable: no
Inverse of flatten: emits one row per group with the remaining columns collected into an array under into.
| Field | Type | Required | Description |
|---|---|---|---|
by |
array of string | yes | Partition keys; one output row is emitted per unique combination. |
into |
string | yes | Name of the output column where the per-group array of nested records is stored. (input: column-output) |
include |
array of string | Optional. Columns to include in each nested record. Defaults to every column not in by. |
Rows → columns
Live-safe by default: yes Pushable: no
Each unique value in columnKey becomes a column. aggregate controls how to combine duplicates (sum/avg/count/min/max/first/last).
| Field | Type | Required | Description |
|---|---|---|---|
rowKeys |
array of string | Columns whose distinct combinations identify each output row. | |
columnKey |
string | yes | Column whose distinct values become the names of new columns. (input: column) |
valueField |
string | yes | Column whose values populate the cells. (input: column) |
aggregate |
string | How to combine multiple input rows that map to the same cell. Default: first. |
|
fillValue |
any | Value to use for output cells with no source row. Defaults to null. | |
prefix |
string | Optional string prepended to every generated column name. (input: prefix) |
Columns → rows
Live-safe by default: yes Pushable: no
Melts named columns into name/value pairs (one output row per input row × valueCol).
| Field | Type | Required | Description |
|---|---|---|---|
idCols |
array of string | Columns kept verbatim on every output row. Empty means every column not in valueCols. |
|
valueCols |
array of string | Columns whose values are unstacked into rows. Empty means every column not in idCols. |
|
nameAs |
string | yes | Output column that records the source column name. (input: column-output) |
valueAs |
string | yes | Output column that records the cell value. (input: column-output) |
Deduplicate rows
Live-safe by default: yes Pushable: no
When by is empty, uniqueness uses every column; otherwise only the named keys.
| Field | Type | Required | Description |
|---|---|---|---|
by |
array of string | Columns whose combined values define a row's identity. Leave empty to deduplicate using every column. |
Keep one row per identity key
Live-safe by default: yes Pushable: no
Different from distinct (full-row equality): pick first or last row per key, with optional ordering.
| Field | Type | Required | Description |
|---|---|---|---|
by |
array of string | yes | Columns whose combined values define a row's identity. |
keep |
string | Whether to keep the first row encountered per identity (first) or the last (last). Combined with orderBy for deterministic results. Default: first. |
|
orderBy |
array | Optional. Sort applied within each identity group before applying keep. |
Random subset of rows
Live-safe by default: yes Pushable: no
Either n (target size) or ratio (0..1). seed makes output deterministic. Method: random (reservoir) | systematic (every k-th).
| Field | Type | Required | Description |
|---|---|---|---|
method |
string | random uses reservoir sampling; systematic keeps every k-th row. Default: random. |
|
n |
integer | Sample size in rows. Mutually exclusive with ratio. |
|
ratio |
number | Fraction of input rows to keep, between 0 and 1. Mutually exclusive with n. |
|
seed |
integer | Optional integer seed for deterministic sampling. Same seed + same input ⇒ same output. |
Fail the query when an expression is false
Live-safe by default: yes Pushable: no Requires: eval
Runtime guardrail. scope=row evaluates per row; scope=overall checks once with count available.
| Field | Type | Required | Description |
|---|---|---|---|
scope |
string | row evaluates the expression per row; overall evaluates once at the end with the row count available. Default: row. |
|
expr |
string | yes | DTL expression that must be truthy. Falsy results fail the query. (input: dtl-expression) |
message |
string | Custom error message returned when the assertion fails. |
Bucket rows into fixed time intervals
Live-safe by default: yes Pushable: no
Adds a column with the start of the bucket containing each row's timestamp. Pair with groupBy + aggregate for time-series rollups.
| Field | Type | Required | Description |
|---|---|---|---|
field |
string | yes | Column carrying the row's timestamp. (input: column) |
interval |
string | yes | Duration string for the bucket width — "5m", "1h", "1d". (input: duration) |
as |
string | yes | Column to write the bucket-start timestamp into. (input: column-output) |
tz |
string | Optional IANA timezone (e.g. America/New_York) used to align bucket boundaries. Defaults to UTC. (input: timezone) |
|
origin |
string | Optional RFC3339 anchor that defines where buckets start. Defaults to the Unix epoch. (input: timestamp) |
5-minute buckets
{
"as": "bucket",
"field": "ts",
"interval": "5m",
"op": "timeBucket"
}Fill missing time intervals
Live-safe by default: yes Pushable: no
Emits synthetic rows for time buckets missing from the input. Useful before charting sparse sensor streams.
| Field | Type | Required | Description |
|---|---|---|---|
field |
string | yes | Column carrying the row's timestamp. (input: column) |
interval |
string | yes | Duration string ("5m", "1h") describing the gap between expected timestamps. (input: duration) |
method |
string | How to populate value columns on synthetic rows: zero, null, lastValue (carry forward), or value (use the literal value field). Default: null. |
|
value |
any | conditional {"method":["value"]} | Used when method is value. Any JSON scalar. |
from |
string | Optional RFC3339 lower bound. Defaults to the earliest timestamp in the input. (input: timestamp) | |
to |
string | Optional RFC3339 upper bound. Defaults to the latest timestamp in the input. (input: timestamp) | |
groupBy |
array of string | Optional. Treat the input as multiple independent time series, gapfilling each partition separately. | |
carry |
array of string | conditional {"method":["lastValue"]} | Columns whose value is copied from the most recent real row when method is lastValue. |
Order rows
Live-safe by default: yes Pushable: yes
Sorts by one or more keys. Direction defaults to asc.
| Field | Type | Required | Description |
|---|---|---|---|
by |
array | yes | Ordered list of {field, dir} keys. Earlier entries are the primary sort; later entries break ties. |
Top 10 by ts
{
"by": [
{
"dir": "desc",
"field": "ts"
}
],
"op": "sort"
}Cap row count
Live-safe by default: yes Pushable: yes
| Field | Type | Required | Description |
|---|---|---|---|
n |
integer | yes | Keep at most this many rows. Set to 0 to drop everything. |
Drop the first N rows
Live-safe by default: yes Pushable: yes
| Field | Type | Required | Description |
|---|---|---|---|
n |
integer | yes | Number of rows to discard from the start of the input. Combined with limit gives offset/page semantics. |
Top N rows per partition
Live-safe by default: yes Pushable: no
Keeps the highest- (or lowest-) ranked N rows per group. With no partition, equivalent to top N overall.
| Field | Type | Required | Description |
|---|---|---|---|
n |
integer | yes | How many rows to keep per partition (1 = top-1). |
partitionBy |
array of string | Optional. Columns that split the input into partitions. Empty = single partition (top-N overall). | |
by |
array | yes | Sort keys used to rank rows within each partition. The first key is primary; later keys break ties. |
Set keys for the next aggregate
Live-safe by default: yes Pushable: yes
On its own this is a pass-through. The planner pairs it with the immediately-following aggregate op.
| Field | Type | Required | Description |
|---|---|---|---|
keys |
array of string | yes | Columns whose unique combinations define each group. The downstream aggregate folds rows within each combination. |
Fold rows into groups
Live-safe by default: yes Pushable: yes
Computes COUNT, SUM, AVG, MIN, MAX over groups defined by a preceding groupBy (or the whole stream when standalone).
| Field | Type | Required | Description |
|---|---|---|---|
keys |
array of string | Optional. Same shape as groupBy.keys — when set, the aggregate uses these keys directly without a preceding groupBy stage. |
|
aggs |
array | yes | Ordered list of {fn, field, as} clauses (e.g. {fn: "SUM", field: "amount", as: "total"}). |
Bucket numeric values into equal-width bins
Live-safe by default: yes Pushable: no
Replaces input rows with one row per bin: {binStart, binEnd, count}. Provide explicit min/max or let the op derive them.
| Field | Type | Required | Description |
|---|---|---|---|
field |
string | yes | Column whose numeric values are bucketed. (input: column) |
bins |
integer | yes | Number of equal-width bins to produce. |
min |
number | Optional lower bound. Defaults to the minimum value seen in the input. | |
max |
number | Optional upper bound. Defaults to the maximum value seen in the input. | |
asCount |
string | Output column for the per-bin count. (input: column-output) Default: count. |
|
asStart |
string | Output column for each bin's lower edge. (input: column-output) Default: binStart. |
|
asEnd |
string | Output column for each bin's upper edge. (input: column-output) Default: binEnd. |
Per-row computation within a partition
Live-safe by default: yes Pushable: no
row_number, rank, dense_rank, lag, lead, first_value, last_value. Output preserves input row order.
| Field | Type | Required | Description |
|---|---|---|---|
fn |
string | yes | Which windowing function to compute per row. |
partitionBy |
array of string | Columns that split the input into independent windows. Within each partition, the function is computed in orderBy order. |
|
orderBy |
array | Sort keys applied within each partition before the function runs. Required for ranking/lag/lead semantics. | |
field |
string | conditional {"fn":["lag","lead","first_value","last_value"]} | Column the window function reads. Required for lag/lead/first_value/last_value; ignored for ranking functions. (input: column) |
offset |
integer | Row offset for lag/lead. Defaults to 1 row. |
|
default |
any | Value to emit when the window function falls outside the partition (e.g. lag(1) on the first row). |
|
as |
string | yes | Column to write the window value into. (input: column-output) |
Hash-join with another dataset
Live-safe by default: yes Pushable: no Requires: classic
Fetches the right side via a secondary classic query. Use cacheTtlMs to avoid re-fetching on every live update.
| Field | Type | Required | Description |
|---|---|---|---|
dataset |
string | yes | Dataset name to fetch the join's right side from. (input: dataset) |
on |
object | yes | Column names on each side that must equal for a match. |
mode |
string | left keeps every left row; inner drops left rows with no match. Default: left. |
|
as |
string | Optional. When set, the matched right-side row is nested under this column instead of being flattened into the left row. (input: column-output) | |
select |
array of string | Optional. Subset of right-side columns to merge in. Empty means all columns. | |
where |
any | Optional WHERE clause applied to the right-side dataset before the join. | |
limit |
integer | Optional. Cap the number of right-side rows fetched (useful when dataset is large). |
|
cacheTtlMs |
integer | Cache the right-side fetch for this many milliseconds. 0 disables caching. Useful when the same lookup runs many times under live mode. Default: 0. |
Join on the closest timestamp
Live-safe by default: yes Pushable: no Requires: classic
For each left row, finds the right row with the closest timestamp on a matching key. Direction backward (default) | forward | nearest, with optional tolerance.
| Field | Type | Required | Description |
|---|---|---|---|
dataset |
string | yes | Dataset to fetch the right side from. (input: dataset) |
leftTime |
string | yes | Column on the streaming (left) side carrying the row's timestamp. (input: column) |
rightTime |
string | yes | Column on the looked-up (right) side carrying the row's timestamp. (input: dataset-column) |
leftKey |
string | Optional. Column on the left whose value must equal rightKey for a match. (input: column) |
|
rightKey |
string | Optional. Column on the right whose value must equal leftKey for a match. (input: dataset-column) |
|
direction |
string | backward finds the latest right row at or before the left row; forward the earliest at or after; nearest the absolute closest. Default: backward. |
|
tolerance |
string | Optional duration ("1m", "30s"). Drops matches further than this from the left row's timestamp. (input: duration) |
|
as |
string | Optional. When set, the matched right row is nested under this column. (input: column-output) | |
select |
array of string | Optional subset of right-side columns to merge in. Empty means all columns. | |
where |
any | Optional WHERE clause applied to the right-side dataset before the join. | |
limit |
integer | Optional cap on right-side rows fetched. |
Cartesian product with another dataset
Live-safe by default: yes Pushable: no Requires: classic
Output size is N × M — use sparingly. Right-side rows can be filtered with where and capped with limit.
| Field | Type | Required | Description |
|---|---|---|---|
dataset |
string | yes | Dataset to fetch the cartesian-product right side from. (input: dataset) |
as |
string | Optional. When set, each right row is nested under this column instead of being flattened into the left row. (input: column-output) | |
select |
array of string | Optional subset of right-side columns to merge in. Empty means all columns. | |
where |
any | Optional WHERE clause applied to the right-side dataset before the cross-join. | |
limit |
integer | Optional cap on right-side rows. Strongly recommended to bound output size. |
Rows present in every source
Live-safe by default: yes Pushable: no Requires: classic
Set intersection across N sub-pipes, identified by by keys (or full-row equality).
| Field | Type | Required | Description |
|---|---|---|---|
sources |
array of object | yes | Two or more sub-pipes. Output rows are those present in every sub-pipe (under the chosen identity). |
by |
array of string | Optional. When set, intersection compares only these columns. Empty falls back to full-row equality. |
Rows in left but not in right
Live-safe by default: yes Pushable: no Requires: classic
| Field | Type | Required | Description |
|---|---|---|---|
left |
object | yes | Source whose rows are kept when not present in right. |
right |
object | yes | Source whose rows are subtracted from left. |
by |
array of string | Optional. When set, set difference compares only these columns. Empty falls back to full-row equality. |
Invoke a registered DTL function
Live-safe by default: no Pushable: no Requires: functionRegistry
Calls a function from the function extension. pure: true declares the function side-effect-free and makes it live-safe.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Fully qualified DTL function name (e.g. geo::lookup). (input: function-name) |
mode |
string | perRow calls the function once per row; batch passes the whole row stream to the function once. Default: perRow. |
|
pure |
boolean | When true, asserts the function has no side effects so live mode can re-run it on each update. Default: false. |
|
args |
object | Object passed to the function. Values may reference row columns via $columnName. |
|
literalArgs |
boolean | When true, $column-style refs in args are passed verbatim instead of resolved against the row. |
|
as |
string | Column to store the function result under. (input: column-output) |
Per-row pure
{
"args": {
"x": "$value"
},
"name": "math::abs",
"op": "callFunction",
"pure": true
}Invoke a managed app
Live-safe by default: no Pushable: no Requires: appCaller
Calls an external app via the runtime extension. Always non-live-safe; live subscriptions require dryRun: true.
| Field | Type | Required | Description |
|---|---|---|---|
appId |
string | yes | Identifier of the managed app to invoke. (input: app-id) |
method |
string | App method to call. Defaults to transform. Default: transform. |
|
capability |
string | Capability namespace the app must expose. Defaults to pipe_query. Default: pipe_query. |
|
batch |
boolean | When true, the entire row stream is sent to the app once. When false, the app is invoked per row. Default: true. |
|
payload |
object | Object merged into the app invocation payload alongside the rows. | |
dataset |
string | Optional dataset name passed to the app for context. (input: dataset) |
Run a registered algorithm
Live-safe by default: no Pushable: no Requires: algorithms
Invokes a native or external algorithm from the shared catalog (e.g. minmax_scale, kmeans, robust_zscore). params are forwarded verbatim to the algorithm — see its descriptor for accepted keys. Live-safety depends on the chosen algorithm: pure ones (most ETL transforms) are live-safe; external/stateful ones are not.
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Identifier of a registered algorithm (e.g. minmax_scale, kmeans). Must exist in the algorithm catalog or the stage fails at build time. |
params |
object | Algorithm-specific options passed through unchanged. Each algorithm documents its own keys in its catalog descriptor (e.g. minmax_scale takes column and as). |
Min-max scale a column
{
"name": "minmax_scale",
"op": "algo",
"params": {
"as": "v_scaled",
"column": "v"
}
}Per-row conditional sub-pipes
Live-safe by default: yes Pushable: no Requires: eval
Routes each row through then or else based on a DTL predicate. Live-safety propagates from the children.
| Field | Type | Required | Description |
|---|---|---|---|
when |
string | yes | DTL expression evaluated per row. Truthy results take the then branch. (input: dtl-expression) |
then |
array | yes | Stages applied to rows where the predicate is truthy. |
else |
array | Optional. Stages applied to rows where the predicate is falsy. Empty drops the row. |
Fan-out then concat
Live-safe by default: yes Pushable: no
Runs each sub-pipe against a clone of the input and concatenates outputs.
| Field | Type | Required | Description |
|---|---|---|---|
sources |
array of object | yes | List of sub-pipes. Each receives a clone of the input rows; outputs are concatenated in order. |
Pass-through with a debug label
Live-safe by default: yes Pushable: no
Records the row count against a label and returns rows unchanged.
| Field | Type | Required | Description |
|---|---|---|---|
label |
string | Label that surfaces in stats.pipe[].label so this checkpoint is identifiable in the response. |