1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
//! Constraint definitions: uniqueness and type enforcement for graph nodes.
//!
//! # GQL syntax
//!
//! ```gql
//! CREATE CONSTRAINT UNIQUE ON :Person(email)
//! CREATE CONSTRAINT TYPE IS INTEGER ON :Person(age)
//! CREATE CONSTRAINT TYPE IS FLOAT ON :Measurement(value)
//! CREATE CONSTRAINT TYPE IS STRING ON :Document(title)
//! CREATE CONSTRAINT TYPE IS BOOLEAN ON :Feature(enabled)
//! DROP CONSTRAINT UNIQUE ON :Person(email)
//! SHOW CONSTRAINTS
//! ```
//!
//! # Storage
//!
//! Constraints are persisted as a bincode-serialized `Vec<ConstraintDef>` in the
//! `meta` column family under key `constraint_defs`. They are loaded into
//! `Graph::constraint_defs` on `open()` and updated atomically on every
//! `add_constraint` / `remove_constraint` call.
//!
//! # Enforcement lifecycle
//!
//! 1. **INSERT** — `build_insert_ops` in the executor calls
//! [`Graph::check_node_constraints`](crate::graph::Graph::check_node_constraints)
//! for each node before building the `Operation::CreateNode`. Nodes that pass
//! the upsert dedup check (exact-match existing node) bypass constraint checking
//! entirely because no new data is written.
//! 2. **SET** — `ops::set_node_property` calls the private `check_constraints` with
//! `self_id = Some(node_id)` so the node being updated is excluded from the
//! uniqueness check (a node may SET its own property to the same value it already
//! holds without triggering a violation).
//! 3. **UNWIND … INSERT** — `execute_unwind_insert` calls `check_node_constraints`
//! for every iteration before queuing a `CreateNode` operation.
//!
//! # Uniqueness check fallback
//!
//! The fast path uses the `prop_idx` column family (O(log n) lookup). This index
//! is only populated when the user has also run `CREATE INDEX ON :Label(prop)`.
//! When the index returns nothing, the check falls back to a linear scan of all
//! nodes carrying the label to guarantee correctness even without an explicit index.
use ;
/// The declared type a property value must conform to.
/// The kind of constraint.
/// A single declared constraint.