Transform Bytecode Spec
RowOps compiles TransformDSL into a compact binary plan (plan_bytes) executed by the WASM engine. This document describes the v1 binary format.
Endianness and Limits
- All integers are little-endian.
op_countand string lengths areu16(max 65535).
Plan Header
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | Magic TRNS (0x54 0x52 0x4E 0x53) |
| 4 | 2 | Version (u16, currently 1) |
| 6 | 2 | Operation count (u16) |
String Encoding
Strings are encoded as:
u16length- UTF-8 bytes
Operation Encoding
Each operation begins with a 1-byte opcode, followed by op-specific payloads.
| Op | Name | Payload |
|---|---|---|
0x01 | Cast | column (string), target_type (u8) |
0x02 | Rename | from (string), to (string) |
0x03 | Derive | target (string), expr (expression bytes) |
0x04 | Filter | expr (expression bytes) |
0x05 | Lookup | column (string), table_id (u32), on_missing (u8) |
0x06 | Conditional | predicate (expression bytes), then_count (u16), then_ops, else_count (u16), else_ops |
expr is encoded as u16 length + opcode bytes.
Cast Target Types
| Value | Type |
|---|---|
0 | string |
1 | number |
2 | boolean |
3 | date |
4 | null |
Lookup on_missing
| Value | Meaning |
|---|---|
0 | null |
1 | raise_error |
2 | keep |
Expression Bytecode
Expressions are encoded as a stack-based RPN program. Each opcode is 1 byte; some opcodes carry extra data.
Push Opcodes
| Op | Name | Payload |
|---|---|---|
0x01 | PushLiteral | value_type (u8) + value |
0x02 | PushColumn | name (string) |
0x03 | PushColumnIndex | index (u16) |
Literal payloads:
| value_type | Meaning | Payload |
|---|---|---|
0x00 | null | none |
0x01 | boolean | u8 (0 or 1) |
0x02 | number | f64 |
0x03 | string | string |
Arithmetic
0x10 Add, 0x11 Sub, 0x12 Mul, 0x13 Div, 0x14 Mod, 0x15 Neg
Comparison
0x20 Eq, 0x21 Ne, 0x22 Lt, 0x23 Le, 0x24 Gt, 0x25 Ge
Logical
0x30 And, 0x31 Or, 0x32 Not
Null Handling
0x40 IsNull, 0x41 Coalesce
String Functions
0x50Upper0x51Lower0x52Trim0x53Concat0x54Substr:i32 start+u8 has_len+i32 len(ifhas_lenis 1)0x55Replace:u8 case_sensitive0x56RegexReplace:pattern(string)0x57TitleCase
Type Conversion
0x60 CastToString, 0x61 CastToNumber, 0x62 CastToBool
Example
Expression: upper(trim(col("email")))
Opcode sequence (RPN):
PushColumn("email")TrimUpper
Encoded (conceptual):
0x02 <"email"> 0x52 0x50
Related APIs
compileDSLToBytesin@rowops/corecompile_transform_planandrun_transform_arrowin@rowops/engine-wasm