diff --git a/crates/query-ops/README.md b/crates/query-ops/README.md
index 34bc79a..70cee32 100644
--- a/crates/query-ops/README.md
+++ b/crates/query-ops/README.md
@@ -16,6 +16,12 @@ The operators are: atom scan, semijoin, and natural join.
| `Relation` | struct | Holds rows over named columns and is the type produced by every operator. Construct it with `Relation::new(columns)` or `Relation::from_rows(columns, rows)`. Column names within a single relation must be unique. |
| `Value` | enum | Represents a single cell value stored in a `Table` or `Relation`. A value is either `Int(i64)` or `Str(String)`. |
+
+
+
+
+
+
### Example
The rule below returns the authors of every bestseller along with the book's price.
@@ -96,6 +102,12 @@ fn main() {
}
```
+
+
+
+
+
+
### Test
```sh
diff --git a/crates/query-ops/docs/diagrams/types.dot b/crates/query-ops/docs/diagrams/types.dot
new file mode 100644
index 0000000..d11a233
--- /dev/null
+++ b/crates/query-ops/docs/diagrams/types.dot
@@ -0,0 +1,60 @@
+digraph QueryOpsTypes {
+fontname = "Helvetica,Arial,sans-serif"
+layout = dot
+rankdir = TB
+ranksep = 0.7;
+nodesep = 0.7;
+splines = true;
+bgcolor = "white"
+
+node [
+fontname = "Helvetica,Arial,sans-serif",
+shape = box,
+style = "filled,rounded",
+color = "#555555",
+fillcolor = "white",
+penwidth = 1.5
+]
+edge [
+fontname = "Helvetica,Arial,sans-serif",
+color = "#333333",
+fontsize = 9,
+fontcolor = "#555555",
+penwidth = 1.2
+]
+
+table_node [label = <
+Table (struct)
+arity: usize
+rows: Vec<Vec<Value>>
+
>, fillcolor = "#E8F4FD", color = "#2196F3"]
+
+relation_node [label = <
+Relation (struct)
+columns: Vec<String>
+rows: Vec<Vec<Value>>
+
>, fillcolor = "#ECEFF1", color = "#607D8B"]
+
+atom_pattern_node [label = <
+AtomPattern (struct)
+columns: Vec<Term>
+
>, fillcolor = "#F3E5F5", color = "#9C27B0"]
+
+term_node [label = <
+Term (enum)
+Var(String)
+Lit(Value)
+
>, fillcolor = "#F3E5F5", color = "#9C27B0"]
+
+value_node [label = <
+Value (enum)
+Int(i64)
+Str(String)
+
>, fillcolor = "#FFF3E0", color = "#FF9800"]
+
+// composition edges: arrow X -> Y reads "X contains Y"
+atom_pattern_node -> term_node [label = "Vec"]
+term_node -> value_node [label = "Lit(Value)"]
+table_node -> value_node [label = "Vec>"]
+relation_node -> value_node [label = "Vec>"]
+}
diff --git a/crates/query-ops/docs/diagrams/types.svg b/crates/query-ops/docs/diagrams/types.svg
new file mode 100644
index 0000000..f34a94d
--- /dev/null
+++ b/crates/query-ops/docs/diagrams/types.svg
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+QueryOpsTypes
+
+
+
+table_node
+
+Table
+ (struct)
+arity: usize
+rows: Vec<Vec<Value>>
+
+
+
+value_node
+
+Value
+ (enum)
+Int(i64)
+Str(String)
+
+
+
+table_node->value_node
+
+
+Vec<Vec<Value>>
+
+
+
+relation_node
+
+Relation
+ (struct)
+columns: Vec<String>
+rows: Vec<Vec<Value>>
+
+
+
+relation_node->value_node
+
+
+Vec<Vec<Value>>
+
+
+
+atom_pattern_node
+
+AtomPattern
+ (struct)
+columns: Vec<Term>
+
+
+
+term_node
+
+Term
+ (enum)
+Var(String)
+Lit(Value)
+
+
+
+atom_pattern_node->term_node
+
+
+Vec<Term>
+
+
+
+term_node->value_node
+
+
+Lit(Value)
+
+
+