Tabular OperatorsOther Operators
annotate
Adds type annotations to dynamic columns, enabling forward-flow type inference and zero-copy access when runtime type matches annotation.
Adds type annotations to dynamic columns, enabling forward-flow type inference and zero-copy access when runtime type matches annotation.
Annotations propagate through project/extend: | project y = x.nested makes y
inherit x.nested's annotation. When a column is rebound, its old annotation is
cleared and the source expression's annotation (if any) is propagated.
Supports scalar types (string, int, long, real, bool, datetime, timespan, guid), array types ([type]), and object types ({field:type, ...}).
Primary use case: Define schema for dynamic data like OTEL log records.
Syntax
annotate column:type, ...Add type annotations to columns
Parameters
| Name | Description |
|---|---|
| column | Column path (e.g., foo or foo.bar.baz) |
| type | Type annotation (string, int, [type], {field:type}) |
Examples
Example 1
datatable(log:dynamic)[
dynamic({"warrior":"Ragnar", "voyages":42}),
dynamic({"warrior":"Bjorn", "voyages":31})
]
| annotate log:{warrior:string, voyages:int}
| extend name = log.warrior, glory = log.voyages + 1| log (dynamic) | name (string) | glory (long) |
|---|---|---|
| {"voyages":31,"warrior":"Bjorn"} | Bjorn | 32 |
| {"voyages":42,"warrior":"Ragnar"} | Ragnar | 43 |
Example 2
datatable(cargo:dynamic)[
dynamic({"items":["silver", "gold"], "weight":150})
]
| annotate cargo:{items:[string], weight:int}
| extend first_item = cargo.items[0]| cargo (dynamic) | first_item (dynamic) |
|---|---|
| {"items":["silver","gold"],"weight":150} | "silver" |