Programs
A compiled Ferret query can be serialized into a binary artifact and loaded later without the compiler. This is useful for distributing pre-compiled queries, skipping compilation at runtime, or caching build output on disk.
Two paths to a Plan
There are two ways to get a Plan from the engine:
Both produce the same *Plan that you create sessions from and run. The difference is where the bytecode comes from: the compiler or a serialized artifact.
Serializing a program
The artifact package provides Marshal to serialize a compiled program:
The default payload format is MessagePack. To use JSON instead, set the format in the options:
Loading a program
Load the artifact back into the engine with engine.Load:
For lower-level access, ferret.UnmarshalProgram returns a *bytecode.Program without wrapping it in a plan:
Artifact format
An artifact is a self-describing binary format with a 14-byte header followed by the encoded payload:
| Bytes | Field | Type | Description |
|---|---|---|---|
| 0–3 | Magic | [4]byte |
FBC2 — identifies the file as a Ferret artifact |
| 4 | Format | uint8 |
Payload format ID (1 = JSON, 2 = MessagePack) |
| 5 | Schema | uint8 |
Schema version (currently 1) |
| 6–7 | ISA | uint16 LE |
Bytecode instruction set version |
| 8–9 | Flags | uint16 LE |
Reserved (must be 0 in schema v1) |
| 10–13 | Length | uint32 LE |
Payload length in bytes |
All multi-byte fields are little-endian. The header is followed by exactly Length bytes of payload data in the format specified by the Format field.
Payload formats
| ID | Constant | Format | Use case |
|---|---|---|---|
| 1 | artifact.FormatJSON |
JSON | Human-readable, debugging |
| 2 | artifact.FormatMsgPack |
MessagePack | Compact, production (default) |
Both formats implement the format.Format interface:
Detecting artifacts
Use HasMagic to quickly check whether a byte slice looks like a Ferret artifact:
HasMagic only checks the first 4 bytes. It does not validate the full artifact — use Load or Unmarshal for that.
Custom loaders
The engine uses a Loader to decode artifacts. By default it supports JSON and MessagePack payloads. You can create a custom loader with additional formats:
The format ID in the RegisteredFormat must match the format ID written in the artifact header. When loading, the loader reads the header, selects the registered format by ID, and delegates decoding to it.
Error handling
The artifact package defines sentinel errors for each validation failure:
| Error | Cause |
|---|---|
ErrInvalidMagic |
First 4 bytes are not FBC2 |
ErrUnsupportedSchema |
Schema version is not supported by this loader |
ErrIncompatibleISA |
Bytecode ISA version does not match the runtime |
ErrUnknownFormat |
Payload format ID is not registered |
ErrInvalidHeader |
Header is malformed or payload length does not match |
ErrInvalidPayload |
Payload format decoder failed |
ErrInvalidArtifact |
General loader or artifact state error |
Use errors.Is to check for specific failures:
Complete example
Compile a query, save it to disk, then load and run it in a separate step: