Data Types
FlowLog supports four primitive data types for relation columns.Integer
| Type | Size | Min | Max |
|---|---|---|---|
int32 | 32-bit | -2.1 × 109 | 2.1 × 109 |
int64 | 64-bit | -9.2 × 1018 | 9.2 × 1018 |
Integer types map directly to the corresponding Rust signed integer types (i32, i64) in the generated code.
.decl Score(student_id: int32, grade: int32)
// Score(1001, 95).
String
The string type represents a UTF-8 string value. String constants are written in double quotes:
.decl Name(id: int32, label: string)
// Name(1, "alice").
Boolean
The bool type represents a true/false value. Boolean literals are written as True or False (capitalized):
.decl Flag(id: int32, active: bool)
// Flag(1, True).
Declaring types in relations
Types are specified in .decl directives:
.decl Edge(src: int32, dst: int32)
.decl Person(id: int64, name: string, active: bool)
Every column in a relation must have an explicit type annotation.
Type checking
FlowLog enforces type safety at relation boundaries — Joins, Rule heads, and String/Boolean constants. Integer constant overflow and comparison operand types are not checked by FlowLog and will be caught by the downstream Rust compiler.
Joins
Variables used as join keys across relations must have matching types. For example, joining Edge(x, y) with Node(y, label) requires y to have the same type in both Edge and Node.
.decl Edge(src: int32, dst: int32)
.decl Node(id: int32, label: string)
// Valid: y is int32 in both Edge and Node
Match(x, label) :- Edge(x, y), Node(y, label).
If Node were instead declared as Node(id: int64, label: string), FlowLog would report a type error because y cannot be both int32 and int64.
Rule heads
When multiple rules write to the same IDB relation, all rules must produce the same column types as the IDB declaration. For example, if Route(src, dst, cost) is declared with (int32, int32, int32), every rule deriving Route must produce (int32, int32, int32).
.decl Edge(src: int32, dst: int32)
.decl Weight(src: int32, dst: int32, cost: int32)
.decl Route(src: int32, dst: int32, cost: int32)
// Both rules produce (int32, int32, int32) — matches the declaration
Route(x, y, c) :- Edge(x, y), Weight(x, y, c).
Route(x, z, c) :- Route(x, y, _), Edge(y, z), Weight(y, z, c).
Since x, y, and z come from Edge (declared as (int32, int32)) and c comes from Weight (declared with cost: int32), the types match the Route declaration.
Constants
String and Bool constants are type-checked by FlowLog. Integer constants (e.g., 42) are NOT explicitly checked — if a constant doesn't fit the column type, the value will be silently truncated.
Comparisons
Type compatibility of comparison operands (e.g., x > y, x != 3) is not checked by FlowLog directly. Mismatched types will produce a compilation error in the generated code.