gqlite 1.1.0 → 1.2.2

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gqliterb/.cargo/config.toml +2 -0
  3. data/ext/gqliterb/Cargo.lock +1109 -0
  4. data/ext/gqliterb/Cargo.toml +43 -0
  5. data/ext/gqliterb/extconf.rb +4 -0
  6. data/ext/gqliterb/src/lib.rs +260 -0
  7. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2060 -0
  8. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +132 -0
  9. data/ext/gqliterb/vendor/gqlitedb/askama.toml +3 -0
  10. data/ext/gqliterb/vendor/gqlitedb/benches/common/mod.rs +25 -0
  11. data/ext/gqliterb/vendor/gqlitedb/benches/common/pokec.rs +185 -0
  12. data/ext/gqliterb/vendor/gqlitedb/benches/pokec_divan.rs +137 -0
  13. data/ext/gqliterb/vendor/gqlitedb/benches/pokec_iai.rs +122 -0
  14. data/ext/gqliterb/vendor/gqlitedb/release.toml +7 -0
  15. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/arithmetic.rs +96 -0
  16. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/containers.rs +33 -0
  17. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/count.rs +35 -0
  18. data/ext/gqliterb/vendor/gqlitedb/src/aggregators/stats.rs +168 -0
  19. data/ext/gqliterb/vendor/gqlitedb/src/aggregators.rs +74 -0
  20. data/ext/gqliterb/vendor/gqlitedb/src/capi.rs +236 -0
  21. data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +427 -0
  22. data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +620 -0
  23. data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1106 -0
  24. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +208 -0
  25. data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
  26. data/ext/gqliterb/vendor/gqlitedb/src/error.rs +621 -0
  27. data/ext/gqliterb/vendor/gqlitedb/src/functions/containers.rs +115 -0
  28. data/ext/gqliterb/vendor/gqlitedb/src/functions/edge.rs +20 -0
  29. data/ext/gqliterb/vendor/gqlitedb/src/functions/math.rs +44 -0
  30. data/ext/gqliterb/vendor/gqlitedb/src/functions/node.rs +16 -0
  31. data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +48 -0
  32. data/ext/gqliterb/vendor/gqlitedb/src/functions/scalar.rs +86 -0
  33. data/ext/gqliterb/vendor/gqlitedb/src/functions/string.rs +28 -0
  34. data/ext/gqliterb/vendor/gqlitedb/src/functions/value.rs +99 -0
  35. data/ext/gqliterb/vendor/gqlitedb/src/functions.rs +412 -0
  36. data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +268 -0
  37. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1788 -0
  38. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +262 -0
  39. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
  40. data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +42 -0
  41. data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +625 -0
  42. data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +191 -0
  43. data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1153 -0
  44. data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +4 -0
  45. data/ext/gqliterb/vendor/gqlitedb/src/prelude.rs +8 -0
  46. data/ext/gqliterb/vendor/gqlitedb/src/serialize_with.rs +94 -0
  47. data/ext/gqliterb/vendor/gqlitedb/src/store/pgql.rs +121 -0
  48. data/ext/gqliterb/vendor/gqlitedb/src/store/redb.rs +1250 -0
  49. data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +994 -0
  50. data/ext/gqliterb/vendor/gqlitedb/src/store.rs +432 -0
  51. data/ext/gqliterb/vendor/gqlitedb/src/tests/compiler.rs +92 -0
  52. data/ext/gqliterb/vendor/gqlitedb/src/tests/evaluators.rs +227 -0
  53. data/ext/gqliterb/vendor/gqlitedb/src/tests/parser.rs +81 -0
  54. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/redb.rs +39 -0
  55. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +39 -0
  56. data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +462 -0
  57. data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/ast.rs +356 -0
  58. data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/programs.rs +455 -0
  59. data/ext/gqliterb/vendor/gqlitedb/src/tests/templates.rs +2 -0
  60. data/ext/gqliterb/vendor/gqlitedb/src/tests.rs +39 -0
  61. data/ext/gqliterb/vendor/gqlitedb/src/utils.rs +28 -0
  62. data/ext/gqliterb/vendor/gqlitedb/src/value/compare.rs +212 -0
  63. data/ext/gqliterb/vendor/gqlitedb/src/value/contains.rs +47 -0
  64. data/ext/gqliterb/vendor/gqlitedb/src/value/value_map.rs +298 -0
  65. data/ext/gqliterb/vendor/gqlitedb/src/value.rs +559 -0
  66. data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +616 -0
  67. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/call_stats.sql +22 -0
  68. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_count_for_node.sql +3 -0
  69. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_create.sql +6 -0
  70. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete.sql +1 -0
  71. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete_by_nodes.sql +2 -0
  72. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_select.sql +139 -0
  73. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_update.sql +4 -0
  74. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_create.sql +16 -0
  75. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_delete.sql +3 -0
  76. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_create_table.sql +1 -0
  77. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_get.sql +1 -0
  78. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_set.sql +1 -0
  79. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_create.sql +1 -0
  80. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_delete.sql +1 -0
  81. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_select.sql +42 -0
  82. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_update.sql +4 -0
  83. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/table_exists.sql +5 -0
  84. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_from_1_01.sql +2 -0
  85. data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_graph_from_1_01.sql +65 -0
  86. data/lib/gqlite.rb +1 -75
  87. metadata +118 -25
  88. data/ext/gqlite/extconf.rb +0 -21
  89. data/ext/gqlite/gqlite-amalgamate.cpp +0 -9599
  90. data/ext/gqlite/gqlite-c.h +0 -95
  91. data/ext/gqlite/gqlite.h +0 -141
@@ -0,0 +1,1106 @@
1
+ pub(crate) mod expression_analyser;
2
+ pub(crate) mod variables_manager;
3
+
4
+ use crate::{
5
+ compiler::variables_manager::VariablesManager, interpreter::instructions::VariablesSizes,
6
+ prelude::*,
7
+ };
8
+
9
+ use interpreter::instructions::{
10
+ self, Block, BlockMatch, CreateAction, Instruction, Instructions, Modifiers, RWAggregation,
11
+ RWExpression,
12
+ };
13
+ use parser::ast;
14
+
15
+ macro_rules! compile_binary_op {
16
+ ( $this:tt, $x:tt, $instructions:tt, $aggregations:tt ) => {
17
+ $this.compile_expression(&$x.right, $instructions, $aggregations)?;
18
+ $this.compile_expression(&$x.left, $instructions, $aggregations)?;
19
+ };
20
+ }
21
+
22
+ struct Compiler
23
+ {
24
+ function_manager: functions::Manager,
25
+ variables_manager: variables_manager::VariablesManager,
26
+ temporary_variables: usize,
27
+ }
28
+
29
+ impl Compiler
30
+ {
31
+ /// Get the variables sizes from the current state of the compiler.
32
+ fn variables_size(&self) -> instructions::VariablesSizes
33
+ {
34
+ instructions::VariablesSizes {
35
+ temporary_variables: self.temporary_variables,
36
+ persistent_variables: self.variables_manager.variables_count(),
37
+ }
38
+ }
39
+
40
+ fn create_temporary_variable(&mut self) -> usize
41
+ {
42
+ let col_id = self.temporary_variables;
43
+ self.temporary_variables += 1;
44
+ col_id + self.variables_manager.variables_count()
45
+ }
46
+
47
+ fn compile_expression(
48
+ &mut self,
49
+ expression: &crate::parser::ast::Expression,
50
+ instructions: &mut Instructions,
51
+ aggregations: &mut Option<&mut Vec<(value_table::ColId, RWAggregation)>>,
52
+ ) -> Result<()>
53
+ {
54
+ expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
55
+ .analyse(&expression)?;
56
+
57
+ let expr = match expression
58
+ {
59
+ ast::Expression::Value(value) => Instruction::Push {
60
+ value: value.value.clone(),
61
+ },
62
+ ast::Expression::Variable(variable) => Instruction::GetVariable {
63
+ col_id: self
64
+ .variables_manager
65
+ .get_variable_index(&variable.identifier)?,
66
+ },
67
+ ast::Expression::Parameter(parameter) => Instruction::GetParameter {
68
+ name: parameter.name.clone(),
69
+ },
70
+ ast::Expression::FunctionCall(function_call) =>
71
+ {
72
+ let aggregator = self
73
+ .function_manager
74
+ .get_aggregator::<CompileTimeError>(&function_call.name);
75
+ match aggregator
76
+ {
77
+ Ok(aggregator) =>
78
+ {
79
+ let var_col_id = self.create_temporary_variable();
80
+ let mut init_instructions = Instructions::new();
81
+ let mut argument_instructions = Instructions::new();
82
+
83
+ self.compile_expression(
84
+ function_call
85
+ .arguments
86
+ .get(0)
87
+ .ok_or(error::InternalError::MissingAggregationArgument)?,
88
+ &mut argument_instructions,
89
+ aggregations,
90
+ )?;
91
+ if let Some(init_arg) = function_call.arguments.get(1)
92
+ {
93
+ self.compile_expression(init_arg, &mut init_instructions, aggregations)?;
94
+ }
95
+
96
+ aggregations
97
+ .as_mut()
98
+ .ok_or(error::InternalError::MissingAggregations)?
99
+ .push((
100
+ var_col_id,
101
+ RWAggregation {
102
+ init_instructions,
103
+ aggregator,
104
+ argument_instructions,
105
+ },
106
+ ));
107
+ Instruction::GetVariable { col_id: var_col_id }
108
+ }
109
+ Err(_) =>
110
+ {
111
+ for v in function_call.arguments.iter()
112
+ {
113
+ self.compile_expression(v, instructions, aggregations)?;
114
+ }
115
+
116
+ let function = self
117
+ .function_manager
118
+ .get_function::<CompileTimeError>(&function_call.name)?;
119
+ Instruction::FunctionCall {
120
+ function,
121
+ arguments_count: function_call.arguments.len(),
122
+ }
123
+ }
124
+ }
125
+ }
126
+ ast::Expression::Array(array) =>
127
+ {
128
+ for v in array.array.iter()
129
+ {
130
+ self.compile_expression(v, instructions, aggregations)?;
131
+ }
132
+ Instruction::CreateArray {
133
+ length: array.array.len(),
134
+ }
135
+ }
136
+ ast::Expression::Map(map) =>
137
+ {
138
+ let mut keys = Vec::new();
139
+ for (k, v) in map.map.iter()
140
+ {
141
+ self.compile_expression(v, instructions, aggregations)?;
142
+ keys.push(k.to_owned());
143
+ }
144
+ Instruction::CreateMap { keys: keys }
145
+ }
146
+ ast::Expression::MemberAccess(member_access) =>
147
+ {
148
+ self.compile_expression(&member_access.left, instructions, aggregations)?;
149
+ Instruction::MemberAccess {
150
+ path: member_access.path.to_owned(),
151
+ }
152
+ }
153
+ ast::Expression::IndexAccess(index_access) =>
154
+ {
155
+ self.compile_expression(&index_access.left, instructions, aggregations)?;
156
+ self.compile_expression(&index_access.index, instructions, aggregations)?;
157
+ Instruction::IndexAccess
158
+ }
159
+ ast::Expression::RangeAccess(index_access) =>
160
+ {
161
+ self.compile_expression(&index_access.left, instructions, aggregations)?;
162
+ let start = if let Some(start) = &index_access.start
163
+ {
164
+ self.compile_expression(start, instructions, aggregations)?;
165
+ true
166
+ }
167
+ else
168
+ {
169
+ false
170
+ };
171
+ let end = if let Some(end) = &index_access.end
172
+ {
173
+ self.compile_expression(end, instructions, aggregations)?;
174
+ true
175
+ }
176
+ else
177
+ {
178
+ false
179
+ };
180
+
181
+ Instruction::RangeAccess { start, end }
182
+ }
183
+ ast::Expression::LogicalAnd(logical_and) =>
184
+ {
185
+ compile_binary_op!(self, logical_and, instructions, aggregations);
186
+ Instruction::AndBinaryOperator
187
+ }
188
+ ast::Expression::LogicalOr(logical_or) =>
189
+ {
190
+ compile_binary_op!(self, logical_or, instructions, aggregations);
191
+ Instruction::OrBinaryOperator
192
+ }
193
+ ast::Expression::LogicalXor(logical_xor) =>
194
+ {
195
+ compile_binary_op!(self, logical_xor, instructions, aggregations);
196
+ Instruction::XorBinaryOperator
197
+ }
198
+ ast::Expression::RelationalEqual(relational_equal) =>
199
+ {
200
+ compile_binary_op!(self, relational_equal, instructions, aggregations);
201
+ Instruction::EqualBinaryOperator
202
+ }
203
+ ast::Expression::RelationalDifferent(relational_different) =>
204
+ {
205
+ compile_binary_op!(self, relational_different, instructions, aggregations);
206
+ Instruction::NotEqualBinaryOperator
207
+ }
208
+ ast::Expression::RelationalInferior(relational_inferior) =>
209
+ {
210
+ compile_binary_op!(self, relational_inferior, instructions, aggregations);
211
+ Instruction::InferiorBinaryOperator
212
+ }
213
+ ast::Expression::RelationalSuperior(relational_superior) =>
214
+ {
215
+ compile_binary_op!(self, relational_superior, instructions, aggregations);
216
+ Instruction::SuperiorBinaryOperator
217
+ }
218
+ ast::Expression::RelationalInferiorEqual(relational_inferior_equal) =>
219
+ {
220
+ compile_binary_op!(self, relational_inferior_equal, instructions, aggregations);
221
+ Instruction::InferiorEqualBinaryOperator
222
+ }
223
+ ast::Expression::RelationalSuperiorEqual(relational_superior_equal) =>
224
+ {
225
+ compile_binary_op!(self, relational_superior_equal, instructions, aggregations);
226
+ Instruction::SuperiorEqualBinaryOperator
227
+ }
228
+ ast::Expression::RelationalIn(relational_in) =>
229
+ {
230
+ compile_binary_op!(self, relational_in, instructions, aggregations);
231
+ Instruction::InBinaryOperator
232
+ }
233
+ ast::Expression::RelationalNotIn(relational_not_in) =>
234
+ {
235
+ compile_binary_op!(self, relational_not_in, instructions, aggregations);
236
+ Instruction::NotInBinaryOperator
237
+ }
238
+
239
+ ast::Expression::Addition(addition) =>
240
+ {
241
+ compile_binary_op!(self, addition, instructions, aggregations);
242
+ Instruction::AdditionBinaryOperator
243
+ }
244
+ ast::Expression::Subtraction(subtraction) =>
245
+ {
246
+ compile_binary_op!(self, subtraction, instructions, aggregations);
247
+ Instruction::SubtractionBinaryOperator
248
+ }
249
+ ast::Expression::Multiplication(multiplication) =>
250
+ {
251
+ compile_binary_op!(self, multiplication, instructions, aggregations);
252
+ Instruction::MultiplicationBinaryOperator
253
+ }
254
+ ast::Expression::Division(division) =>
255
+ {
256
+ compile_binary_op!(self, division, instructions, aggregations);
257
+ Instruction::DivisionBinaryOperator
258
+ }
259
+ ast::Expression::Modulo(modulo) =>
260
+ {
261
+ compile_binary_op!(self, modulo, instructions, aggregations);
262
+ Instruction::ModuloBinaryOperator
263
+ }
264
+ ast::Expression::Negation(logical_negation) =>
265
+ {
266
+ self.compile_expression(&logical_negation.value, instructions, aggregations)?;
267
+ Instruction::NegationUnaryOperator
268
+ }
269
+ ast::Expression::LogicalNegation(logical_negation) =>
270
+ {
271
+ self.compile_expression(&logical_negation.value, instructions, aggregations)?;
272
+ Instruction::NotUnaryOperator
273
+ }
274
+ ast::Expression::IsNull(is_null) =>
275
+ {
276
+ self.compile_expression(&is_null.value, instructions, aggregations)?;
277
+ Instruction::IsNullUnaryOperator
278
+ }
279
+ ast::Expression::IsNotNull(is_null) =>
280
+ {
281
+ self.compile_expression(&is_null.value, instructions, aggregations)?;
282
+ instructions.push(Instruction::IsNullUnaryOperator);
283
+ Instruction::NotUnaryOperator
284
+ }
285
+ };
286
+ instructions.push(expr);
287
+ Ok(())
288
+ }
289
+
290
+ fn compile_optional_expression(
291
+ &mut self,
292
+ properties: &Option<ast::Expression>,
293
+ instructions: &mut Instructions,
294
+ ) -> Result<()>
295
+ {
296
+ if let Some(expr) = properties
297
+ {
298
+ self.compile_expression(expr, instructions, &mut None)?;
299
+ }
300
+ else
301
+ {
302
+ instructions.push(Instruction::Push {
303
+ value: crate::value::Value::Map(Default::default()),
304
+ });
305
+ }
306
+ Ok(())
307
+ }
308
+
309
+ fn compile_create_node(
310
+ &mut self,
311
+ node: &crate::parser::ast::NodePattern,
312
+ instructions: &mut Instructions,
313
+ variables: &mut Vec<Option<value_table::ColId>>,
314
+ ) -> Result<()>
315
+ {
316
+ variables.push(
317
+ self
318
+ .variables_manager
319
+ .get_variable_index_option(&node.variable)?,
320
+ );
321
+ self
322
+ .variables_manager
323
+ .mark_variables_as_set(&node.variable)?;
324
+ self.compile_optional_expression(&node.properties, instructions)?;
325
+ let mut labels = Default::default();
326
+ self.compile_labels_expression(&mut labels, &node.labels)?;
327
+ instructions.push(Instruction::CreateNodeLiteral { labels });
328
+ Ok(())
329
+ }
330
+
331
+ fn compile_labels_expression(
332
+ &mut self,
333
+ labels: &mut Vec<String>,
334
+ label_expressions: &ast::LabelExpression,
335
+ ) -> Result<()>
336
+ {
337
+ match &label_expressions
338
+ {
339
+ &ast::LabelExpression::And(expressions) =>
340
+ {
341
+ for expr in expressions.iter()
342
+ {
343
+ self.compile_labels_expression(labels, &expr)?;
344
+ }
345
+ Ok(())
346
+ }
347
+ &ast::LabelExpression::String(label) =>
348
+ {
349
+ labels.push(label.to_owned());
350
+ Ok(())
351
+ }
352
+ &ast::LabelExpression::None => Ok(()),
353
+ _ => Err(
354
+ InternalError::InvalidCreateLabels {
355
+ context: "compile_create_labels",
356
+ }
357
+ .into(),
358
+ ),
359
+ }
360
+ }
361
+
362
+ // Assume top of the stack contains an edge or node
363
+ fn compile_filter_labels(
364
+ &mut self,
365
+ instructions: &mut Instructions,
366
+ label_expressions: &ast::LabelExpression,
367
+ has_label_function: &functions::Function,
368
+ ) -> Result<()>
369
+ {
370
+ match &label_expressions
371
+ {
372
+ &ast::LabelExpression::And(expressions) =>
373
+ {
374
+ instructions.push(Instruction::Push { value: true.into() });
375
+ instructions.push(Instruction::Swap);
376
+ for expr in expressions.iter()
377
+ {
378
+ self.compile_filter_labels(instructions, expr, has_label_function)?;
379
+ // stack contains (a: bool) (b: labels) (c: bool)
380
+ instructions.push(Instruction::InverseRot3);
381
+ // stack contains (c: bool) (a: bool) (b: labels)
382
+ instructions.push(Instruction::AndBinaryOperator);
383
+ // stack contains (a&c: bool) (b: labels)
384
+ instructions.push(Instruction::Swap);
385
+ // stack contains (b: labels) (a&&c: bool)
386
+ }
387
+ Ok(())
388
+ }
389
+ &ast::LabelExpression::Or(expressions) =>
390
+ {
391
+ instructions.push(Instruction::Push {
392
+ value: false.into(),
393
+ });
394
+ instructions.push(Instruction::Swap);
395
+ for expr in expressions.iter()
396
+ {
397
+ self.compile_filter_labels(instructions, expr, has_label_function)?;
398
+ // stack contains (a: bool) (b: labels) (c: bool)
399
+ instructions.push(Instruction::InverseRot3);
400
+ // stack contains (c: bool) (a: bool) (b: labels)
401
+ instructions.push(Instruction::OrBinaryOperator);
402
+ // stack contains (a||c: bool) (b: labels)
403
+ instructions.push(Instruction::Swap);
404
+ // stack contains (b: labels) (a||c: bool)
405
+ }
406
+ Ok(())
407
+ }
408
+ &ast::LabelExpression::Not(expr) =>
409
+ {
410
+ self.compile_filter_labels(instructions, expr, has_label_function)?;
411
+ instructions.push(Instruction::NotUnaryOperator);
412
+ Ok(())
413
+ }
414
+ &ast::LabelExpression::String(label) =>
415
+ {
416
+ instructions.push(Instruction::Duplicate);
417
+ instructions.push(Instruction::Push {
418
+ value: label.to_owned().into(),
419
+ });
420
+ instructions.push(Instruction::FunctionCall {
421
+ function: has_label_function.to_owned(),
422
+ arguments_count: 2,
423
+ });
424
+ Ok(())
425
+ }
426
+ &ast::LabelExpression::None =>
427
+ {
428
+ instructions.push(Instruction::Push { value: true.into() });
429
+ Ok(())
430
+ }
431
+ }
432
+ }
433
+
434
+ fn compile_create_patterns(
435
+ &mut self,
436
+ patterns: &Vec<crate::parser::ast::Pattern>,
437
+ ) -> Result<Block>
438
+ {
439
+ let actions = patterns.iter().map(|c| {
440
+ let mut instructions = Instructions::new();
441
+ let mut variables = Vec::<Option<value_table::ColId>>::new();
442
+ match c
443
+ {
444
+ crate::parser::ast::Pattern::Node(node) =>
445
+ {
446
+ self.compile_create_node(node, &mut instructions, &mut variables)?;
447
+ }
448
+ crate::parser::ast::Pattern::Edge(edge) =>
449
+ {
450
+ // Generate source
451
+ if self
452
+ .variables_manager
453
+ .is_set_variable(&edge.source.variable)?
454
+ {
455
+ instructions.push(Instruction::GetVariable {
456
+ col_id: self
457
+ .variables_manager
458
+ .get_variable_index(edge.source.variable.as_ref().unwrap())?,
459
+ });
460
+ }
461
+ else
462
+ {
463
+ self.compile_create_node(&edge.source, &mut instructions, &mut variables)?;
464
+ instructions.push(Instruction::Duplicate);
465
+ }
466
+ // Generate destination
467
+ if edge.source.variable.is_some()
468
+ && edge.destination.variable.is_some()
469
+ && edge.source.variable == edge.destination.variable
470
+ {
471
+ instructions.push(Instruction::Duplicate);
472
+ }
473
+ else if self
474
+ .variables_manager
475
+ .is_set_variable(&edge.destination.variable)?
476
+ {
477
+ instructions.push(Instruction::GetVariable {
478
+ col_id: self
479
+ .variables_manager
480
+ .get_variable_index(edge.destination.variable.as_ref().unwrap())?,
481
+ });
482
+ }
483
+ else
484
+ {
485
+ self.compile_create_node(&edge.destination, &mut instructions, &mut variables)?;
486
+ instructions.push(Instruction::Duplicate);
487
+ instructions.push(Instruction::Rot3);
488
+ }
489
+ variables.push(
490
+ self
491
+ .variables_manager
492
+ .get_variable_index_option(&edge.variable)?,
493
+ );
494
+ self
495
+ .variables_manager
496
+ .mark_variables_as_set(&edge.variable)?;
497
+ self.compile_optional_expression(&edge.properties, &mut instructions)?;
498
+ if !edge.labels.is_string()
499
+ {
500
+ Err(CompileTimeError::NoSingleRelationshipType)?;
501
+ }
502
+ let mut labels = Default::default();
503
+ self.compile_labels_expression(&mut labels, &edge.labels)?;
504
+ instructions.push(Instruction::CreateEdgeLiteral { labels });
505
+ }
506
+ crate::parser::ast::Pattern::Path(_) =>
507
+ {
508
+ Err(InternalError::PathPatternInCreateExpression {
509
+ context: "compiler/compile_create_patterns",
510
+ })?;
511
+ }
512
+ }
513
+ Ok(CreateAction {
514
+ instructions,
515
+ variables,
516
+ })
517
+ });
518
+ Ok(Block::Create {
519
+ actions: actions.collect::<Result<_>>()?,
520
+ variables_size: self.variables_size(),
521
+ })
522
+ }
523
+
524
+ fn compile_match_node(
525
+ &mut self,
526
+ node: &crate::parser::ast::NodePattern,
527
+ instructions: &mut Instructions,
528
+ filter: &mut Instructions,
529
+ get_node_function_name: Option<&'static str>,
530
+ ) -> Result<()>
531
+ {
532
+ self.compile_optional_expression(&node.properties, instructions)?;
533
+ let mut labels = Default::default();
534
+ if node.labels.is_all_inclusive()
535
+ {
536
+ self.compile_labels_expression(&mut labels, &node.labels)?;
537
+ }
538
+ else
539
+ {
540
+ if let Some(get_node_function_name) = get_node_function_name
541
+ {
542
+ filter.push(Instruction::Duplicate);
543
+ filter.push(Instruction::FunctionCall {
544
+ function: self
545
+ .function_manager
546
+ .get_function::<CompileTimeError>(get_node_function_name)?,
547
+ arguments_count: 1,
548
+ });
549
+ }
550
+ let has_label_function = self
551
+ .function_manager
552
+ .get_function::<CompileTimeError>("has_label")?;
553
+ self.compile_filter_labels(filter, &node.labels, &has_label_function)?;
554
+ filter.push(Instruction::Rot3);
555
+ filter.push(Instruction::AndBinaryOperator);
556
+ filter.push(Instruction::Swap);
557
+ }
558
+ instructions.push(Instruction::CreateNodeQuery { labels });
559
+ Ok(())
560
+ }
561
+
562
+ fn compile_match_edge(
563
+ &mut self,
564
+ path_variable: Option<ast::VariableIdentifier>,
565
+ edge: &crate::parser::ast::EdgePattern,
566
+ single_match: bool,
567
+ previous_edges: &mut Vec<usize>,
568
+ ) -> Result<BlockMatch>
569
+ {
570
+ let mut instructions = Instructions::new();
571
+ let mut source_variable = None;
572
+ let mut filter = Instructions::new();
573
+ if self
574
+ .variables_manager
575
+ .is_set_variable(&edge.source.variable)?
576
+ {
577
+ instructions.push(Instruction::GetVariable {
578
+ col_id: self
579
+ .variables_manager
580
+ .get_variable_index(edge.source.variable.as_ref().unwrap())?,
581
+ });
582
+ instructions.push(Instruction::CreateNodeQuery { labels: vec![] });
583
+ }
584
+ else
585
+ {
586
+ source_variable = edge.source.variable.to_owned();
587
+ self.compile_match_node(
588
+ &edge.source,
589
+ &mut instructions,
590
+ &mut filter,
591
+ Some("get_source"),
592
+ )?;
593
+ }
594
+ let mut destination_variable = None;
595
+ if self
596
+ .variables_manager
597
+ .is_set_variable(&edge.destination.variable)?
598
+ {
599
+ instructions.push(Instruction::GetVariable {
600
+ col_id: self
601
+ .variables_manager
602
+ .get_variable_index(edge.destination.variable.as_ref().unwrap())?,
603
+ });
604
+ instructions.push(Instruction::CreateNodeQuery { labels: vec![] });
605
+ }
606
+ else
607
+ {
608
+ destination_variable = edge.destination.variable.to_owned();
609
+ self.compile_match_node(
610
+ &edge.destination,
611
+ &mut instructions,
612
+ &mut filter,
613
+ Some("get_destination"),
614
+ )?;
615
+ }
616
+ if self.variables_manager.is_set_variable(&edge.variable)?
617
+ {
618
+ instructions.push(Instruction::GetVariable {
619
+ col_id: self
620
+ .variables_manager
621
+ .get_variable_index(edge.variable.as_ref().unwrap())?,
622
+ });
623
+ instructions.push(Instruction::CreateEdgeQuery { labels: vec![] });
624
+ }
625
+ else
626
+ {
627
+ self.compile_optional_expression(&edge.properties, &mut instructions)?;
628
+ // Handle labels
629
+ let mut labels = Default::default();
630
+ if edge.labels.is_all_inclusive()
631
+ {
632
+ self.compile_labels_expression(&mut labels, &edge.labels)?;
633
+ }
634
+ else
635
+ {
636
+ let has_label_function = self
637
+ .function_manager
638
+ .get_function::<CompileTimeError>("has_label")?;
639
+ self.compile_filter_labels(&mut filter, &edge.labels, &has_label_function)?;
640
+ filter.push(Instruction::Rot3);
641
+ filter.push(Instruction::AndBinaryOperator);
642
+ filter.push(Instruction::Swap);
643
+ }
644
+ instructions.push(Instruction::CreateEdgeQuery { labels });
645
+ }
646
+
647
+ // Mark variables as set once they are compiled
648
+ self
649
+ .variables_manager
650
+ .mark_variables_as_set(&edge.source.variable)?;
651
+ self
652
+ .variables_manager
653
+ .mark_variables_as_set(&edge.destination.variable)?;
654
+ self
655
+ .variables_manager
656
+ .mark_variables_as_set(&edge.variable)?;
657
+
658
+ // Make sure that this edge isn't equal to an already matched edge
659
+ let edge_variable = if single_match
660
+ {
661
+ self
662
+ .variables_manager
663
+ .get_variable_index_option(&edge.variable)?
664
+ }
665
+ else
666
+ {
667
+ let edge_variable = self
668
+ .variables_manager
669
+ .get_variable_index_option(&edge.variable)?
670
+ .unwrap_or_else(|| self.create_temporary_variable());
671
+ for other in previous_edges.iter()
672
+ {
673
+ filter.push(Instruction::Duplicate);
674
+ filter.push(Instruction::GetVariable { col_id: *other });
675
+ filter.push(Instruction::NotEqualBinaryOperator);
676
+ filter.push(Instruction::InverseRot3);
677
+ filter.push(Instruction::AndBinaryOperator);
678
+ filter.push(Instruction::Swap);
679
+ }
680
+ previous_edges.push(edge_variable);
681
+ Some(edge_variable)
682
+ };
683
+ self
684
+ .variables_manager
685
+ .mark_variables_as_set(&path_variable)?;
686
+ // Create block
687
+ Ok(BlockMatch::MatchEdge {
688
+ instructions: instructions,
689
+ left_variable: self
690
+ .variables_manager
691
+ .get_variable_index_option(&source_variable)?,
692
+ edge_variable,
693
+ right_variable: self
694
+ .variables_manager
695
+ .get_variable_index_option(&destination_variable)?,
696
+ path_variable: self
697
+ .variables_manager
698
+ .get_variable_index_option(&path_variable)?,
699
+ filter,
700
+ directivity: edge.directivity,
701
+ })
702
+ }
703
+
704
+ fn compile_return_with(
705
+ &mut self,
706
+ all: bool,
707
+ expressions: &Vec<ast::NamedExpression>,
708
+ where_expression: &Option<ast::Expression>,
709
+ modifiers: &ast::Modifiers,
710
+ ) -> Result<(
711
+ Vec<(String, RWExpression)>,
712
+ Instructions,
713
+ Modifiers,
714
+ VariablesSizes,
715
+ )>
716
+ {
717
+ let mut variables = Vec::<(ast::VariableIdentifier, RWExpression)>::new();
718
+ let mut filter = Default::default();
719
+ if all
720
+ {
721
+ for (var_id, var) in self.variables_manager.variables_iter()
722
+ {
723
+ variables.push((
724
+ var_id.clone(),
725
+ instructions::RWExpression {
726
+ col_id: var.col_id(),
727
+ instructions: vec![Instruction::GetVariable {
728
+ col_id: var.col_id(),
729
+ }],
730
+ aggregations: Default::default(),
731
+ },
732
+ ));
733
+ }
734
+ }
735
+ for e in expressions.iter()
736
+ {
737
+ let mut instructions = Instructions::new();
738
+ let mut aggregations = Vec::<(usize, RWAggregation)>::new();
739
+ self.compile_expression(
740
+ &e.expression,
741
+ &mut instructions,
742
+ &mut Some(&mut aggregations),
743
+ )?;
744
+ if variables.iter().any(|(name, _)| *name == e.identifier)
745
+ {
746
+ return Err(
747
+ CompileTimeError::ColumnNameConflict {
748
+ name: e.identifier.name().to_owned(),
749
+ }
750
+ .into(),
751
+ );
752
+ }
753
+ let col_id = self.variables_manager.analyse_named_expression(&e)?;
754
+ variables.push((
755
+ e.identifier.clone(),
756
+ RWExpression {
757
+ col_id,
758
+ instructions,
759
+ aggregations,
760
+ },
761
+ ));
762
+ }
763
+
764
+ // Compile where expression
765
+ if let Some(where_expression) = where_expression
766
+ {
767
+ let ei = expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
768
+ .analyse(where_expression)?;
769
+ if ei.aggregation_result
770
+ {
771
+ return Err(CompileTimeError::InvalidAggregation.into());
772
+ }
773
+ self.compile_expression(where_expression, &mut filter, &mut None)?;
774
+ }
775
+
776
+ let modifiers = self.compile_modifiers(&modifiers)?;
777
+ let variables_size = self.variables_size();
778
+ self
779
+ .variables_manager
780
+ .keep_variables(variables.iter().map(|(n, _)| n))?;
781
+
782
+ let variables = variables
783
+ .into_iter()
784
+ .map(|(var_id, e)| (var_id.take_name(), e))
785
+ .collect();
786
+ Ok((variables, filter, modifiers, variables_size))
787
+ }
788
+
789
+ fn compile_match_patterns(
790
+ &mut self,
791
+ patterns: &Vec<crate::parser::ast::Pattern>,
792
+ where_expression: &Option<crate::parser::ast::Expression>,
793
+ optional: bool,
794
+ ) -> Result<Block>
795
+ {
796
+ let is_single_match = patterns.len() == 1;
797
+ let mut edge_variables = vec![];
798
+ let blocks = patterns.iter().map(|c| match c
799
+ {
800
+ crate::parser::ast::Pattern::Node(node) =>
801
+ {
802
+ let mut instructions = Instructions::new();
803
+ let mut filter = Instructions::new();
804
+ self.compile_match_node(node, &mut instructions, &mut filter, None)?;
805
+ self
806
+ .variables_manager
807
+ .mark_variables_as_set(&node.variable)?;
808
+ Ok(BlockMatch::MatchNode {
809
+ instructions: instructions,
810
+ variable: self
811
+ .variables_manager
812
+ .get_variable_index_option(&node.variable)?,
813
+ filter,
814
+ })
815
+ }
816
+ crate::parser::ast::Pattern::Edge(edge) =>
817
+ {
818
+ self.compile_match_edge(None, &edge, is_single_match, &mut edge_variables)
819
+ }
820
+ crate::parser::ast::Pattern::Path(path) => self.compile_match_edge(
821
+ Some(path.variable.to_owned()),
822
+ &path.edge,
823
+ is_single_match,
824
+ &mut edge_variables,
825
+ ),
826
+ });
827
+ let blocks = blocks.collect::<Result<_>>()?;
828
+ let mut filter = Instructions::new();
829
+ if let Some(where_expression) = where_expression
830
+ {
831
+ let ei = expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
832
+ .analyse(where_expression)?;
833
+ if ei.aggregation_result
834
+ {
835
+ return Err(CompileTimeError::InvalidAggregation.into());
836
+ }
837
+ self.compile_expression(where_expression, &mut filter, &mut None)?;
838
+ }
839
+ Ok(Block::BlockMatch {
840
+ blocks,
841
+ filter,
842
+ optional,
843
+ variables_size: self.variables_size(),
844
+ })
845
+ }
846
+
847
+ fn check_for_constant_integer_expression(&mut self, x: &ast::Expression) -> Result<()>
848
+ {
849
+ let ei = expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
850
+ .analyse(&x)?;
851
+ if !ei.constant
852
+ {
853
+ Err(error::CompileTimeError::NonConstantExpression.into())
854
+ }
855
+ else
856
+ {
857
+ match ei.expression_type
858
+ {
859
+ expression_analyser::ExpressionType::Integer
860
+ | expression_analyser::ExpressionType::Variant => Ok(()),
861
+ _ => Err(error::CompileTimeError::InvalidArgumentType.into()),
862
+ }
863
+ }
864
+ }
865
+
866
+ pub(crate) fn compile_modifiers(
867
+ &mut self,
868
+ modifiers: &ast::Modifiers,
869
+ ) -> Result<instructions::Modifiers>
870
+ {
871
+ let limit = modifiers
872
+ .limit
873
+ .as_ref()
874
+ .map(|x| {
875
+ self.check_for_constant_integer_expression(x)?;
876
+ let mut instructions = Instructions::new();
877
+ self.compile_expression(&x, &mut instructions, &mut None)?;
878
+ Ok::<_, ErrorType>(instructions)
879
+ })
880
+ .transpose()?;
881
+ let skip = modifiers
882
+ .skip
883
+ .as_ref()
884
+ .map(|x| {
885
+ self.check_for_constant_integer_expression(x)?;
886
+ let mut instructions = Instructions::new();
887
+ self.compile_expression(&x, &mut instructions, &mut None)?;
888
+ Ok::<_, ErrorType>(instructions)
889
+ })
890
+ .transpose()?;
891
+ let order_by = modifiers.order_by.as_ref().map_or_else(
892
+ || Ok(Default::default()),
893
+ |x| {
894
+ x.expressions
895
+ .iter()
896
+ .map(|x| {
897
+ let mut instructions = Instructions::new();
898
+
899
+ self.compile_expression(&x.expression, &mut instructions, &mut None)?;
900
+
901
+ Ok(instructions::OrderBy {
902
+ asc: x.asc,
903
+ instructions,
904
+ })
905
+ })
906
+ .collect::<Result<_>>()
907
+ },
908
+ )?;
909
+ Ok(instructions::Modifiers {
910
+ limit,
911
+ skip,
912
+ order_by,
913
+ })
914
+ }
915
+ }
916
+
917
+ pub(crate) fn compile(
918
+ function_manager: &functions::Manager,
919
+ statements: crate::parser::ast::Statements,
920
+ ) -> Result<interpreter::Program>
921
+ {
922
+ let mut compiler = Compiler {
923
+ variables_manager: VariablesManager::new(function_manager),
924
+ function_manager: function_manager.clone(),
925
+ temporary_variables: 0,
926
+ };
927
+ let mut statements_err = Ok(());
928
+ let program = statements
929
+ .iter()
930
+ .map(|stmt| {
931
+ compiler.temporary_variables = 0;
932
+ compiler.variables_manager.analyse(stmt)?;
933
+ let inst = match stmt
934
+ {
935
+ ast::Statement::CreateGraph(create_graph) => Ok(Block::CreateGraph {
936
+ name: create_graph.name.to_owned(),
937
+ }),
938
+ ast::Statement::UseGraph(use_graph) => Ok(Block::UseGraph {
939
+ name: use_graph.name.to_owned(),
940
+ }),
941
+ ast::Statement::Create(create) => compiler.compile_create_patterns(&create.patterns),
942
+ ast::Statement::Match(match_statement) => compiler.compile_match_patterns(
943
+ &match_statement.patterns,
944
+ &match_statement.where_expression,
945
+ match_statement.optional,
946
+ ),
947
+ ast::Statement::Return(return_statement) =>
948
+ {
949
+ let (variables, filter, modifiers, variables_size) = compiler.compile_return_with(
950
+ return_statement.all,
951
+ &return_statement.expressions,
952
+ &return_statement.where_expression,
953
+ &return_statement.modifiers,
954
+ )?;
955
+ Ok(Block::Return {
956
+ variables,
957
+ filter,
958
+ modifiers,
959
+ variables_size,
960
+ })
961
+ }
962
+ ast::Statement::Call(call) =>
963
+ {
964
+ let mut instructions = Instructions::new();
965
+ for e in call.arguments.iter().rev()
966
+ {
967
+ compiler.compile_expression(e, &mut instructions, &mut None)?;
968
+ }
969
+ Ok(Block::Call {
970
+ arguments: instructions,
971
+ name: call.name.to_owned(),
972
+ })
973
+ }
974
+ ast::Statement::With(with) =>
975
+ {
976
+ let (variables, filter, modifiers, variables_size) = compiler.compile_return_with(
977
+ with.all,
978
+ &with.expressions,
979
+ &with.where_expression,
980
+ &with.modifiers,
981
+ )?;
982
+ Ok(Block::With {
983
+ variables: variables.into_iter().map(|(_, v)| v).collect(),
984
+ filter,
985
+ modifiers,
986
+ variables_size,
987
+ })
988
+ }
989
+ ast::Statement::Unwind(unwind) =>
990
+ {
991
+ let mut instructions = Instructions::new();
992
+ compiler.compile_expression(&unwind.expression, &mut instructions, &mut None)?;
993
+ Ok(Block::Unwind {
994
+ col_id: compiler
995
+ .variables_manager
996
+ .get_variable_index(&unwind.identifier)?,
997
+ instructions,
998
+ variables_size: compiler.variables_size(),
999
+ })
1000
+ }
1001
+ ast::Statement::Delete(delete_statement) => Ok(Block::Delete {
1002
+ detach: delete_statement.detach,
1003
+ instructions: delete_statement
1004
+ .expressions
1005
+ .iter()
1006
+ .map(|expr| {
1007
+ let mut instructions = Instructions::new();
1008
+ let ei =
1009
+ expression_analyser::Analyser::new(&compiler.variables_manager, function_manager)
1010
+ .analyse(expr)?;
1011
+ match ei.expression_type
1012
+ {
1013
+ expression_analyser::ExpressionType::Node
1014
+ | expression_analyser::ExpressionType::Edge
1015
+ | expression_analyser::ExpressionType::Variant =>
1016
+ {
1017
+ compiler.compile_expression(&expr, &mut instructions, &mut None)?
1018
+ }
1019
+ _ => Err(CompileTimeError::InvalidDelete)?,
1020
+ }
1021
+ Ok(instructions)
1022
+ })
1023
+ .collect::<Result<_>>()?,
1024
+ }),
1025
+ ast::Statement::Update(update_statement) => Ok(Block::Update {
1026
+ updates: update_statement
1027
+ .updates
1028
+ .iter()
1029
+ .map(|x| match x
1030
+ {
1031
+ ast::OneUpdate::SetProperty(update_property)
1032
+ | ast::OneUpdate::AddProperty(update_property) =>
1033
+ {
1034
+ let mut instructions = Instructions::new();
1035
+ compiler.compile_expression(
1036
+ &update_property.expression,
1037
+ &mut instructions,
1038
+ &mut None,
1039
+ )?;
1040
+
1041
+ match x
1042
+ {
1043
+ ast::OneUpdate::SetProperty(_) => Ok(instructions::UpdateOne::SetProperty {
1044
+ target: compiler
1045
+ .variables_manager
1046
+ .get_variable_index(&update_property.target)?,
1047
+ path: update_property.path.to_owned(),
1048
+ instructions,
1049
+ }),
1050
+ ast::OneUpdate::AddProperty(_) => Ok(instructions::UpdateOne::AddProperty {
1051
+ target: compiler
1052
+ .variables_manager
1053
+ .get_variable_index(&update_property.target)?,
1054
+ path: update_property.path.to_owned(),
1055
+ instructions,
1056
+ }),
1057
+ _ => Err(
1058
+ InternalError::Unreachable {
1059
+ context: "compile/Update/SetAddProperty",
1060
+ }
1061
+ .into(),
1062
+ ),
1063
+ }
1064
+ }
1065
+ ast::OneUpdate::RemoveProperty(remove_property) =>
1066
+ {
1067
+ Ok(instructions::UpdateOne::RemoveProperty {
1068
+ target: compiler
1069
+ .variables_manager
1070
+ .get_variable_index(&remove_property.target)?,
1071
+ path: remove_property.path.to_owned(),
1072
+ })
1073
+ }
1074
+ ast::OneUpdate::AddLabels(add_labels) => Ok(instructions::UpdateOne::AddLabels {
1075
+ target: compiler
1076
+ .variables_manager
1077
+ .get_variable_index(&add_labels.target)?,
1078
+ labels: add_labels.labels.to_owned(),
1079
+ }),
1080
+ ast::OneUpdate::RemoveLabels(rm_labels) =>
1081
+ {
1082
+ Ok(instructions::UpdateOne::RemoveLabels {
1083
+ target: compiler
1084
+ .variables_manager
1085
+ .get_variable_index(&rm_labels.target)?,
1086
+ labels: rm_labels.labels.to_owned(),
1087
+ })
1088
+ }
1089
+ })
1090
+ .collect::<Result<_>>()?,
1091
+ variables_size: compiler.variables_size(),
1092
+ }),
1093
+ };
1094
+ inst
1095
+ })
1096
+ .scan(&mut statements_err, |err, gp| {
1097
+ gp.map_err(|e| **err = Err(e)).ok()
1098
+ });
1099
+ let program = program.collect::<interpreter::Program>();
1100
+ statements_err?;
1101
+ if crate::consts::SHOW_PROGRAM
1102
+ {
1103
+ println!("program = {:#?}", program);
1104
+ }
1105
+ Ok(program)
1106
+ }