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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::registry::*;
use akar_common::types::Value;
// ==================== Schema Functions ====================
/// Evaluate a schema function: OFFSET, ID, START_NODE, END_NODE, LABEL.
pub(crate) fn evaluate_schema(op: SchemaOp, args: &[Value]) -> Result<Value, String> {
if args.is_empty() {
return Err(format!("Schema function {:?} requires an argument", op));
}
match op {
SchemaOp::Offset => {
// OFFSET(v) → returns the internal offset (row number) of a node/rel ID
match &args[0] {
Value::InternalID(id) => Ok(Value::Int64(id.offset as i64)),
Value::Struct(entries) => {
// Try to extract offset from a struct with "_id" field
for (k, v) in entries {
if k == "_id" {
if let Value::InternalID(inner) = v {
return Ok(Value::Int64(inner.offset as i64));
}
}
}
Err("OFFSET: argument struct has no _id field".into())
}
other => Err(format!(
"OFFSET requires a node/rel value, got {:?}",
other.logical_type()
)),
}
}
SchemaOp::Id => {
// ID(v) → returns the InternalID (offset + table_id)
match &args[0] {
Value::InternalID(id) => Ok(Value::InternalID(*id)),
Value::Struct(entries) => {
// Try to extract id from a struct with "_id" field
for (k, v) in entries {
if k == "_id" {
return Ok(v.clone());
}
}
Err("ID: argument struct has no _id field".into())
}
other => Err(format!("ID requires a node/rel value, got {:?}", other.logical_type())),
}
}
SchemaOp::StartNode => {
// START_NODE(r) → returns the source node of a relationship
match &args[0] {
Value::Struct(entries) => {
for (k, v) in entries {
if k == "_src" {
return Ok(v.clone());
}
}
Err("START_NODE: rel struct has no _src field".into())
}
other => Err(format!(
"START_NODE requires a relationship value, got {:?}",
other.logical_type()
)),
}
}
SchemaOp::EndNode => {
// END_NODE(r) → returns the target node of a relationship
match &args[0] {
Value::Struct(entries) => {
for (k, v) in entries {
if k == "_dst" {
return Ok(v.clone());
}
}
Err("END_NODE: rel struct has no _dst field".into())
}
other => Err(format!(
"END_NODE requires a relationship value, got {:?}",
other.logical_type()
)),
}
}
SchemaOp::Label => {
// LABEL(v) → returns the table/label name as a string
match &args[0] {
Value::String(s) => Ok(Value::String(s.clone())),
Value::Struct(entries) => {
// Try _label field first
for (k, v) in entries {
if k == "_label" {
return Ok(v.clone());
}
}
// Fallback: try _id and look up by table_id
for (k, v) in entries {
if k == "_id" {
if let Value::InternalID(id) = v {
return Ok(Value::String(format!("Table({})", id.table_id)));
}
}
}
Err("LABEL: argument struct has no _label field".into())
}
Value::InternalID(id) => Ok(Value::String(format!("Table({})", id.table_id))),
other => Err(format!(
"LABEL requires a node/rel/string value, got {:?}",
other.logical_type()
)),
}
}
SchemaOp::Cost => {
let path = &args[0];
match path {
Value::Struct(fields) => {
for (k, v) in fields {
if k == "_cost" || k == "cost" {
return Ok(v.clone());
}
}
Ok(Value::Double(0.0))
}
_ => Ok(Value::Double(0.0)),
}
}
SchemaOp::RowId => match &args[0] {
Value::InternalID(id) => Ok(Value::UInt64(id.offset)),
Value::Struct(entries) => {
for (k, v) in entries {
if k == "_id" || k == "id" {
if let Value::InternalID(id) = v {
return Ok(Value::UInt64(id.offset));
}
}
}
Ok(Value::UInt64(0))
}
_ => Ok(Value::UInt64(0)),
},
}
}