1use crate::value::LoraValue;
2use lora_compiler::physical::PhysicalNodeId;
3use lora_store::{NodeId, RelationshipId};
4use thiserror::Error;
5
6#[derive(Debug, Error)]
7pub enum ExecutorError {
8 #[error("this query modifies the graph, but it was executed in read-only mode (CREATE at plan node {node_id:?})")]
9 ReadOnlyCreate { node_id: PhysicalNodeId },
10
11 #[error("this query modifies the graph, but it was executed in read-only mode (MERGE at plan node {node_id:?})")]
12 ReadOnlyMerge { node_id: PhysicalNodeId },
13
14 #[error("this query modifies the graph, but it was executed in read-only mode (DELETE at plan node {node_id:?})")]
15 ReadOnlyDelete { node_id: PhysicalNodeId },
16
17 #[error("this query modifies the graph, but it was executed in read-only mode (SET at plan node {node_id:?})")]
18 ReadOnlySet { node_id: PhysicalNodeId },
19
20 #[error("this query modifies the graph, but it was executed in read-only mode (REMOVE at plan node {node_id:?})")]
21 ReadOnlyRemove { node_id: PhysicalNodeId },
22
23 #[error("this query modifies the graph, but it was executed in read-only mode (FOREACH at plan node {node_id:?})")]
24 ReadOnlyForeach { node_id: PhysicalNodeId },
25
26 #[error("expected variable {var} to contain a node before expanding a relationship, but found {found}")]
27 ExpectedNodeForExpand { var: String, found: String },
28
29 #[error("expected a map value for properties, but found {found}")]
30 ExpectedPropertyMap { found: String },
31
32 #[error("grouping could not be executed because the group-by expression was not lowered to a variable")]
33 GroupByNotLowered,
34
35 #[error("aggregation could not be executed because the aggregate expression was not lowered to a variable")]
36 AggregateNotLowered,
37
38 #[error("variable-length relationships are not supported in CREATE")]
39 UnsupportedCreateRelationshipRange,
40
41 #[error("a CREATE relationship is missing its relationship type")]
42 MissingRelationshipType,
43
44 #[error("failed to create relationship `{rel_type}` from node {src} to node {dst}")]
45 RelationshipCreateFailed {
46 src: u64,
47 dst: u64,
48 rel_type: String,
49 },
50
51 #[error("failed to create node because storage is exhausted")]
52 NodeCreateFailed,
53
54 #[error("cannot delete node {node_id} because it still has relationships; use DETACH DELETE to remove the node and its relationships")]
55 DeleteNodeWithRelationships { node_id: NodeId },
56
57 #[error("failed to delete relationship {rel_id}")]
58 DeleteRelationshipFailed { rel_id: RelationshipId },
59
60 #[error(
61 "DELETE can only be used with nodes, relationships, or lists of them, but found {found}"
62 )]
63 InvalidDeleteTarget { found: String },
64
65 #[error("REMOVE label can only be applied to a node, but found {found}")]
66 ExpectedNodeForRemoveLabels { found: String },
67
68 #[error("REMOVE referenced variable {var}, but that variable is not bound in the current row")]
69 UnboundVariableForRemove { var: String },
70
71 #[error("SET label can only be applied to a node, but found {found}")]
72 ExpectedNodeForSetLabels { found: String },
73
74 #[error("SET referenced variable {var}, but that variable is not bound in the current row")]
75 UnboundVariableForSet { var: String },
76
77 #[error("SET target must be a node or relationship, but found {found}")]
78 InvalidSetTarget { found: String },
79
80 #[error("REMOVE property currently only supports direct property expressions like n.name or r.weight")]
81 UnsupportedRemoveTarget,
82
83 #[error("REMOVE target must be a node or relationship property, but found {found}")]
84 InvalidRemoveTarget { found: String },
85
86 #[error(
87 "SET property currently only supports direct property expressions like n.name or r.weight"
88 )]
89 UnsupportedSetTarget,
90
91 #[error("expected variable {var} to contain a relationship during EXPAND, but found {found}")]
92 ExpectedRelationshipForExpand { var: String, found: String },
93
94 #[error("query deadline exceeded")]
95 QueryTimeout,
96
97 #[error("{0}")]
101 ConstraintViolation(String),
102
103 #[error("{0}")]
104 RuntimeError(String),
105}
106
107pub type ExecResult<T> = Result<T, ExecutorError>;
108
109pub fn value_kind(value: &LoraValue) -> String {
110 match value {
111 LoraValue::Null => "null".into(),
112 LoraValue::Bool(_) => "bool".into(),
113 LoraValue::Int(_) => "int".into(),
114 LoraValue::Float(_) => "float".into(),
115 LoraValue::String(_) => "string".into(),
116 LoraValue::Binary(_) => "binary".into(),
117 LoraValue::List(_) => "list".into(),
118 LoraValue::Map(_) => "map".into(),
119 LoraValue::Node(_) => "node".into(),
120 LoraValue::Relationship(_) => "relationship".into(),
121 LoraValue::Path(_) => "path".into(),
122 LoraValue::Date(_) => "date".into(),
123 LoraValue::DateTime(_) => "datetime".into(),
124 LoraValue::LocalDateTime(_) => "localdatetime".into(),
125 LoraValue::Time(_) => "time".into(),
126 LoraValue::LocalTime(_) => "localtime".into(),
127 LoraValue::Duration(_) => "duration".into(),
128 LoraValue::Point(_) => "point".into(),
129 LoraValue::Vector(_) => "vector".into(),
130 }
131}