gqlite 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +20 -0
  3. data/ext/gqlitedb/Cargo.toml +77 -0
  4. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/pokec.rs +30 -20
  5. data/ext/gqlitedb/gqlite_bench_data/README.MD +6 -0
  6. data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +85 -0
  7. data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +34 -0
  8. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +2 -2
  9. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
  10. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
  11. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
  12. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +34 -10
  13. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +10 -4
  14. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +36 -39
  15. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +46 -41
  16. data/ext/gqlitedb/src/connection.rs +300 -0
  17. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +113 -50
  18. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
  19. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +3 -3
  20. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +3 -3
  21. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +2 -2
  22. data/ext/gqlitedb/src/functions/path.rs +75 -0
  23. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +3 -3
  24. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +1 -1
  25. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +7 -7
  26. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +29 -31
  27. data/ext/gqlitedb/src/graph.rs +11 -0
  28. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +178 -224
  29. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +8 -2
  30. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -5
  31. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +54 -76
  32. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +9 -4
  33. data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +86 -34
  34. data/ext/gqlitedb/src/parser.rs +4 -0
  35. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
  36. data/ext/gqlitedb/src/query_result.rs +88 -0
  37. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +260 -170
  38. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +157 -142
  39. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +30 -23
  40. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +41 -85
  41. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +12 -5
  42. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +12 -5
  43. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +106 -114
  44. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
  45. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
  46. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
  47. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
  48. data/ext/gqlitedb/src/value.rs +225 -0
  49. data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +22 -18
  50. data/ext/gqliterb/Cargo.toml +12 -34
  51. data/ext/gqliterb/src/lib.rs +67 -39
  52. data/ext/graphcore/Cargo.toml +19 -0
  53. data/ext/graphcore/README.MD +4 -0
  54. data/ext/graphcore/release.toml +1 -0
  55. data/ext/graphcore/src/error.rs +28 -0
  56. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +146 -35
  57. data/ext/graphcore/src/lib.rs +16 -0
  58. data/ext/graphcore/src/prelude.rs +4 -0
  59. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
  60. data/ext/graphcore/src/table.rs +272 -0
  61. data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
  62. data/ext/graphcore/src/value.rs +413 -0
  63. metadata +94 -83
  64. data/ext/gqliterb/.cargo/config.toml +0 -2
  65. data/ext/gqliterb/Cargo.lock +0 -1109
  66. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2060
  67. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -132
  68. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +0 -208
  69. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +0 -48
  70. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
  71. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -559
  72. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
  73. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
  74. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
  75. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
  76. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
  77. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
  78. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
  79. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
  80. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
  81. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
  82. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
  83. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
  84. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
  85. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
  86. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
  87. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
  88. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
  89. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
  90. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
  91. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
  92. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
  93. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
  94. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
  95. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
  96. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
  97. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
  98. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
  99. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
  100. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
  101. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
  102. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
  103. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
  104. /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -9,6 +9,7 @@ use crate::{
9
9
  use interpreter::instructions;
10
10
 
11
11
  #[derive(Debug, Clone)]
12
+ #[allow(clippy::enum_variant_names)]
12
13
  enum Value
13
14
  {
14
15
  GraphValue(value::Value),
@@ -16,18 +17,6 @@ enum Value
16
17
  EdgeQuery(store::SelectEdgeQuery),
17
18
  }
18
19
 
19
- impl Value
20
- {
21
- fn is_null(&self) -> bool
22
- {
23
- match self
24
- {
25
- Value::GraphValue(gv) => gv.is_null(),
26
- _ => false,
27
- }
28
- }
29
- }
30
-
31
20
  impl<T> From<T> for Value
32
21
  where
33
22
  T: Into<value::Value>,
@@ -46,7 +35,7 @@ macro_rules! try_into_gv_impl {
46
35
  fn try_into(self) -> crate::Result<$vn>
47
36
  {
48
37
  let a: value::Value = self.try_into()?;
49
- a.try_into()
38
+ Ok(a.try_into()?)
50
39
  }
51
40
  }
52
41
  impl TryPopInto<$vn> for Stack
@@ -54,12 +43,12 @@ macro_rules! try_into_gv_impl {
54
43
  fn try_pop_into(&mut self) -> crate::Result<$vn>
55
44
  {
56
45
  self.try_pop()?.try_into()
57
- .map_err(|e: ErrorType| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
46
+ .map_err(|e: ErrorType| error::map_error!(e, Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
58
47
  }
59
48
  fn try_drain_into(&mut self, n: usize) -> Result<Vec<$vn>>
60
49
  {
61
50
  self.try_drain(n)?.map(|x| x.try_into()).collect::<Result<_>>()
62
- .map_err(|e| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
51
+ .map_err(|e| error::map_error!(e, Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
63
52
  }
64
53
  }
65
54
  };
@@ -96,13 +85,13 @@ macro_rules! try_into_impl {
96
85
  fn try_pop_into(&mut self) -> Result<$type>
97
86
  {
98
87
  self.try_pop()?.try_into()
99
- .map_err(|e: ErrorType| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
88
+ .map_err(|e: ErrorType| error::map_error!(e, Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
100
89
 
101
90
  }
102
91
  fn try_drain_into(&mut self, n: usize) -> Result<Vec<$type>>
103
92
  {
104
93
  self.try_drain(n)?.map(|x| x.try_into()).collect::<Result<_>>()
105
- .map_err(|e| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
94
+ .map_err(|e| error::map_error!(e, Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
106
95
  }
107
96
  }
108
97
  };
@@ -116,7 +105,7 @@ impl From<store::SelectNodeQuery> for Value
116
105
  {
117
106
  fn from(value: store::SelectNodeQuery) -> Self
118
107
  {
119
- Self::NodeQuery(value.into())
108
+ Self::NodeQuery(value)
120
109
  }
121
110
  }
122
111
 
@@ -124,7 +113,7 @@ impl From<store::SelectEdgeQuery> for Value
124
113
  {
125
114
  fn from(value: store::SelectEdgeQuery) -> Self
126
115
  {
127
- Self::EdgeQuery(value.into())
116
+ Self::EdgeQuery(value)
128
117
  }
129
118
  }
130
119
 
@@ -195,7 +184,7 @@ impl Stack
195
184
  Ok(self.stack.drain((self.stack.len() - len)..))
196
185
  }
197
186
  }
198
- fn to_vec(self) -> Vec<Value>
187
+ fn into_vec(self) -> Vec<Value>
199
188
  {
200
189
  self.stack
201
190
  }
@@ -226,12 +215,12 @@ where
226
215
  fn try_pop_into(&mut self) -> Result<T>
227
216
  {
228
217
  self.try_pop()?.try_into()
229
- .map_err(|e: ErrorType| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
218
+ .map_err(|e: ErrorType| error::map_error!(e, Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
230
219
  }
231
220
  fn try_drain_into(&mut self, n: usize) -> Result<Vec<T>>
232
221
  {
233
222
  self.try_drain(n)?.map(|x| x.try_into()).collect::<Result<Vec<_>>>()
234
- .map_err(|e| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
223
+ .map_err(|e| error::map_error!(e, Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))
235
224
  }
236
225
  }
237
226
 
@@ -246,11 +235,11 @@ fn execute_boolean_operator(
246
235
  let b: value::Value = b.try_into()?;
247
236
  match instruction
248
237
  {
249
- &instructions::Instruction::AndBinaryOperator =>
238
+ instructions::Instruction::AndBinaryOperator =>
250
239
  {
251
240
  if a.is_null()
252
241
  {
253
- if b.is_null() || <value::Value as TryInto<bool>>::try_into(b)? == true
242
+ if b.is_null() || <value::Value as TryInto<bool>>::try_into(b)?
254
243
  {
255
244
  stack.push(value::Value::Null);
256
245
  }
@@ -279,11 +268,11 @@ fn execute_boolean_operator(
279
268
  }
280
269
  }
281
270
  }
282
- &instructions::Instruction::OrBinaryOperator =>
271
+ instructions::Instruction::OrBinaryOperator =>
283
272
  {
284
273
  if a.is_null()
285
274
  {
286
- if b.is_null() || <value::Value as TryInto<bool>>::try_into(b)? == false
275
+ if b.is_null() || !<value::Value as TryInto<bool>>::try_into(b)?
287
276
  {
288
277
  stack.push(value::Value::Null);
289
278
  }
@@ -299,20 +288,17 @@ fn execute_boolean_operator(
299
288
  {
300
289
  stack.push(true);
301
290
  }
291
+ else if b.is_null()
292
+ {
293
+ stack.push(value::Value::Null);
294
+ }
302
295
  else
303
296
  {
304
- if b.is_null()
305
- {
306
- stack.push(value::Value::Null);
307
- }
308
- else
309
- {
310
- stack.push(b);
311
- }
297
+ stack.push(b);
312
298
  }
313
299
  }
314
300
  }
315
- &instructions::Instruction::XorBinaryOperator =>
301
+ instructions::Instruction::XorBinaryOperator =>
316
302
  {
317
303
  if a.is_null() || b.is_null()
318
304
  {
@@ -335,7 +321,7 @@ fn execute_boolean_operator(
335
321
 
336
322
  fn execute_binary_operator<T: Into<crate::value::Value>>(
337
323
  stack: &mut Stack,
338
- operand: impl FnOnce(crate::value::Value, crate::value::Value) -> Result<T>,
324
+ operand: impl FnOnce(crate::value::Value, crate::value::Value) -> Result<T, graphcore::Error>,
339
325
  ) -> Result<()>
340
326
  {
341
327
  let a = stack.try_pop()?;
@@ -371,22 +357,22 @@ fn eval_instructions(
371
357
  let props: value::Value = stack.try_pop_into()?;
372
358
  let dst: graph::Node = stack.try_pop_into()?;
373
359
  let src: graph::Node = stack.try_pop_into()?;
374
- stack.push(crate::graph::Edge {
375
- key: graph::Key::default(),
376
- source: src,
377
- destination: dst,
378
- labels: labels.to_owned(),
379
- properties: props.into_map(),
380
- });
360
+ stack.push(crate::graph::Path::new(
361
+ graph::Key::default(),
362
+ src,
363
+ labels.to_owned(),
364
+ props.into_map(),
365
+ dst,
366
+ ));
381
367
  }
382
368
  instructions::Instruction::CreateNodeLiteral { labels } =>
383
369
  {
384
370
  let props: value::Value = stack.try_pop_into()?;
385
- stack.push(crate::graph::Node {
386
- key: crate::graph::Key::default(),
387
- labels: labels.clone(),
388
- properties: props.into_map(),
389
- });
371
+ stack.push(crate::graph::Node::new(
372
+ crate::graph::Key::default(),
373
+ labels.clone(),
374
+ props.into_map(),
375
+ ));
390
376
  }
391
377
  instructions::Instruction::CreateEdgeQuery { labels } =>
392
378
  {
@@ -399,7 +385,7 @@ fn eval_instructions(
399
385
  {
400
386
  stack.push(store::SelectEdgeQuery::select_source_destination_keys(
401
387
  src,
402
- [ed.key],
388
+ [ed.key()],
403
389
  dst,
404
390
  ));
405
391
  }
@@ -418,8 +404,8 @@ fn eval_instructions(
418
404
  {
419
405
  stack.push(store::SelectEdgeQuery::select_none());
420
406
  }
421
- _ => Err(InternalError::InvalidValueCast {
422
- value: props,
407
+ _ => Err(RunTimeError::InvalidValueCast {
408
+ value: Box::new(props),
423
409
  typename: "Edge properties",
424
410
  })?,
425
411
  }
@@ -431,7 +417,7 @@ fn eval_instructions(
431
417
  {
432
418
  value::Value::Node(no) =>
433
419
  {
434
- stack.push(store::SelectNodeQuery::select_keys([no.key]));
420
+ stack.push(store::SelectNodeQuery::select_keys([no.key()]));
435
421
  }
436
422
  value::Value::Map(ob) =>
437
423
  {
@@ -444,8 +430,8 @@ fn eval_instructions(
444
430
  {
445
431
  stack.push(store::SelectNodeQuery::select_none());
446
432
  }
447
- _ => Err(InternalError::InvalidValueCast {
448
- value: props,
433
+ _ => Err(RunTimeError::InvalidValueCast {
434
+ value: Box::new(props),
449
435
  typename: "Node properties",
450
436
  })?,
451
437
  }
@@ -531,7 +517,7 @@ fn eval_instructions(
531
517
  value::Value::Array(array) =>
532
518
  {
533
519
  let idx: i64 = index.try_into()
534
- .map_err(|e: ErrorType| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))?;
520
+ .map_err(|e: graphcore::Error| error::map_error!(e.into(), Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))?;
535
521
  stack.push(
536
522
  array
537
523
  .get(idx as usize)
@@ -539,24 +525,36 @@ fn eval_instructions(
539
525
  .to_owned(),
540
526
  );
541
527
  }
542
- value::Value::Map(map)
543
- | value::Value::Node(graph::Node {
544
- key: _,
545
- labels: _,
546
- properties: map,
547
- })
548
- | value::Value::Edge(graph::Edge {
549
- key: _,
550
- source: _,
551
- destination: _,
552
- labels: _,
553
- properties: map,
554
- }) =>
528
+ value::Value::Map(map) =>
555
529
  {
556
530
  let idx: String = index.try_into()
557
- .map_err(|e: ErrorType| error::map_error!(e, Error::Internal(InternalError::InvalidValueCast{..}) => RunTimeError::MapElementAccessByNonString ))?;
531
+ .map_err(|e: graphcore::Error| error::map_error!(e.into(), Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::MapElementAccessByNonString ))?;
558
532
  stack.push(map.get(&idx).unwrap_or(&value::Value::Null).to_owned());
559
533
  }
534
+ value::Value::Node(node) =>
535
+ {
536
+ let idx: String = index.try_into()
537
+ .map_err(|e: graphcore::Error| error::map_error!(e.into(), Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))?;
538
+ stack.push(
539
+ node
540
+ .properties()
541
+ .get(&idx)
542
+ .unwrap_or(&value::Value::Null)
543
+ .to_owned(),
544
+ );
545
+ }
546
+ value::Value::Edge(edge) =>
547
+ {
548
+ let idx: String = index.try_into()
549
+ .map_err(|e: graphcore::Error| error::map_error!(e.into(), Error::RunTime(RunTimeError::InvalidValueCast{..}) => RunTimeError::InvalidArgumentType ))?;
550
+ stack.push(
551
+ edge
552
+ .properties()
553
+ .get(&idx)
554
+ .unwrap_or(&value::Value::Null)
555
+ .to_owned(),
556
+ );
557
+ }
560
558
  value::Value::Null => stack.push(value::Value::Null),
561
559
  _ => Err(error::RunTimeError::InvalidArgumentType)?,
562
560
  }
@@ -583,8 +581,7 @@ fn eval_instructions(
583
581
  // Get the array out of the stack
584
582
  let v: value::Value = stack.try_pop_into()?;
585
583
  // if either end or start are null, return null
586
- if end.as_ref().map_or(false, |e| e.is_null())
587
- || start.as_ref().map_or(false, |s| s.is_null())
584
+ if end.as_ref().is_some_and(|e| e.is_null()) || start.as_ref().is_some_and(|s| s.is_null())
588
585
  {
589
586
  stack.push(value::Value::Null);
590
587
  }
@@ -599,14 +596,14 @@ fn eval_instructions(
599
596
  (Some(start), Some(end)) => Some(end - start),
600
597
  _ => None,
601
598
  };
602
- if length.map_or(false, |l| l >= v.len() as i64)
599
+ if length.is_some_and(|l| l >= v.len() as i64)
603
600
  {
604
601
  stack.push(v);
605
602
  }
606
603
  else
607
604
  {
608
605
  // If start is negative, it should be made into a positive number
609
- while start.map_or(false, |x| x < 0)
606
+ while start.is_some_and(|x| x < 0)
610
607
  {
611
608
  start = start.map(|x| x + v.len() as i64);
612
609
  end = end.map(|x| x + v.len() as i64);
@@ -659,10 +656,6 @@ fn eval_instructions(
659
656
  stack.push(a);
660
657
  stack.push(b);
661
658
  }
662
- &instructions::Instruction::Drop =>
663
- {
664
- stack.try_pop()?;
665
- }
666
659
  &instructions::Instruction::AndBinaryOperator
667
660
  | &instructions::Instruction::OrBinaryOperator
668
661
  | &instructions::Instruction::XorBinaryOperator =>
@@ -754,7 +747,7 @@ fn eval_instructions(
754
747
  execute_binary_operator::<value::Value>(stack, |a, b| {
755
748
  if b.is_null()
756
749
  {
757
- Ok(value::Value::Null.into())
750
+ Ok(value::Value::Null)
758
751
  }
759
752
  else
760
753
  {
@@ -771,7 +764,7 @@ fn eval_instructions(
771
764
  execute_binary_operator::<value::Value>(stack, |a, b| {
772
765
  if b.is_null()
773
766
  {
774
- Ok(value::Value::Null.into())
767
+ Ok(value::Value::Null)
775
768
  }
776
769
  else
777
770
  {
@@ -803,18 +796,23 @@ fn eval_instructions(
803
796
  {
804
797
  execute_binary_operator(stack, |a, b| a % b)?;
805
798
  }
799
+ &instructions::Instruction::ExponentBinaryOperator =>
800
+ {
801
+ execute_binary_operator(stack, |a, b| a.pow(b))?;
802
+ }
806
803
  }
807
804
  }
808
805
  Ok(())
809
806
  }
810
807
 
808
+ #[allow(clippy::too_many_arguments)]
811
809
  pub(crate) fn eval_update_property<TStore: store::Store>(
812
810
  store: &TStore,
813
- mut tx: &mut TStore::TransactionBox,
811
+ tx: &mut TStore::TransactionBox,
814
812
  graph_name: &String,
815
813
  row: &mut value_table::Row,
816
814
  target: value_table::ColId,
817
- path: &Vec<String>,
815
+ path: &[String],
818
816
  instructions: &instructions::Instructions,
819
817
  parameters: &crate::value::ValueMap,
820
818
  set: bool,
@@ -822,12 +820,12 @@ pub(crate) fn eval_update_property<TStore: store::Store>(
822
820
  {
823
821
  let var = row.get(target)?;
824
822
  let mut stack = Stack::default();
825
- eval_instructions(&mut stack, row, &instructions, &parameters)?;
823
+ eval_instructions(&mut stack, row, instructions, parameters)?;
826
824
  let value: value::Value = stack.try_pop_into()?;
827
825
  let value = match value
828
826
  {
829
- value::Value::Node(n) => n.properties.into(),
830
- value::Value::Edge(e) => e.properties.into(),
827
+ value::Value::Node(n) => n.take_properties().into(),
828
+ value::Value::Edge(e) => e.take_properties().into(),
831
829
  _ => value,
832
830
  };
833
831
  let mut piter = path.iter();
@@ -838,15 +836,15 @@ pub(crate) fn eval_update_property<TStore: store::Store>(
838
836
  let mut n = n.to_owned();
839
837
  if set
840
838
  {
841
- n.properties
839
+ n.properties_mut()
842
840
  .set_value(piter.next(), piter, value.remove_null())?;
843
841
  }
844
842
  else
845
843
  {
846
- n.properties
844
+ n.properties_mut()
847
845
  .add_values(piter.next(), piter, value.try_into()?)?;
848
846
  }
849
- store.update_node(&mut tx, &graph_name, &n)?;
847
+ store.update_node(tx, graph_name, &n)?;
850
848
  row.set(target, n.into())?;
851
849
  }
852
850
  value::Value::Edge(e) =>
@@ -854,15 +852,15 @@ pub(crate) fn eval_update_property<TStore: store::Store>(
854
852
  let mut e = e.to_owned();
855
853
  if set
856
854
  {
857
- e.properties
855
+ e.properties_mut()
858
856
  .set_value(piter.next(), piter, value.remove_null())?;
859
857
  }
860
858
  else
861
859
  {
862
- e.properties
860
+ e.properties_mut()
863
861
  .add_values(piter.next(), piter, value.try_into()?)?;
864
862
  }
865
- store.update_edge(&mut tx, &graph_name, &e)?;
863
+ store.update_edge(tx, graph_name, &e)?;
866
864
  row.set(target, e.into())?;
867
865
  }
868
866
  value::Value::Null =>
@@ -874,8 +872,6 @@ pub(crate) fn eval_update_property<TStore: store::Store>(
874
872
  Ok(())
875
873
  }
876
874
 
877
- struct OrderByKey(Vec<(value::Value, bool)>);
878
-
879
875
  fn handle_asc(o: std::cmp::Ordering, asc: bool) -> std::cmp::Ordering
880
876
  {
881
877
  if asc
@@ -893,18 +889,6 @@ fn handle_asc(o: std::cmp::Ordering, asc: bool) -> std::cmp::Ordering
893
889
  }
894
890
  }
895
891
 
896
- fn compute_order_by(
897
- a: &Vec<(value::Value, bool)>,
898
- b: &Vec<(value::Value, bool)>,
899
- ) -> std::cmp::Ordering
900
- {
901
- a.iter()
902
- .zip(b.iter())
903
- .map(|(a, b)| handle_asc(a.0.orderability(&b.0), a.1))
904
- .find(|p| *p != std::cmp::Ordering::Equal)
905
- .unwrap_or(std::cmp::Ordering::Equal)
906
- }
907
-
908
892
  #[derive(Debug, Default, Clone, Hash, PartialEq)]
909
893
  struct RowKey(value_table::Row);
910
894
 
@@ -932,7 +916,7 @@ fn create_aggregations_states(
932
916
  )?;
933
917
  let state = agg.aggregator.create(
934
918
  stack
935
- .to_vec()
919
+ .into_vec()
936
920
  .into_iter()
937
921
  .map(|v| v.try_into())
938
922
  .collect::<Result<_>>()?,
@@ -956,7 +940,7 @@ fn compute_return_with_table(
956
940
  {
957
941
  let mut output_table = value_table::ValueTable::new(variables_sizes.total_size());
958
942
  // Compute table
959
- if variables.iter().any(|v| v.aggregations.len() > 0)
943
+ if variables.iter().any(|v| !v.aggregations.is_empty())
960
944
  {
961
945
  // 1) For each row, compute non-aggregated columns, based on those columns, select a vector of aggregator states. and update them
962
946
 
@@ -970,19 +954,19 @@ fn compute_return_with_table(
970
954
  let out_row = variables
971
955
  .iter()
972
956
  .map(|rw_expr| {
973
- if rw_expr.aggregations.len() > 0
974
- {
975
- Ok(value::Value::Null)
976
- }
977
- else
957
+ if rw_expr.aggregations.is_empty()
978
958
  {
979
959
  assert_eq!(rw_expr.aggregations.len(), 0);
980
960
  let mut stack = Stack::default();
981
- eval_instructions(&mut stack, &row, &rw_expr.instructions, &parameters)?;
961
+ eval_instructions(&mut stack, &row, &rw_expr.instructions, parameters)?;
982
962
  let value: value::Value = stack.try_pop_into()?;
983
963
  row.set(rw_expr.col_id, value.to_owned())?;
984
964
  Ok(value)
985
965
  }
966
+ else
967
+ {
968
+ Ok(value::Value::Null)
969
+ }
986
970
  })
987
971
  .collect::<Result<Row>>()?;
988
972
  // b) initialise aggregations
@@ -1012,8 +996,8 @@ fn compute_return_with_table(
1012
996
  }
1013
997
  }
1014
998
 
1015
- // Aggregation always return at least once
1016
- if aggregation_table.is_empty()
999
+ // Aggregation always return at least once, unless there is a non-aggregated value
1000
+ if aggregation_table.is_empty() && variables.iter().all(|v| !v.aggregations.is_empty())
1017
1001
  {
1018
1002
  let row = Row::new(Default::default(), variables_sizes.total_size());
1019
1003
  let aggregations_states = create_aggregations_states(&variables, parameters)?;
@@ -1030,7 +1014,7 @@ fn compute_return_with_table(
1030
1014
  .zip(aggregations_states.into_iter())
1031
1015
  .enumerate()
1032
1016
  {
1033
- if rw_expr.aggregations.len() == 0
1017
+ if rw_expr.aggregations.is_empty()
1034
1018
  {
1035
1019
  out_row.set(rw_expr.col_id, row.0.get(idx)?.to_owned())?;
1036
1020
  }
@@ -1038,10 +1022,11 @@ fn compute_return_with_table(
1038
1022
  {
1039
1023
  for (name, s) in aggregation_states.into_iter()
1040
1024
  {
1041
- out_row.set(name, s.finalise()?)?;
1025
+ let value = s.finalise()?;
1026
+ out_row.set(name, value)?;
1042
1027
  }
1043
1028
  let mut stack = Stack::default();
1044
- eval_instructions(&mut stack, &out_row, &rw_expr.instructions, &parameters)?;
1029
+ eval_instructions(&mut stack, &out_row, &rw_expr.instructions, parameters)?;
1045
1030
  let value: value::Value = stack.try_pop_into()?;
1046
1031
  out_row.set(rw_expr.col_id, value.to_owned())?;
1047
1032
  }
@@ -1059,7 +1044,7 @@ fn compute_return_with_table(
1059
1044
  {
1060
1045
  assert_eq!(rw_expr.aggregations.len(), 0);
1061
1046
  let mut stack = Stack::default();
1062
- eval_instructions(&mut stack, &out_row, &rw_expr.instructions, &parameters)?;
1047
+ eval_instructions(&mut stack, &out_row, &rw_expr.instructions, parameters)?;
1063
1048
  let value: value::Value = stack.try_pop_into()?;
1064
1049
  out_row.set(rw_expr.col_id, value.to_owned())?;
1065
1050
  }
@@ -1070,7 +1055,7 @@ fn compute_return_with_table(
1070
1055
  // Apply filter
1071
1056
  if !filter.is_empty()
1072
1057
  {
1073
- output_table = filter_rows(output_table.into_row_iter(), &filter, &parameters)?.try_into()?;
1058
+ output_table = filter_rows(output_table.into_row_iter(), filter, parameters)?.try_into()?;
1074
1059
  }
1075
1060
  // Apply modifiers
1076
1061
  // Sort the table according to order_by
@@ -1083,7 +1068,7 @@ fn compute_return_with_table(
1083
1068
  for info in modifiers.order_by.iter()
1084
1069
  {
1085
1070
  let mut stack = Stack::default();
1086
- eval_instructions(&mut stack, &x, &info.instructions, &parameters)?;
1071
+ eval_instructions(&mut stack, &x, &info.instructions, parameters)?;
1087
1072
  v.push((stack.try_pop_into()?, info.asc));
1088
1073
  }
1089
1074
  Ok((x, v))
@@ -1106,7 +1091,7 @@ fn compute_return_with_table(
1106
1091
  if let Some(skip) = &modifiers.skip
1107
1092
  {
1108
1093
  let mut stack = Stack::default();
1109
- eval_instructions(&mut stack, &value_table::Row::default(), &skip, &parameters)?;
1094
+ eval_instructions(&mut stack, &value_table::Row::default(), skip, parameters)?;
1110
1095
  let q: i64 = stack
1111
1096
  .try_pop_into()
1112
1097
  .map_err(|_| RunTimeError::InvalidArgumentType)?;
@@ -1124,12 +1109,7 @@ fn compute_return_with_table(
1124
1109
  if let Some(limit) = &modifiers.limit
1125
1110
  {
1126
1111
  let mut stack = Stack::default();
1127
- eval_instructions(
1128
- &mut stack,
1129
- &value_table::Row::default(),
1130
- &limit,
1131
- &parameters,
1132
- )?;
1112
+ eval_instructions(&mut stack, &value_table::Row::default(), limit, parameters)?;
1133
1113
  let q: i64 = stack
1134
1114
  .try_pop_into()
1135
1115
  .map_err(|_| RunTimeError::InvalidArgumentType)?;
@@ -1154,7 +1134,7 @@ fn compute_return_with_table(
1154
1134
  0,
1155
1135
  ))
1156
1136
  })
1157
- .map(|r| value_table::RowResult(r))
1137
+ .map(value_table::RowResult)
1158
1138
  .collect()
1159
1139
  }
1160
1140
 
@@ -1168,7 +1148,7 @@ fn filter_rows(
1168
1148
  .filter_map(|row| {
1169
1149
  let res: Result<bool> = (|| {
1170
1150
  let mut stack = Stack::default();
1171
- eval_instructions(&mut stack, &row, &filter, &parameters)?;
1151
+ eval_instructions(&mut stack, &row, filter, parameters)?;
1172
1152
  stack.try_pop_as_boolean()
1173
1153
  })();
1174
1154
  match res
@@ -1195,24 +1175,24 @@ fn is_write_program(program: &super::Program) -> bool
1195
1175
  program.iter().any(|b| match b
1196
1176
  {
1197
1177
  Block::UseGraph { .. }
1198
- | Block::BlockMatch { .. }
1178
+ | Block::Match { .. }
1199
1179
  | Block::Return { .. }
1200
1180
  | Block::Unwind { .. }
1201
1181
  | Block::Call { .. }
1202
1182
  | Block::With { .. } => false,
1203
1183
  Block::CreateGraph { .. }
1184
+ | Block::DropGraph { .. }
1204
1185
  | Block::Create { .. }
1205
1186
  | Block::Update { .. }
1206
1187
  | Block::Delete { .. } => true,
1207
1188
  })
1208
1189
  }
1209
1190
 
1210
- ///
1211
1191
  pub(crate) fn eval_program<TStore: store::Store>(
1212
1192
  store: &TStore,
1213
1193
  program: &super::Program,
1214
1194
  parameters: &crate::value::ValueMap,
1215
- ) -> crate::Result<crate::value::Value>
1195
+ ) -> crate::Result<query_result::QueryResult>
1216
1196
  {
1217
1197
  let mut graph_name: String = "default".into();
1218
1198
  let mut input_table = value_table::ValueTable::new(0);
@@ -1245,6 +1225,16 @@ pub(crate) fn eval_program<TStore: store::Store>(
1245
1225
  } ))?;
1246
1226
  graph_name = name.to_owned();
1247
1227
  }
1228
+ instructions::Block::DropGraph { name, if_exists } =>
1229
+ {
1230
+ store
1231
+ .drop_graph(&mut tx, name, *if_exists)
1232
+ .map_err(|e|
1233
+ error::map_error!(e, Error::StoreError(StoreError::UnknownGraph { graph_name }) => RunTimeError::UnknownGraph {
1234
+ graph_name: graph_name.clone(),
1235
+ } ))?;
1236
+ graph_name = name.to_owned();
1237
+ }
1248
1238
  instructions::Block::UseGraph { name } =>
1249
1239
  {
1250
1240
  graph_name = name.to_owned();
@@ -1266,7 +1256,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1266
1256
  let mut new_row = row.extended(variables_size.total_size())?;
1267
1257
  for action in actions.iter()
1268
1258
  {
1269
- eval_instructions(&mut stack, &new_row, &action.instructions, &parameters)?;
1259
+ eval_instructions(&mut stack, &new_row, &action.instructions, parameters)?;
1270
1260
  for (v, var) in stack
1271
1261
  .try_drain_into(action.variables.len())?
1272
1262
  .into_iter()
@@ -1276,18 +1266,18 @@ pub(crate) fn eval_program<TStore: store::Store>(
1276
1266
  {
1277
1267
  crate::value::Value::Node(n) =>
1278
1268
  {
1279
- store.create_nodes(&mut tx, &graph_name, vec![n.to_owned()].iter())?;
1269
+ store.create_nodes(&mut tx, &graph_name, vec![&n])?;
1280
1270
  if let Some(var) = var
1281
1271
  {
1282
1272
  new_row.set_if_unset(*var, crate::value::Value::Node(n))?;
1283
1273
  }
1284
1274
  }
1285
- crate::value::Value::Edge(e) =>
1275
+ crate::value::Value::Path(p) =>
1286
1276
  {
1287
- store.create_edges(&mut tx, &graph_name, vec![e.to_owned()].iter())?;
1277
+ store.create_edges(&mut tx, &graph_name, vec![&p])?;
1288
1278
  if let Some(var) = var
1289
1279
  {
1290
- new_row.set(*var, crate::value::Value::Edge(e))?;
1280
+ new_row.set(*var, crate::value::Value::Edge(p.into()))?;
1291
1281
  }
1292
1282
  }
1293
1283
  _ =>
@@ -1301,7 +1291,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1301
1291
  }
1302
1292
  input_table = output_table;
1303
1293
  }
1304
- instructions::Block::BlockMatch {
1294
+ instructions::Block::Match {
1305
1295
  blocks,
1306
1296
  filter,
1307
1297
  optional,
@@ -1325,21 +1315,16 @@ pub(crate) fn eval_program<TStore: store::Store>(
1325
1315
  filter,
1326
1316
  } =>
1327
1317
  {
1328
- eval_instructions(&mut stack, &row, &instructions, &parameters)?;
1318
+ eval_instructions(&mut stack, &row, instructions, parameters)?;
1329
1319
  let query: store::SelectNodeQuery = stack.try_pop_into()?;
1330
1320
  let nodes = store.select_nodes(&mut tx, &graph_name, query)?;
1331
1321
 
1332
- for node in nodes.iter()
1322
+ for node in nodes.into_iter()
1333
1323
  {
1334
1324
  let mut new_row = row.clone();
1335
- match &variable
1325
+ if let Some(variable) = variable
1336
1326
  {
1337
- Some(variable) =>
1338
- {
1339
- new_row.set_if_unset(*variable, node.to_owned().into())?;
1340
- }
1341
- None =>
1342
- {}
1327
+ new_row.set_if_unset(*variable, node.to_owned().into())?;
1343
1328
  }
1344
1329
  let should_add_row = if filter.is_empty()
1345
1330
  {
@@ -1349,8 +1334,8 @@ pub(crate) fn eval_program<TStore: store::Store>(
1349
1334
  {
1350
1335
  let mut stack = Stack::default();
1351
1336
  stack.push(true);
1352
- stack.push(node.to_owned());
1353
- eval_instructions(&mut stack, &new_row, &filter, &parameters)?;
1337
+ stack.push(node);
1338
+ eval_instructions(&mut stack, &new_row, filter, parameters)?;
1354
1339
  stack.try_pop()?; // Get rid of the edge
1355
1340
  stack.try_pop_into()?
1356
1341
  };
@@ -1370,54 +1355,37 @@ pub(crate) fn eval_program<TStore: store::Store>(
1370
1355
  directivity,
1371
1356
  } =>
1372
1357
  {
1373
- eval_instructions(&mut stack, &row, &instructions, &parameters)?;
1358
+ eval_instructions(&mut stack, &row, instructions, parameters)?;
1374
1359
  let query = stack.try_pop_into()?;
1375
1360
 
1376
1361
  let edges = store.select_edges(&mut tx, &graph_name, query, *directivity)?;
1377
1362
 
1378
- for edge in edges.iter()
1363
+ for edge in edges.into_iter()
1379
1364
  {
1380
1365
  let mut new_row = row.clone();
1366
+ let (left, right) = if edge.reversed
1367
+ {
1368
+ (edge.path.destination(), edge.path.source())
1369
+ }
1370
+ else
1371
+ {
1372
+ (edge.path.source(), edge.path.destination())
1373
+ };
1381
1374
  if let Some(left_variable) = left_variable.to_owned()
1382
1375
  {
1383
- new_row.set(
1384
- left_variable,
1385
- if edge.reversed
1386
- {
1387
- edge.edge.destination.to_owned()
1388
- }
1389
- else
1390
- {
1391
- edge.edge.source.to_owned()
1392
- }
1393
- .into(),
1394
- )?;
1376
+ new_row.set(left_variable, left.to_owned().into())?;
1395
1377
  }
1396
1378
  if let Some(right_variable) = right_variable.to_owned()
1397
1379
  {
1398
- new_row.set(
1399
- right_variable,
1400
- if edge.reversed
1401
- {
1402
- edge.edge.source.to_owned()
1403
- }
1404
- else
1405
- {
1406
- edge.edge.destination.to_owned()
1407
- }
1408
- .into(),
1409
- )?;
1380
+ new_row.set(right_variable, right.to_owned().into())?;
1410
1381
  }
1411
1382
  if let Some(edge_variable) = edge_variable.to_owned()
1412
1383
  {
1413
- new_row.set(edge_variable, edge.edge.to_owned().into())?;
1384
+ new_row.set(edge_variable, edge.path.to_edge().into())?;
1414
1385
  }
1415
1386
  if let Some(path_variable) = path_variable.to_owned()
1416
1387
  {
1417
- new_row.set(
1418
- path_variable,
1419
- crate::value::Value::Path(edge.edge.to_owned().into()),
1420
- )?;
1388
+ new_row.set(path_variable, edge.path.to_owned().into())?;
1421
1389
  }
1422
1390
  let should_add_row = if filter.is_empty()
1423
1391
  {
@@ -1427,8 +1395,8 @@ pub(crate) fn eval_program<TStore: store::Store>(
1427
1395
  {
1428
1396
  let mut stack = Stack::default();
1429
1397
  stack.push(true);
1430
- stack.push(edge.edge.to_owned());
1431
- eval_instructions(&mut stack, &new_row, &filter, &parameters)?;
1398
+ stack.push(edge.path.into_edge());
1399
+ eval_instructions(&mut stack, &new_row, filter, parameters)?;
1432
1400
  stack.try_pop()?; // Get rid of the edge
1433
1401
  stack.try_pop_into()?
1434
1402
  };
@@ -1444,7 +1412,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1444
1412
  }
1445
1413
  if !filter.is_empty()
1446
1414
  {
1447
- current_rows = filter_rows(current_rows.into_iter(), &filter, &parameters)?;
1415
+ current_rows = filter_rows(current_rows.into_iter(), filter, parameters)?;
1448
1416
  }
1449
1417
  if current_rows.is_empty() && *optional
1450
1418
  {
@@ -1464,29 +1432,23 @@ pub(crate) fn eval_program<TStore: store::Store>(
1464
1432
  variables_size,
1465
1433
  } =>
1466
1434
  {
1467
- let (names, variables): (Vec<_>, Vec<_>) =
1468
- variables.into_iter().map(|(s, e)| (s, e)).unzip();
1435
+ let (names, variables): (Vec<_>, Vec<_>) = variables.iter().map(|(s, e)| (s, e)).unzip();
1469
1436
  let output_table = compute_return_with_table(
1470
1437
  variables,
1471
- &filter,
1472
- &modifiers,
1438
+ filter,
1439
+ modifiers,
1473
1440
  input_table,
1474
- &parameters,
1475
- &variables_size,
1441
+ parameters,
1442
+ variables_size,
1476
1443
  )?;
1477
- let mut r = Vec::<crate::value::Value>::new();
1478
- r.push(crate::value::Value::Array(
1479
- names
1480
- .into_iter()
1481
- .map(|name| crate::value::Value::String(name.to_owned()))
1482
- .collect(),
1483
- ));
1444
+ let headers = names.into_iter().map(|name| name.to_owned()).collect();
1445
+ let mut data = Vec::<crate::value::Value>::new();
1484
1446
  for row in output_table.into_row_iter()
1485
1447
  {
1486
- r.push(row.into());
1448
+ data.extend(row.into_iter());
1487
1449
  }
1488
1450
  tx.close()?;
1489
- return Ok(r.into());
1451
+ return Ok(graphcore::Table::new(headers, data)?.into());
1490
1452
  }
1491
1453
  instructions::Block::With {
1492
1454
  variables,
@@ -1497,11 +1459,11 @@ pub(crate) fn eval_program<TStore: store::Store>(
1497
1459
  {
1498
1460
  input_table = compute_return_with_table(
1499
1461
  variables.iter().collect(),
1500
- &filter,
1501
- &modifiers,
1462
+ filter,
1463
+ modifiers,
1502
1464
  input_table,
1503
- &parameters,
1504
- &variables_size,
1465
+ parameters,
1466
+ variables_size,
1505
1467
  )?;
1506
1468
  }
1507
1469
  instructions::Block::Unwind {
@@ -1514,7 +1476,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1514
1476
  for row in input_table.into_row_iter()
1515
1477
  {
1516
1478
  let mut stack = Stack::default();
1517
- eval_instructions(&mut stack, &row, &instructions, &parameters)?;
1479
+ eval_instructions(&mut stack, &row, instructions, parameters)?;
1518
1480
  let value = stack.try_pop_into()?;
1519
1481
  match value
1520
1482
  {
@@ -1551,12 +1513,12 @@ pub(crate) fn eval_program<TStore: store::Store>(
1551
1513
  for instructions in instructions.iter()
1552
1514
  {
1553
1515
  let mut stack = Stack::default();
1554
- eval_instructions(&mut stack, &row, &instructions, &parameters)?;
1516
+ eval_instructions(&mut stack, &row, instructions, parameters)?;
1555
1517
  let value: value::Value = stack.try_pop_into()?;
1556
1518
  match value
1557
1519
  {
1558
- value::Value::Node(node) => nodes_keys.push(node.key),
1559
- value::Value::Edge(edge) => edges_keys.push(edge.key),
1520
+ value::Value::Node(node) => nodes_keys.push(node.unpack().0),
1521
+ value::Value::Edge(edge) => edges_keys.push(edge.unpack().0),
1560
1522
  value::Value::Null =>
1561
1523
  {}
1562
1524
  _ => return Err(RunTimeError::InvalidDelete.into()),
@@ -1604,7 +1566,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1604
1566
  *target,
1605
1567
  path,
1606
1568
  instructions,
1607
- &parameters,
1569
+ parameters,
1608
1570
  true,
1609
1571
  )?;
1610
1572
  }
@@ -1622,7 +1584,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1622
1584
  *target,
1623
1585
  path,
1624
1586
  instructions,
1625
- &parameters,
1587
+ parameters,
1626
1588
  false,
1627
1589
  )?;
1628
1590
  }
@@ -1635,14 +1597,14 @@ pub(crate) fn eval_program<TStore: store::Store>(
1635
1597
  value::Value::Node(n) =>
1636
1598
  {
1637
1599
  let mut n = n.to_owned();
1638
- n.properties.remove_value(piter.next(), piter)?;
1600
+ n.properties_mut().remove_value(piter.next(), piter)?;
1639
1601
  store.update_node(&mut tx, &graph_name, &n)?;
1640
1602
  out_row.set(*target, n.into())?;
1641
1603
  }
1642
1604
  value::Value::Edge(e) =>
1643
1605
  {
1644
1606
  let mut e = e.to_owned();
1645
- e.properties.remove_value(piter.next(), piter)?;
1607
+ e.properties_mut().remove_value(piter.next(), piter)?;
1646
1608
  store.update_edge(&mut tx, &graph_name, &e)?;
1647
1609
  out_row.set(*target, e.into())?;
1648
1610
  }
@@ -1673,15 +1635,11 @@ pub(crate) fn eval_program<TStore: store::Store>(
1673
1635
  let mut n = n.to_owned();
1674
1636
  if add_labels
1675
1637
  {
1676
- n.labels.append(&mut labels.clone());
1638
+ n.labels_mut().append(&mut labels.clone());
1677
1639
  }
1678
1640
  else
1679
1641
  {
1680
- n.labels = n
1681
- .labels
1682
- .into_iter()
1683
- .filter(|x| !labels.contains(x))
1684
- .collect();
1642
+ n.labels_edit(|l| l.into_iter().filter(|x| !labels.contains(x)).collect());
1685
1643
  }
1686
1644
  store.update_node(&mut tx, &graph_name, &n)?;
1687
1645
  out_row.set(*target, n.into())?;
@@ -1691,15 +1649,11 @@ pub(crate) fn eval_program<TStore: store::Store>(
1691
1649
  let mut e = e.to_owned();
1692
1650
  if add_labels
1693
1651
  {
1694
- e.labels.append(&mut labels.clone());
1652
+ e.labels_mut().append(&mut labels.clone());
1695
1653
  }
1696
1654
  else
1697
1655
  {
1698
- e.labels = e
1699
- .labels
1700
- .into_iter()
1701
- .filter(|x| !labels.contains(x))
1702
- .collect();
1656
+ e.labels_edit(|l| l.into_iter().filter(|x| !labels.contains(x)).collect());
1703
1657
  }
1704
1658
  store.update_edge(&mut tx, &graph_name, &e)?;
1705
1659
  out_row.set(*target, e.into())?;
@@ -1733,7 +1687,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1733
1687
  "properties_count".into(),
1734
1688
  (stats.properties_count as i64).into(),
1735
1689
  );
1736
- return Ok(crate::value::Value::Map(res));
1690
+ return Ok(crate::value::Value::Map(res).into());
1737
1691
  }
1738
1692
  else
1739
1693
  {
@@ -1743,7 +1697,7 @@ pub(crate) fn eval_program<TStore: store::Store>(
1743
1697
  }
1744
1698
  }
1745
1699
  tx.close()?;
1746
- Ok(crate::value::Value::Null)
1700
+ Ok(crate::QueryResult::Empty)
1747
1701
  }
1748
1702
 
1749
1703
  #[cfg(test)]