gqlite 1.2.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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/ext/gqliterb/.cargo/config.toml +2 -0
  3. data/ext/gqliterb/Cargo.lock +133 -123
  4. data/ext/gqliterb/Cargo.toml +3 -6
  5. data/ext/gqliterb/src/lib.rs +2 -2
  6. data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2060 -0
  7. data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +132 -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 +236 -0
  20. data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +427 -0
  21. data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +620 -0
  22. data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1106 -0
  23. data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +208 -0
  24. data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
  25. data/ext/gqliterb/vendor/gqlitedb/src/error.rs +621 -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 +48 -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 +412 -0
  35. data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +268 -0
  36. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1788 -0
  37. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +262 -0
  38. data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
  39. data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +42 -0
  40. data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +625 -0
  41. data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +191 -0
  42. data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1153 -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 +1250 -0
  48. data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +994 -0
  49. data/ext/gqliterb/vendor/gqlitedb/src/store.rs +432 -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 +39 -0
  54. data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +39 -0
  55. data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +462 -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 +559 -0
  65. data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +616 -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,620 @@
1
+ use std::collections::HashMap;
2
+
3
+ use crate::prelude::*;
4
+
5
+ use compiler::expression_analyser::{self, ExpressionType};
6
+ use parser::ast;
7
+
8
+ fn unknown_variable_error(name: &ast::VariableIdentifier) -> ErrorType
9
+ {
10
+ InternalError::UnknownVariable {
11
+ name: name.name().clone(),
12
+ }
13
+ .into()
14
+ }
15
+
16
+ // __ __ _ _ _
17
+ // \ \ / /_ _ _ __(_) __ _| |__ | | ___
18
+ // \ \ / / _` | '__| |/ _` | '_ \| |/ _ \
19
+ // \ V / (_| | | | | (_| | |_) | | __/
20
+ // \_/ \__,_|_| |_|\__,_|_.__/|_|\___|
21
+
22
+ #[derive(Debug, Clone)]
23
+ pub(crate) enum VariableContent
24
+ {
25
+ Node(ast::NodePattern),
26
+ Edge(ast::EdgePattern),
27
+ None,
28
+ }
29
+
30
+ #[derive(Debug, Clone)]
31
+ pub(crate) struct Variable
32
+ {
33
+ content: VariableContent,
34
+ variable_type: ExpressionType,
35
+ col_id: value_table::ColId,
36
+ /// Track if the variable is expected to have been set or has just been declared.
37
+ is_set: bool,
38
+ }
39
+
40
+ impl Variable
41
+ {
42
+ fn from_node(value: ast::NodePattern, col_id: value_table::ColId) -> Self
43
+ {
44
+ Self {
45
+ content: VariableContent::Node(value),
46
+ variable_type: ExpressionType::Node,
47
+ col_id,
48
+ is_set: false,
49
+ }
50
+ }
51
+ fn from_edge(value: ast::EdgePattern, col_id: value_table::ColId) -> Self
52
+ {
53
+ Self {
54
+ content: VariableContent::Edge(value),
55
+ variable_type: ExpressionType::Edge,
56
+ col_id,
57
+ is_set: false,
58
+ }
59
+ }
60
+ fn from_expression(value: ExpressionType, col_id: value_table::ColId) -> Self
61
+ {
62
+ match value
63
+ {
64
+ ExpressionType::Edge => Self {
65
+ content: VariableContent::Edge(ast::EdgePattern {
66
+ variable: None,
67
+ labels: ast::LabelExpression::None,
68
+ properties: None,
69
+ source: ast::NodePattern {
70
+ variable: None,
71
+ labels: ast::LabelExpression::None,
72
+ properties: None,
73
+ },
74
+ destination: ast::NodePattern {
75
+ variable: None,
76
+ labels: ast::LabelExpression::None,
77
+ properties: None,
78
+ },
79
+ directivity: crate::graph::EdgeDirectivity::Directed,
80
+ }),
81
+ variable_type: ExpressionType::Edge,
82
+ col_id,
83
+ is_set: false,
84
+ },
85
+ ExpressionType::Node => Self {
86
+ content: VariableContent::Node(ast::NodePattern {
87
+ variable: None,
88
+ labels: ast::LabelExpression::None,
89
+ properties: None,
90
+ }),
91
+ variable_type: ExpressionType::Node,
92
+ col_id,
93
+ is_set: false,
94
+ },
95
+ variable_type => Self {
96
+ content: VariableContent::None,
97
+ variable_type,
98
+ col_id,
99
+ is_set: false,
100
+ },
101
+ }
102
+ }
103
+ pub(crate) fn col_id(&self) -> value_table::ColId
104
+ {
105
+ self.col_id
106
+ }
107
+ pub(crate) fn mark_set(mut self) -> Self
108
+ {
109
+ self.is_set = true;
110
+ self
111
+ }
112
+ }
113
+
114
+ // __ __ _ _ _ _
115
+ // \ \ / /_ _| (_) __| | __ _| |_ ___ _ __
116
+ // \ \ / / _` | | |/ _` |/ _` | __/ _ \| '__|
117
+ // \ V / (_| | | | (_| | (_| | || (_) | |
118
+ // \_/ \__,_|_|_|\__,_|\__,_|\__\___/|_|
119
+
120
+ #[derive(Debug)]
121
+ pub(crate) struct VariablesManager
122
+ {
123
+ variables: HashMap<ast::VariableIdentifier, Variable>,
124
+ function_manager: functions::Manager,
125
+ }
126
+
127
+ impl VariablesManager
128
+ {
129
+ pub(crate) fn new(function_manager: &functions::Manager) -> Self
130
+ {
131
+ Self {
132
+ variables: Default::default(),
133
+ function_manager: function_manager.clone(),
134
+ }
135
+ }
136
+ pub(crate) fn has_variable(&self, identifier: &Option<ast::VariableIdentifier>) -> bool
137
+ {
138
+ identifier
139
+ .as_ref()
140
+ .map_or(false, |identifier| self.variables.contains_key(&identifier))
141
+ }
142
+ /// Get the index of the variable in the row of variables
143
+ pub(crate) fn get_variable_index(&self, identifier: &ast::VariableIdentifier) -> Result<usize>
144
+ {
145
+ self
146
+ .variables
147
+ .get(&identifier)
148
+ .ok_or_else(|| unknown_variable_error(identifier))
149
+ .map(|x| x.col_id)
150
+ }
151
+ /// Get the index of the variable in the row of variables
152
+ pub(crate) fn get_variable_index_option(
153
+ &self,
154
+ identifier: &Option<ast::VariableIdentifier>,
155
+ ) -> Result<Option<usize>>
156
+ {
157
+ match identifier
158
+ {
159
+ Some(identifier) => Ok(Some(self.get_variable_index(identifier)?)),
160
+ None => Ok(None),
161
+ }
162
+ }
163
+ pub(crate) fn variables_count(&self) -> usize
164
+ {
165
+ self.variables.len()
166
+ }
167
+ pub(crate) fn variables_iter(
168
+ &self,
169
+ ) -> std::collections::hash_map::Iter<'_, ast::VariableIdentifier, Variable>
170
+ {
171
+ self.variables.iter()
172
+ }
173
+ pub(crate) fn is_set_variable(&self, var_id: &Option<ast::VariableIdentifier>) -> Result<bool>
174
+ {
175
+ var_id.as_ref().map_or(Ok(false), |name| {
176
+ self
177
+ .variables
178
+ .get(&name)
179
+ .ok_or_else(|| unknown_variable_error(name))
180
+ .map(|x| x.is_set)
181
+ })
182
+ }
183
+ /// Mark a variable as set.
184
+ pub(crate) fn mark_variables_as_set<'a>(
185
+ &mut self,
186
+ var_id: impl Into<Option<&'a ast::VariableIdentifier>>,
187
+ ) -> Result<()>
188
+ {
189
+ if let Some(var_id) = var_id.into()
190
+ {
191
+ self
192
+ .variables
193
+ .get_mut(&var_id)
194
+ .ok_or_else(|| unknown_variable_error(var_id))
195
+ .map(|x| x.is_set = true)
196
+ }
197
+ else
198
+ {
199
+ Ok(())
200
+ }
201
+ }
202
+ fn declare_variable(
203
+ &mut self,
204
+ var_id: &ast::VariableIdentifier,
205
+ expression_type: ExpressionType,
206
+ ) -> Result<()>
207
+ {
208
+ if self.variables.contains_key(&var_id)
209
+ {
210
+ Err(
211
+ CompileTimeError::VariableAlreadyBound {
212
+ name: var_id.name().clone(),
213
+ }
214
+ .into(),
215
+ )
216
+ }
217
+ else
218
+ {
219
+ self.variables.insert(
220
+ var_id.clone(),
221
+ Variable::from_expression(expression_type, self.variables.len()),
222
+ );
223
+ Ok(())
224
+ }
225
+ }
226
+ // Validate a node variable, and if unknown, declare it
227
+ fn validate_node(&mut self, node: &ast::NodePattern) -> Result<()>
228
+ {
229
+ if let Some(var_id) = &node.variable
230
+ {
231
+ if let Some(var) = self.variables.get(&var_id)
232
+ {
233
+ match var.variable_type
234
+ {
235
+ ExpressionType::Node => match &var.content
236
+ {
237
+ VariableContent::Node(var_node) =>
238
+ {
239
+ if (!node.labels.is_none() || !node.properties.is_none())
240
+ && (node.labels != var_node.labels || node.properties != var_node.properties)
241
+ {
242
+ Err(
243
+ CompileTimeError::VariableAlreadyBound {
244
+ name: var_id.name().clone(),
245
+ }
246
+ .into(),
247
+ )
248
+ }
249
+ else
250
+ {
251
+ Ok(())
252
+ }
253
+ }
254
+ _ => Err(
255
+ InternalError::ExpectedNode {
256
+ context: "validate_node",
257
+ }
258
+ .into(),
259
+ ),
260
+ },
261
+ ExpressionType::Variant => Ok(()), // Cannot be checked at compile time
262
+ _ => Err(
263
+ CompileTimeError::VariableTypeConflict {
264
+ name: var_id.name().to_owned(),
265
+ }
266
+ .into(),
267
+ ),
268
+ }
269
+ }
270
+ else
271
+ {
272
+ if let Some(props) = &node.properties
273
+ {
274
+ expression_analyser::Analyser::new(&self, &self.function_manager).analyse(&props)?;
275
+ }
276
+ self.variables.insert(
277
+ var_id.clone(),
278
+ Variable::from_node((*node).to_owned(), self.variables.len()),
279
+ );
280
+ Ok(())
281
+ }
282
+ }
283
+ else
284
+ {
285
+ Ok(())
286
+ }
287
+ }
288
+ fn validate_edge(&mut self, edge: &ast::EdgePattern) -> Result<()>
289
+ {
290
+ self.validate_node(&edge.source)?;
291
+ self.validate_node(&edge.destination)?;
292
+ if let Some(var_id) = &edge.variable
293
+ {
294
+ if let Some(var) = self.variables.get(&var_id)
295
+ {
296
+ match var.content
297
+ {
298
+ VariableContent::Edge { .. } => Err(
299
+ CompileTimeError::VariableAlreadyBound {
300
+ name: var_id.name().clone(),
301
+ }
302
+ .into(),
303
+ ),
304
+ _ => Err(
305
+ CompileTimeError::VariableTypeConflict {
306
+ name: var_id.name().clone(),
307
+ }
308
+ .into(),
309
+ ),
310
+ }
311
+ }
312
+ else
313
+ {
314
+ if let Some(props) = &edge.properties
315
+ {
316
+ expression_analyser::Analyser::new(&self, &self.function_manager).analyse(&props)?;
317
+ }
318
+ self.variables.insert(
319
+ var_id.clone(),
320
+ Variable::from_edge((*edge).to_owned(), self.variables.len()),
321
+ );
322
+ Ok(())
323
+ }
324
+ }
325
+ else
326
+ {
327
+ Ok(())
328
+ }
329
+ }
330
+ /// Check if the node variable exists, and that it is a node and that the definition
331
+ /// is compatible.
332
+ fn is_valid_existing_node(&self, node: &ast::NodePattern) -> Result<bool>
333
+ {
334
+ if let Some(var_id) = &node.variable
335
+ {
336
+ if let Some(var) = self.variables.get(&var_id)
337
+ {
338
+ match var.variable_type
339
+ {
340
+ ExpressionType::Node => match &var.content
341
+ {
342
+ VariableContent::Node(var_node) =>
343
+ {
344
+ if (!node.labels.is_none() || !node.properties.is_none())
345
+ && (node.labels != var_node.labels || node.properties != var_node.properties)
346
+ {
347
+ Err(
348
+ CompileTimeError::VariableAlreadyBound {
349
+ name: var_id.name().clone(),
350
+ }
351
+ .into(),
352
+ )
353
+ }
354
+ else
355
+ {
356
+ Ok(true)
357
+ }
358
+ }
359
+ _ => Err(
360
+ InternalError::ExpectedNode {
361
+ context: "is_valid_existing_node",
362
+ }
363
+ .into(),
364
+ ),
365
+ },
366
+ ExpressionType::Variant => Ok(true), // Cannot be checked at compile time
367
+ _ => Err(
368
+ CompileTimeError::VariableTypeConflict {
369
+ name: var_id.name().clone(),
370
+ }
371
+ .into(),
372
+ ),
373
+ }
374
+ }
375
+ else
376
+ {
377
+ Ok(false)
378
+ }
379
+ }
380
+ else
381
+ {
382
+ Ok(false)
383
+ }
384
+ }
385
+ /// Check if the edge variable exists, and that it is a edge and that the definition
386
+ /// is compatible.
387
+ fn is_valid_existing_edge(&self, edge: &ast::EdgePattern) -> Result<bool>
388
+ {
389
+ if let Some(var_id) = &edge.variable
390
+ {
391
+ if let Some(var) = self.variables.get(&var_id)
392
+ {
393
+ match var.variable_type
394
+ {
395
+ ExpressionType::Edge => match &var.content
396
+ {
397
+ VariableContent::Edge(var_edge) =>
398
+ {
399
+ if (!edge.labels.is_none() || !edge.properties.is_none())
400
+ && (var_edge.labels != edge.labels || var_edge.properties != edge.properties)
401
+ {
402
+ Err(
403
+ CompileTimeError::VariableAlreadyBound {
404
+ name: var_id.name().clone(),
405
+ }
406
+ .into(),
407
+ )
408
+ }
409
+ else
410
+ {
411
+ Ok(true)
412
+ }
413
+ }
414
+ _ => Err(
415
+ InternalError::ExpectedEdge {
416
+ context: "is_valid_existing_edge",
417
+ }
418
+ .into(),
419
+ ),
420
+ },
421
+ ExpressionType::Variant => Ok(true), // Cannot be checked at compile time
422
+ _ => Err(
423
+ CompileTimeError::VariableTypeConflict {
424
+ name: var_id.name().clone(),
425
+ }
426
+ .into(),
427
+ ),
428
+ }
429
+ }
430
+ else
431
+ {
432
+ Ok(false)
433
+ }
434
+ }
435
+ else
436
+ {
437
+ Ok(false)
438
+ }
439
+ }
440
+
441
+ /// Expression type for the given expression type
442
+ pub(crate) fn expression_type(
443
+ &self,
444
+ identifier: &ast::VariableIdentifier,
445
+ ) -> Result<ExpressionType>
446
+ {
447
+ Ok(
448
+ self
449
+ .variables
450
+ .get(identifier)
451
+ .ok_or_else(|| CompileTimeError::UndefinedVariable {
452
+ name: identifier.name().to_owned(),
453
+ })?
454
+ .variable_type,
455
+ )
456
+ }
457
+
458
+ fn analyse_edge_path(
459
+ &mut self,
460
+ path_variable: Option<ast::VariableIdentifier>,
461
+ edge: &crate::parser::ast::EdgePattern,
462
+ is_create: bool,
463
+ ) -> Result<()>
464
+ {
465
+ if let Some(path_variable) = &path_variable
466
+ {
467
+ self.declare_variable(path_variable, expression_analyser::ExpressionType::Path)?;
468
+ }
469
+ if !self.is_valid_existing_node(&edge.source)?
470
+ {
471
+ self.validate_node(&edge.source)?;
472
+ }
473
+ if !self.is_valid_existing_node(&edge.destination)?
474
+ {
475
+ self.validate_node(&edge.destination)?;
476
+ }
477
+ if is_create || !self.is_valid_existing_edge(&edge)?
478
+ {
479
+ self.validate_edge(edge)?;
480
+ }
481
+ Ok(())
482
+ }
483
+
484
+ fn analyse_pattern(&mut self, pattern: &ast::Pattern, is_create: bool) -> Result<()>
485
+ {
486
+ match pattern
487
+ {
488
+ ast::Pattern::Node(node) =>
489
+ {
490
+ self.validate_node(node)?;
491
+ }
492
+ ast::Pattern::Edge(edge) =>
493
+ {
494
+ self.analyse_edge_path(None, edge, is_create)?;
495
+ }
496
+ ast::Pattern::Path(path) =>
497
+ {
498
+ self.analyse_edge_path(None, &path.edge, is_create)?;
499
+ self.declare_variable(&path.variable, ExpressionType::Path)?;
500
+ }
501
+ }
502
+ Ok(())
503
+ }
504
+ /// Analyse a named expression and return a col id
505
+ pub(crate) fn analyse_named_expression(
506
+ &mut self,
507
+ named_expression: &ast::NamedExpression,
508
+ ) -> Result<usize>
509
+ {
510
+ let expression_info = expression_analyser::Analyser::new(&self, &self.function_manager)
511
+ .analyse(&named_expression.expression)?;
512
+ let col_id = self
513
+ .variables
514
+ .get(&named_expression.identifier)
515
+ .map_or(self.variables.len(), |var| var.col_id);
516
+ self.variables.insert(
517
+ named_expression.identifier.clone(),
518
+ Variable::from_expression(expression_info.expression_type, col_id).mark_set(),
519
+ );
520
+ Ok(col_id)
521
+ }
522
+ pub(crate) fn keep_variables<'a>(
523
+ &mut self,
524
+ names: impl IntoIterator<Item = &'a ast::VariableIdentifier>,
525
+ ) -> Result<()>
526
+ {
527
+ let mut new_variables = HashMap::<ast::VariableIdentifier, Variable>::default();
528
+ for (col_id, var_id) in names.into_iter().enumerate()
529
+ {
530
+ let mut var = self
531
+ .variables
532
+ .remove(&var_id)
533
+ .ok_or_else(|| unknown_variable_error(var_id))?;
534
+ var.col_id = col_id;
535
+ new_variables.insert(var_id.clone(), var.mark_set());
536
+ }
537
+ self.variables = new_variables;
538
+ Ok(())
539
+ }
540
+ pub(crate) fn analyse(&mut self, statement: &ast::Statement) -> Result<()>
541
+ {
542
+ if self.variables.iter().any(|(_, var)| var.is_set != true)
543
+ {
544
+ return Err(
545
+ InternalError::NotAllVariablesAreSet {
546
+ set_variables: self
547
+ .variables
548
+ .iter()
549
+ .filter(|(_, var)| var.is_set)
550
+ .map(|(key, _)| key.name().clone())
551
+ .collect(),
552
+ all_variables: self
553
+ .variables
554
+ .keys()
555
+ .map(|key| key.name().clone())
556
+ .collect(),
557
+ }
558
+ .into(),
559
+ );
560
+ }
561
+ #[allow(unused_variables)]
562
+ match statement
563
+ {
564
+ ast::Statement::CreateGraph(create_graph) =>
565
+ {}
566
+ ast::Statement::UseGraph(use_graph) =>
567
+ {}
568
+ ast::Statement::Create(create) =>
569
+ {
570
+ for pattern in create.patterns.iter()
571
+ {
572
+ match &pattern
573
+ {
574
+ ast::Pattern::Node(n) =>
575
+ {
576
+ if self.has_variable(&n.variable)
577
+ {
578
+ return Err(
579
+ CompileTimeError::VariableAlreadyBound {
580
+ name: n.variable.clone().unwrap().name().clone(),
581
+ }
582
+ .into(),
583
+ );
584
+ }
585
+ }
586
+ _ =>
587
+ {}
588
+ }
589
+ self.analyse_pattern(pattern, true)?;
590
+ }
591
+ }
592
+ ast::Statement::Match(match_statement) =>
593
+ {
594
+ for pattern in match_statement.patterns.iter()
595
+ {
596
+ self.analyse_pattern(pattern, false)?;
597
+ }
598
+ }
599
+ ast::Statement::Return(return_statement) =>
600
+ {}
601
+ ast::Statement::Call(call) =>
602
+ {}
603
+ ast::Statement::With(with) =>
604
+ {}
605
+ ast::Statement::Unwind(unwind) =>
606
+ {
607
+ self.declare_variable(
608
+ &unwind.identifier.to_owned(),
609
+ expression_analyser::ExpressionType::Variant,
610
+ )?;
611
+ self.mark_variables_as_set(&unwind.identifier)?;
612
+ }
613
+ ast::Statement::Delete(delete) =>
614
+ {}
615
+ ast::Statement::Update(update) =>
616
+ {}
617
+ }
618
+ Ok(())
619
+ }
620
+ }