Skip to content

Commit c95a3bd

Browse files
staworkoclaude
andcommitted
Add documentation comments to LQP protobuf definitions
Document all messages, fields, and enums across logic.proto, fragments.proto, and transactions.proto with comments explaining purpose and semantics. Extend docs/lqp.md with sections on execution model, write/read operations, types, and external data. Information sourced from the design doc, usage patterns in raicode and relationalai-python, and test examples in tests/lqp. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 6484c76 commit c95a3bd

4 files changed

Lines changed: 411 additions & 116 deletions

File tree

docs/lqp.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,64 @@ LQP clients send `Transaction`s that the engine executes.
4848

4949
Write := Define(fragment::Fragment)
5050
| Undefine(fragment_id::FragmentId)
51+
| Context(relations::RelationId[])
52+
| Snapshot(mappings::SnapshotMapping[], prefix::String[])
5153

5254
Read := Demand(relation_id::RelationId)
5355
| Output(name::String, relation_id::RelationId)
54-
| Export(config::ExportCSVConfig)
55-
| WhatIf(branch::String, epochs::Epoch[])
56+
| Export(config::ExportConfig)
57+
| WhatIf(branch::String, epoch::Epoch)
5658
| Abort(name::String, relation_id::RelationId)
5759

5860
Transactions are structured into one or more epochs, which correspond to observable states
5961
of the installed program. This allows users to execute a sequence of steps in a single
6062
transaction. Within an epoch writes execute before reads. Multiple writes or multiple reads
61-
can be performed concurrently and in any order. Of special note are the WhatIf operations,
63+
can be performed concurrently and in any order. Of special note are the `WhatIf` operations,
6264
which allow executing an epoch in a throwaway clone of the runtime state.
65+
66+
## Execution Model
67+
68+
Transaction execution proceeds in two passes. First, the _simulator_ runs the transaction
69+
against a transient copy of the runtime state to validate it and minimize it (e.g. dropping
70+
writes whose effects are clobbered by later writes). Then the _driver_ executes the
71+
validated, minimized transaction against the actual runtime. If the simulator detects invalid
72+
state at any point, the transaction is aborted and errors are returned.
73+
74+
## Write Operations
75+
76+
`Define` installs a fragment and its declarations into the execution graph. `Undefine`
77+
removes a fragment. `Context` declares which relations should be jointly optimized — more
78+
context gives the optimizer more reuse opportunities but increases planning time. `Snapshot`
79+
materializes derived relations into durable EDB (base) relations, associating new relation
80+
values with stable identities over time.
81+
82+
## Read Operations
83+
84+
`Demand` triggers computation of a relation without returning its contents — useful for
85+
warming caches. `Output` computes and returns a relation's contents under a human-readable
86+
name. `Export` writes data to external storage (CSV or Iceberg). `WhatIf` runs a speculative
87+
epoch on a transient fork; writes don't persist, reads observe the modified state. `Abort`
88+
enforces integrity constraints: the transaction fails if the referenced relation is non-empty.
89+
90+
## Types
91+
92+
All types are primitive and aligned with the Apache Iceberg type system. The engine uses
93+
type information for equality, ordering, promotion, and algebraic properties of operations.
94+
Overloading must be handled by higher-level compilers. See the `Type` message in
95+
`logic.proto` for the full list.
96+
97+
## External Data
98+
99+
`Data` declarations describe external sources (CSV, Iceberg, BeTree) without eagerly
100+
ingesting them — data is loaded lazily when first demanded. `EDB` declares durable
101+
engine-managed base relations (the result of `Snapshot` operations). `CSVData` and
102+
`IcebergData` describe how to read from those respective formats, with column-to-relation
103+
mappings via `GNFColumn`.
104+
105+
## Protobuf Specification
106+
107+
The proto files in `../proto/relationalai/lqp/v1/` are the authoritative specification:
108+
109+
- `logic.proto` — Declarations, formulas, types, values, and external data sources
110+
- `fragments.proto` — Content-addressable compilation units and debug info
111+
- `transactions.proto` — Transaction structure, write/read operations, and export config
Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
// Logical Query Protocol — Fragments
2+
//
3+
// Fragments are the unit of incremental compilation and installation. The full
4+
// execution graph is partitioned into content-addressable fragments that can be
5+
// defined, redefined, and undefined independently.
6+
//
7+
// Instead of resending the entire program on every transaction, a client can
8+
// use the Sync mechanism (see transactions.proto) to reconcile its expected
9+
// set of fragments with the engine's installed state. The engine identifies
10+
// fragments by their content hash, so unchanged fragments are never resent.
11+
//
12+
// The granularity of fragments is chosen by the compiler: one per source file,
13+
// per module, per definition, or even a single fragment for the entire program.
14+
115
syntax = "proto3";
216

317
option go_package = "github.com/RelationalAI/logical-query-protocol/sdks/go/src/lqp/v1";
@@ -6,17 +20,27 @@ package relationalai.lqp.v1;
620

721
import "relationalai/lqp/v1/logic.proto";
822

23+
// A content-addressable unit of the execution graph containing one or more
24+
// declarations. Each declaration can only belong to a single fragment.
25+
// Fragments are installed/removed via Define/Undefine write operations.
926
message Fragment {
1027
FragmentId id = 1;
1128
repeated Declaration declarations = 2;
29+
// Optional human-readable name mappings for debugging and logging.
1230
DebugInfo debug_info = 3;
1331
}
1432

33+
// Maps opaque RelationIds to human-readable names for use in logs,
34+
// error messages, and debugging tools. The ids and orig_names arrays
35+
// are parallel (same length, matched by index).
1536
message DebugInfo {
1637
repeated RelationId ids = 1;
1738
repeated string orig_names = 2;
1839
}
1940

41+
// Content-based identifier for a fragment. Typically a hash of the
42+
// fragment's declarations, enabling deduplication and cache-friendly
43+
// synchronization.
2044
message FragmentId {
21-
bytes id = 1; // Variable-length identifier, up to 256 bits (32 bytes) or less
45+
bytes id = 1; // Variable-length identifier, up to 256 bits (32 bytes)
2246
}

0 commit comments

Comments
 (0)