gqlite 1.2.0 → 1.2.3

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