gqlite 1.5.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/Cargo.toml +10 -4
- data/ext/db-index/Cargo.toml +29 -0
- data/ext/db-index/src/hnsw/error.rs +66 -0
- data/ext/db-index/src/hnsw/graph_store.rs +272 -0
- data/ext/db-index/src/hnsw/id.rs +36 -0
- data/ext/db-index/src/hnsw/implementation.rs +1517 -0
- data/ext/db-index/src/hnsw/kernels.rs +1228 -0
- data/ext/db-index/src/hnsw/metric.rs +244 -0
- data/ext/db-index/src/hnsw/scalar.rs +72 -0
- data/ext/db-index/src/hnsw/simple_store.rs +140 -0
- data/ext/db-index/src/hnsw/store.rs +472 -0
- data/ext/db-index/src/hnsw/vector.rs +105 -0
- data/ext/db-index/src/hnsw/vectors.rs +568 -0
- data/ext/db-index/src/hnsw.rs +42 -0
- data/ext/db-index/src/lib.rs +3 -0
- data/ext/gqlitedb/Cargo.toml +19 -9
- data/ext/gqlitedb/benches/common/pokec.rs +62 -2
- data/ext/gqlitedb/benches/pokec_divan.rs +66 -2
- data/ext/gqlitedb/benches/pokec_iai.rs +60 -3
- data/ext/gqlitedb/release.toml +2 -2
- data/ext/gqlitedb/src/aggregators/arithmetic.rs +3 -1
- data/ext/gqlitedb/src/aggregators/containers.rs +1 -1
- data/ext/gqlitedb/src/aggregators/stats.rs +21 -12
- data/ext/gqlitedb/src/capi.rs +1 -1
- data/ext/gqlitedb/src/compiler/expression_analyser.rs +28 -20
- data/ext/gqlitedb/src/compiler/variables_manager.rs +97 -29
- data/ext/gqlitedb/src/compiler.rs +505 -225
- data/ext/gqlitedb/src/connection.rs +149 -11
- data/ext/gqlitedb/src/consts.rs +1 -2
- data/ext/gqlitedb/src/error.rs +123 -61
- data/ext/gqlitedb/src/functions/common.rs +39 -2
- data/ext/gqlitedb/src/functions/math.rs +8 -3
- data/ext/gqlitedb/src/functions/path.rs +48 -11
- data/ext/gqlitedb/src/functions/value.rs +1 -1
- data/ext/gqlitedb/src/functions.rs +23 -7
- data/ext/gqlitedb/src/graph.rs +1 -9
- data/ext/gqlitedb/src/interpreter/evaluators.rs +968 -130
- data/ext/gqlitedb/src/interpreter/instructions.rs +39 -2
- data/ext/gqlitedb/src/lib.rs +5 -4
- data/ext/gqlitedb/src/planner.rs +329 -0
- data/ext/gqlitedb/src/prelude.rs +3 -3
- data/ext/gqlitedb/src/store/pgrx.rs +1 -1
- data/ext/gqlitedb/src/store/postgres.rs +735 -7
- data/ext/gqlitedb/src/store/redb/hnsw_store.rs +702 -0
- data/ext/gqlitedb/src/store/redb/index.rs +274 -0
- data/ext/gqlitedb/src/store/redb.rs +1268 -113
- data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +28 -0
- data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +103 -0
- data/ext/gqlitedb/src/store/sqlbase.rs +146 -16
- data/ext/gqlitedb/src/store/sqlite.rs +569 -5
- data/ext/gqlitedb/src/store/vector_extract.rs +56 -0
- data/ext/gqlitedb/src/store.rs +123 -3
- data/ext/gqlitedb/src/tests/compiler.rs +207 -10
- data/ext/gqlitedb/src/tests/connection/postgres.rs +38 -3
- data/ext/gqlitedb/src/tests/connection/redb.rs +23 -0
- data/ext/gqlitedb/src/tests/connection/sqlite.rs +31 -0
- data/ext/gqlitedb/src/tests/connection.rs +61 -1
- data/ext/gqlitedb/src/tests/evaluators.rs +162 -7
- data/ext/gqlitedb/src/tests/parser.rs +54 -23
- data/ext/gqlitedb/src/tests/planner.rs +511 -0
- data/ext/gqlitedb/src/tests/store/postgres.rs +7 -0
- data/ext/gqlitedb/src/tests/store/redb.rs +8 -0
- data/ext/gqlitedb/src/tests/store/sqlite.rs +8 -0
- data/ext/gqlitedb/src/tests/store/vector_index/postgres.rs +182 -0
- data/ext/gqlitedb/src/tests/store/vector_index/redb.rs +386 -0
- data/ext/gqlitedb/src/tests/store/vector_index/sqlite.rs +166 -0
- data/ext/gqlitedb/src/tests/store/vector_index.rs +2313 -0
- data/ext/gqlitedb/src/tests/store.rs +78 -14
- data/ext/gqlitedb/src/tests/templates/ast.rs +92 -16
- data/ext/gqlitedb/src/tests/templates/programs.rs +14 -7
- data/ext/gqlitedb/src/tests.rs +15 -9
- data/ext/gqlitedb/src/utils.rs +6 -1
- data/ext/gqlitedb/src/value/compare.rs +61 -3
- data/ext/gqlitedb/src/value.rs +136 -7
- data/ext/gqlitedb/templates/sql/postgres/metadata_delete.sql +1 -0
- data/ext/gqlitedb/templates/sql/postgres/node_select.sql +1 -1
- data/ext/gqlitedb/templates/sql/sqlite/metadata_delete.sql +1 -0
- data/ext/gqliterb/src/lib.rs +53 -8
- data/ext/gqlparser/Cargo.toml +25 -0
- data/ext/gqlparser/README.MD +9 -0
- data/ext/gqlparser/benches/pokec_divan.rs +34 -0
- data/ext/gqlparser/src/common.rs +69 -0
- data/ext/gqlparser/src/gqls/ast.rs +69 -0
- data/ext/gqlparser/src/gqls/constraint.rs +79 -0
- data/ext/gqlparser/src/gqls/error.rs +22 -0
- data/ext/gqlparser/src/gqls/parser.rs +813 -0
- data/ext/gqlparser/src/gqls/prelude.rs +8 -0
- data/ext/gqlparser/src/gqls/properties.rs +115 -0
- data/ext/gqlparser/src/gqls/resolve.rs +207 -0
- data/ext/gqlparser/src/gqls.rs +265 -0
- data/ext/gqlparser/src/lib.rs +7 -0
- data/ext/gqlparser/src/oc/ast.rs +680 -0
- data/ext/gqlparser/src/oc/error.rs +172 -0
- data/ext/gqlparser/src/oc/lexer.rs +429 -0
- data/ext/gqlparser/src/oc/parser/tests.rs +2284 -0
- data/ext/gqlparser/src/oc/parser.rs +2005 -0
- data/ext/gqlparser/src/oc.rs +33 -0
- data/ext/gqlparser/src/prelude.rs +3 -0
- data/ext/graphcore/Cargo.toml +1 -0
- data/ext/graphcore/src/error.rs +26 -0
- data/ext/graphcore/src/graph.rs +177 -51
- data/ext/graphcore/src/lib.rs +4 -2
- data/ext/graphcore/src/open_cypher.rs +12 -0
- data/ext/graphcore/src/table.rs +50 -2
- data/ext/graphcore/src/timestamp.rs +127 -104
- data/ext/graphcore/src/value/tensor.rs +739 -0
- data/ext/graphcore/src/value/value_map.rs +1 -1
- data/ext/graphcore/src/value.rs +343 -19
- metadata +90 -22
- data/ext/gqlitedb/src/parser/ast.rs +0 -604
- data/ext/gqlitedb/src/parser/parser_impl.rs +0 -1213
- data/ext/gqlitedb/src/parser.rs +0 -4
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
pub(crate) mod variables_manager;
|
|
1
|
+
use gqlparser::oc::ast;
|
|
3
2
|
|
|
4
3
|
use crate::{
|
|
5
|
-
compiler::
|
|
4
|
+
compiler::{expression_analyser::ExpressionType, variables_manager::VariablesManager},
|
|
5
|
+
interpreter::instructions::{CreateActionVariable, VariablesSizes},
|
|
6
|
+
planner::{LogicalPlan, LogicalPlans, ProjectionKind},
|
|
6
7
|
prelude::*,
|
|
7
8
|
};
|
|
8
9
|
|
|
@@ -10,7 +11,9 @@ use interpreter::instructions::{
|
|
|
10
11
|
self, Block, BlockMatch, CreateAction, Instruction, Instructions, Modifiers, RWAggregation,
|
|
11
12
|
RWExpression,
|
|
12
13
|
};
|
|
13
|
-
|
|
14
|
+
|
|
15
|
+
pub(crate) mod expression_analyser;
|
|
16
|
+
pub(crate) mod variables_manager;
|
|
14
17
|
|
|
15
18
|
macro_rules! compile_binary_op {
|
|
16
19
|
( $this:tt, $x:tt, $instructions:tt, $aggregations:tt ) => {
|
|
@@ -27,6 +30,25 @@ struct CompiledReturnWith
|
|
|
27
30
|
variables_sizes: VariablesSizes,
|
|
28
31
|
}
|
|
29
32
|
|
|
33
|
+
struct PlannedProjection
|
|
34
|
+
{
|
|
35
|
+
kind: ProjectionKind,
|
|
36
|
+
all: bool,
|
|
37
|
+
expressions: Vec<ast::NamedExpression>,
|
|
38
|
+
where_expression: Option<ast::Expression>,
|
|
39
|
+
modifiers: ast::Modifiers,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fn is_scan_plan(plan: &LogicalPlan) -> bool
|
|
43
|
+
{
|
|
44
|
+
match plan
|
|
45
|
+
{
|
|
46
|
+
LogicalPlan::NodeScan { .. } => true,
|
|
47
|
+
LogicalPlan::Filter { source, .. } => is_scan_plan(source),
|
|
48
|
+
_ => false,
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
30
52
|
struct Compiler
|
|
31
53
|
{
|
|
32
54
|
function_manager: functions::Manager,
|
|
@@ -54,7 +76,7 @@ impl Compiler
|
|
|
54
76
|
|
|
55
77
|
fn compile_expression(
|
|
56
78
|
&mut self,
|
|
57
|
-
expression: &
|
|
79
|
+
expression: &gqlparser::oc::ast::Expression,
|
|
58
80
|
instructions: &mut Instructions,
|
|
59
81
|
aggregations: &mut Option<&mut Vec<(value_table::ColId, RWAggregation)>>,
|
|
60
82
|
) -> Result<()>
|
|
@@ -321,16 +343,17 @@ impl Compiler
|
|
|
321
343
|
|
|
322
344
|
fn compile_create_node(
|
|
323
345
|
&mut self,
|
|
324
|
-
node:
|
|
346
|
+
node: gqlparser::oc::ast::NodePattern,
|
|
325
347
|
instructions: &mut Instructions,
|
|
326
|
-
variables: &mut Vec<
|
|
348
|
+
variables: &mut Vec<CreateActionVariable>,
|
|
327
349
|
) -> Result<()>
|
|
328
350
|
{
|
|
329
|
-
variables.push(
|
|
330
|
-
|
|
351
|
+
variables.push(CreateActionVariable {
|
|
352
|
+
path: None,
|
|
353
|
+
element: self
|
|
331
354
|
.variables_manager
|
|
332
355
|
.get_variable_index_option(&node.variable)?,
|
|
333
|
-
);
|
|
356
|
+
});
|
|
334
357
|
self
|
|
335
358
|
.variables_manager
|
|
336
359
|
.mark_variables_as_set(&node.variable)?;
|
|
@@ -341,6 +364,84 @@ impl Compiler
|
|
|
341
364
|
Ok(())
|
|
342
365
|
}
|
|
343
366
|
|
|
367
|
+
fn compile_create_edge(
|
|
368
|
+
&mut self,
|
|
369
|
+
edge: gqlparser::oc::ast::EdgePattern,
|
|
370
|
+
instructions: &mut Instructions,
|
|
371
|
+
variables: &mut Vec<CreateActionVariable>,
|
|
372
|
+
path_variable: Option<ast::VariableIdentifier>,
|
|
373
|
+
) -> Result<()>
|
|
374
|
+
{
|
|
375
|
+
let source_variable = edge.source.variable.clone();
|
|
376
|
+
let destination_variable = edge.destination.variable.clone();
|
|
377
|
+
// Generate source
|
|
378
|
+
if self
|
|
379
|
+
.variables_manager
|
|
380
|
+
.is_set_variable(&edge.source.variable)?
|
|
381
|
+
{
|
|
382
|
+
instructions.push(Instruction::GetVariable {
|
|
383
|
+
col_id: self
|
|
384
|
+
.variables_manager
|
|
385
|
+
.get_variable_index(edge.source.variable.as_ref().unwrap())?,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
else
|
|
389
|
+
{
|
|
390
|
+
self.compile_create_node(edge.source, instructions, variables)?;
|
|
391
|
+
instructions.push(Instruction::Duplicate);
|
|
392
|
+
}
|
|
393
|
+
// Generate destination
|
|
394
|
+
if source_variable.is_some()
|
|
395
|
+
&& destination_variable.is_some()
|
|
396
|
+
&& source_variable == destination_variable
|
|
397
|
+
{
|
|
398
|
+
instructions.push(Instruction::Duplicate);
|
|
399
|
+
}
|
|
400
|
+
else if self
|
|
401
|
+
.variables_manager
|
|
402
|
+
.is_set_variable(&edge.destination.variable)?
|
|
403
|
+
{
|
|
404
|
+
instructions.push(Instruction::GetVariable {
|
|
405
|
+
col_id: self
|
|
406
|
+
.variables_manager
|
|
407
|
+
.get_variable_index(edge.destination.variable.as_ref().unwrap())?,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
else
|
|
411
|
+
{
|
|
412
|
+
self.compile_create_node(edge.destination, instructions, variables)?;
|
|
413
|
+
instructions.push(Instruction::Duplicate);
|
|
414
|
+
instructions.push(Instruction::Rot3);
|
|
415
|
+
}
|
|
416
|
+
variables.push(CreateActionVariable {
|
|
417
|
+
element: self
|
|
418
|
+
.variables_manager
|
|
419
|
+
.get_variable_index_option(&edge.variable)?,
|
|
420
|
+
path: self
|
|
421
|
+
.variables_manager
|
|
422
|
+
.get_variable_index_option(&path_variable)?,
|
|
423
|
+
});
|
|
424
|
+
self
|
|
425
|
+
.variables_manager
|
|
426
|
+
.mark_variables_as_set(&edge.variable)?;
|
|
427
|
+
self.compile_optional_expression(&edge.properties, instructions)?;
|
|
428
|
+
// Reject variable-length relationships in CREATE statements
|
|
429
|
+
if edge.recursive_range.is_some()
|
|
430
|
+
{
|
|
431
|
+
return Err(CompileTimeError::CreatingVarLength.into());
|
|
432
|
+
}
|
|
433
|
+
if !edge.labels.is_string()
|
|
434
|
+
{
|
|
435
|
+
Err(CompileTimeError::NoSingleRelationshipType {
|
|
436
|
+
text: Default::default(),
|
|
437
|
+
span: Default::default(),
|
|
438
|
+
})?;
|
|
439
|
+
}
|
|
440
|
+
let mut labels = Default::default();
|
|
441
|
+
Self::compile_labels_expression(&mut labels, &edge.labels)?;
|
|
442
|
+
instructions.push(Instruction::CreateEdgeLiteral { labels });
|
|
443
|
+
Ok(())
|
|
444
|
+
}
|
|
344
445
|
fn compile_labels_expression(
|
|
345
446
|
labels: &mut Vec<String>,
|
|
346
447
|
label_expressions: &ast::LabelExpression,
|
|
@@ -442,80 +543,35 @@ impl Compiler
|
|
|
442
543
|
}
|
|
443
544
|
}
|
|
444
545
|
|
|
445
|
-
fn compile_create_patterns(
|
|
546
|
+
fn compile_create_patterns(
|
|
547
|
+
&mut self,
|
|
548
|
+
patterns: impl IntoIterator<Item = gqlparser::oc::ast::Pattern>,
|
|
549
|
+
) -> Result<Block>
|
|
446
550
|
{
|
|
447
|
-
let actions = patterns.
|
|
551
|
+
let actions = patterns.into_iter().map(|c| {
|
|
448
552
|
let mut instructions = Instructions::new();
|
|
449
|
-
let mut variables = Vec::<
|
|
553
|
+
let mut variables = Vec::<CreateActionVariable>::new();
|
|
450
554
|
match c
|
|
451
555
|
{
|
|
452
|
-
|
|
556
|
+
gqlparser::oc::ast::Pattern::Node(node) =>
|
|
453
557
|
{
|
|
454
558
|
self.compile_create_node(node, &mut instructions, &mut variables)?;
|
|
455
559
|
}
|
|
456
|
-
|
|
560
|
+
gqlparser::oc::ast::Pattern::Edge(edge) =>
|
|
457
561
|
{
|
|
458
|
-
|
|
459
|
-
if self
|
|
460
|
-
.variables_manager
|
|
461
|
-
.is_set_variable(&edge.source.variable)?
|
|
462
|
-
{
|
|
463
|
-
instructions.push(Instruction::GetVariable {
|
|
464
|
-
col_id: self
|
|
465
|
-
.variables_manager
|
|
466
|
-
.get_variable_index(edge.source.variable.as_ref().unwrap())?,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
else
|
|
470
|
-
{
|
|
471
|
-
self.compile_create_node(&edge.source, &mut instructions, &mut variables)?;
|
|
472
|
-
instructions.push(Instruction::Duplicate);
|
|
473
|
-
}
|
|
474
|
-
// Generate destination
|
|
475
|
-
if edge.source.variable.is_some()
|
|
476
|
-
&& edge.destination.variable.is_some()
|
|
477
|
-
&& edge.source.variable == edge.destination.variable
|
|
478
|
-
{
|
|
479
|
-
instructions.push(Instruction::Duplicate);
|
|
480
|
-
}
|
|
481
|
-
else if self
|
|
482
|
-
.variables_manager
|
|
483
|
-
.is_set_variable(&edge.destination.variable)?
|
|
484
|
-
{
|
|
485
|
-
instructions.push(Instruction::GetVariable {
|
|
486
|
-
col_id: self
|
|
487
|
-
.variables_manager
|
|
488
|
-
.get_variable_index(edge.destination.variable.as_ref().unwrap())?,
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
else
|
|
492
|
-
{
|
|
493
|
-
self.compile_create_node(&edge.destination, &mut instructions, &mut variables)?;
|
|
494
|
-
instructions.push(Instruction::Duplicate);
|
|
495
|
-
instructions.push(Instruction::Rot3);
|
|
496
|
-
}
|
|
497
|
-
variables.push(
|
|
498
|
-
self
|
|
499
|
-
.variables_manager
|
|
500
|
-
.get_variable_index_option(&edge.variable)?,
|
|
501
|
-
);
|
|
502
|
-
self
|
|
503
|
-
.variables_manager
|
|
504
|
-
.mark_variables_as_set(&edge.variable)?;
|
|
505
|
-
self.compile_optional_expression(&edge.properties, &mut instructions)?;
|
|
506
|
-
if !edge.labels.is_string()
|
|
507
|
-
{
|
|
508
|
-
Err(CompileTimeError::NoSingleRelationshipType)?;
|
|
509
|
-
}
|
|
510
|
-
let mut labels = Default::default();
|
|
511
|
-
Self::compile_labels_expression(&mut labels, &edge.labels)?;
|
|
512
|
-
instructions.push(Instruction::CreateEdgeLiteral { labels });
|
|
562
|
+
self.compile_create_edge(edge, &mut instructions, &mut variables, None)?;
|
|
513
563
|
}
|
|
514
|
-
|
|
564
|
+
gqlparser::oc::ast::Pattern::Path(path) =>
|
|
515
565
|
{
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
566
|
+
self
|
|
567
|
+
.variables_manager
|
|
568
|
+
.mark_variables_as_set(&path.variable)?;
|
|
569
|
+
self.compile_create_edge(
|
|
570
|
+
path.edge,
|
|
571
|
+
&mut instructions,
|
|
572
|
+
&mut variables,
|
|
573
|
+
Some(path.variable),
|
|
574
|
+
)?;
|
|
519
575
|
}
|
|
520
576
|
}
|
|
521
577
|
Ok(CreateAction {
|
|
@@ -531,7 +587,7 @@ impl Compiler
|
|
|
531
587
|
|
|
532
588
|
fn compile_match_node(
|
|
533
589
|
&mut self,
|
|
534
|
-
node: &
|
|
590
|
+
node: &gqlparser::oc::ast::NodePattern,
|
|
535
591
|
instructions: &mut Instructions,
|
|
536
592
|
filter: &mut Instructions,
|
|
537
593
|
get_node_function_name: Option<&'static str>,
|
|
@@ -570,7 +626,7 @@ impl Compiler
|
|
|
570
626
|
fn compile_match_edge(
|
|
571
627
|
&mut self,
|
|
572
628
|
path_variable: Option<ast::VariableIdentifier>,
|
|
573
|
-
edge: &
|
|
629
|
+
edge: &gqlparser::oc::ast::EdgePattern,
|
|
574
630
|
single_match: bool,
|
|
575
631
|
previous_edges: &mut Vec<usize>,
|
|
576
632
|
) -> Result<BlockMatch>
|
|
@@ -599,11 +655,13 @@ impl Compiler
|
|
|
599
655
|
Some("get_source"),
|
|
600
656
|
)?;
|
|
601
657
|
}
|
|
602
|
-
let
|
|
658
|
+
let destination_variable;
|
|
603
659
|
if self
|
|
604
660
|
.variables_manager
|
|
605
661
|
.is_set_variable(&edge.destination.variable)?
|
|
606
662
|
{
|
|
663
|
+
// Always capture the destination variable so the DFS can filter by pre-bound destination key.
|
|
664
|
+
destination_variable = edge.destination.variable.to_owned();
|
|
607
665
|
instructions.push(Instruction::GetVariable {
|
|
608
666
|
col_id: self
|
|
609
667
|
.variables_manager
|
|
@@ -706,6 +764,7 @@ impl Compiler
|
|
|
706
764
|
.get_variable_index_option(&path_variable)?,
|
|
707
765
|
filter,
|
|
708
766
|
directivity: edge.directivity,
|
|
767
|
+
recursive_range: edge.recursive_range.clone(),
|
|
709
768
|
})
|
|
710
769
|
}
|
|
711
770
|
|
|
@@ -796,8 +855,8 @@ impl Compiler
|
|
|
796
855
|
|
|
797
856
|
fn compile_match_patterns(
|
|
798
857
|
&mut self,
|
|
799
|
-
patterns: &[
|
|
800
|
-
where_expression: &Option<
|
|
858
|
+
patterns: &[gqlparser::oc::ast::Pattern],
|
|
859
|
+
where_expression: &Option<gqlparser::oc::ast::Expression>,
|
|
801
860
|
optional: bool,
|
|
802
861
|
) -> Result<Block>
|
|
803
862
|
{
|
|
@@ -805,7 +864,7 @@ impl Compiler
|
|
|
805
864
|
let mut edge_variables = vec![];
|
|
806
865
|
let blocks = patterns.iter().map(|c| match c
|
|
807
866
|
{
|
|
808
|
-
|
|
867
|
+
gqlparser::oc::ast::Pattern::Node(node) =>
|
|
809
868
|
{
|
|
810
869
|
let mut instructions = Instructions::new();
|
|
811
870
|
let mut filter = Instructions::new();
|
|
@@ -821,11 +880,11 @@ impl Compiler
|
|
|
821
880
|
filter,
|
|
822
881
|
})
|
|
823
882
|
}
|
|
824
|
-
|
|
883
|
+
gqlparser::oc::ast::Pattern::Edge(edge) =>
|
|
825
884
|
{
|
|
826
885
|
self.compile_match_edge(None, edge, is_single_match, &mut edge_variables)
|
|
827
886
|
}
|
|
828
|
-
|
|
887
|
+
gqlparser::oc::ast::Pattern::Path(path) => self.compile_match_edge(
|
|
829
888
|
Some(path.variable.to_owned()),
|
|
830
889
|
&path.edge,
|
|
831
890
|
is_single_match,
|
|
@@ -852,11 +911,17 @@ impl Compiler
|
|
|
852
911
|
})
|
|
853
912
|
}
|
|
854
913
|
|
|
855
|
-
fn
|
|
914
|
+
fn check_for_positive_constant_integer_expression(&mut self, x: &ast::Expression) -> Result<()>
|
|
856
915
|
{
|
|
916
|
+
if let ast::Expression::Value(value) = x
|
|
917
|
+
&& let Ok(v) = <&graphcore::Value as TryInto<i64>>::try_into(&value.value)
|
|
918
|
+
&& v < 0
|
|
919
|
+
{
|
|
920
|
+
return Err(error::CompileTimeError::NegativeIntegerArgument.into());
|
|
921
|
+
}
|
|
857
922
|
let ei = expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
|
|
858
923
|
.analyse(x)?;
|
|
859
|
-
if !ei.
|
|
924
|
+
if !ei.runtime_constant
|
|
860
925
|
{
|
|
861
926
|
Err(error::CompileTimeError::NonConstantExpression.into())
|
|
862
927
|
}
|
|
@@ -880,7 +945,7 @@ impl Compiler
|
|
|
880
945
|
.limit
|
|
881
946
|
.as_ref()
|
|
882
947
|
.map(|x| {
|
|
883
|
-
self.
|
|
948
|
+
self.check_for_positive_constant_integer_expression(x)?;
|
|
884
949
|
let mut instructions = Instructions::new();
|
|
885
950
|
self.compile_expression(x, &mut instructions, &mut None)?;
|
|
886
951
|
Ok::<_, ErrorType>(instructions)
|
|
@@ -890,7 +955,7 @@ impl Compiler
|
|
|
890
955
|
.skip
|
|
891
956
|
.as_ref()
|
|
892
957
|
.map(|x| {
|
|
893
|
-
self.
|
|
958
|
+
self.check_for_positive_constant_integer_expression(x)?;
|
|
894
959
|
let mut instructions = Instructions::new();
|
|
895
960
|
self.compile_expression(x, &mut instructions, &mut None)?;
|
|
896
961
|
Ok::<_, ErrorType>(instructions)
|
|
@@ -920,11 +985,227 @@ impl Compiler
|
|
|
920
985
|
order_by,
|
|
921
986
|
})
|
|
922
987
|
}
|
|
988
|
+
|
|
989
|
+
fn unpack_scan_plan(
|
|
990
|
+
logical_plan: LogicalPlan,
|
|
991
|
+
) -> Result<(Vec<ast::Pattern>, Option<ast::Expression>, bool)>
|
|
992
|
+
{
|
|
993
|
+
match logical_plan
|
|
994
|
+
{
|
|
995
|
+
LogicalPlan::NodeScan { patterns, optional } => Ok((patterns, None, optional)),
|
|
996
|
+
LogicalPlan::Filter { source, expression } =>
|
|
997
|
+
{
|
|
998
|
+
let (patterns, filter, optional) = Self::unpack_scan_plan(*source)?;
|
|
999
|
+
if filter.is_some()
|
|
1000
|
+
{
|
|
1001
|
+
return Err(
|
|
1002
|
+
InternalError::Unreachable {
|
|
1003
|
+
context: "compile/unpack_scan_plan/filter",
|
|
1004
|
+
}
|
|
1005
|
+
.into(),
|
|
1006
|
+
);
|
|
1007
|
+
}
|
|
1008
|
+
Ok((patterns, Some(expression), optional))
|
|
1009
|
+
}
|
|
1010
|
+
_ => Err(
|
|
1011
|
+
InternalError::Unreachable {
|
|
1012
|
+
context: "compile/unpack_scan_plan",
|
|
1013
|
+
}
|
|
1014
|
+
.into(),
|
|
1015
|
+
),
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
fn compile_scan_plan(&mut self, logical_plan: LogicalPlan) -> Result<Block>
|
|
1020
|
+
{
|
|
1021
|
+
let (patterns, where_expression, optional) = Self::unpack_scan_plan(logical_plan)?;
|
|
1022
|
+
self.compile_match_patterns(&patterns, &where_expression, optional)
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
fn unpack_projection_plan(logical_plan: LogicalPlan) -> Result<PlannedProjection>
|
|
1026
|
+
{
|
|
1027
|
+
match logical_plan
|
|
1028
|
+
{
|
|
1029
|
+
LogicalPlan::Projection {
|
|
1030
|
+
kind,
|
|
1031
|
+
all,
|
|
1032
|
+
expressions,
|
|
1033
|
+
} => Ok(PlannedProjection {
|
|
1034
|
+
kind,
|
|
1035
|
+
all,
|
|
1036
|
+
expressions,
|
|
1037
|
+
where_expression: None,
|
|
1038
|
+
modifiers: Default::default(),
|
|
1039
|
+
}),
|
|
1040
|
+
LogicalPlan::Filter { source, expression } =>
|
|
1041
|
+
{
|
|
1042
|
+
let mut projection = Self::unpack_projection_plan(*source)?;
|
|
1043
|
+
if projection.where_expression.is_some()
|
|
1044
|
+
{
|
|
1045
|
+
return Err(
|
|
1046
|
+
InternalError::Unreachable {
|
|
1047
|
+
context: "compile/unpack_projection_plan/filter",
|
|
1048
|
+
}
|
|
1049
|
+
.into(),
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
1052
|
+
projection.where_expression = Some(expression);
|
|
1053
|
+
Ok(projection)
|
|
1054
|
+
}
|
|
1055
|
+
LogicalPlan::Sort {
|
|
1056
|
+
source,
|
|
1057
|
+
expressions,
|
|
1058
|
+
} =>
|
|
1059
|
+
{
|
|
1060
|
+
let mut projection = Self::unpack_projection_plan(*source)?;
|
|
1061
|
+
if projection.modifiers.order_by.is_some()
|
|
1062
|
+
{
|
|
1063
|
+
return Err(
|
|
1064
|
+
InternalError::Unreachable {
|
|
1065
|
+
context: "compile/unpack_projection_plan/sort",
|
|
1066
|
+
}
|
|
1067
|
+
.into(),
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
projection.modifiers.order_by = Some(ast::OrderBy { expressions });
|
|
1071
|
+
Ok(projection)
|
|
1072
|
+
}
|
|
1073
|
+
LogicalPlan::Skip { source, expression } =>
|
|
1074
|
+
{
|
|
1075
|
+
let mut projection = Self::unpack_projection_plan(*source)?;
|
|
1076
|
+
if projection.modifiers.skip.is_some()
|
|
1077
|
+
{
|
|
1078
|
+
return Err(
|
|
1079
|
+
InternalError::Unreachable {
|
|
1080
|
+
context: "compile/unpack_projection_plan/skip",
|
|
1081
|
+
}
|
|
1082
|
+
.into(),
|
|
1083
|
+
);
|
|
1084
|
+
}
|
|
1085
|
+
projection.modifiers.skip = Some(expression);
|
|
1086
|
+
Ok(projection)
|
|
1087
|
+
}
|
|
1088
|
+
LogicalPlan::Limit { source, expression } =>
|
|
1089
|
+
{
|
|
1090
|
+
let mut projection = Self::unpack_projection_plan(*source)?;
|
|
1091
|
+
if projection.modifiers.limit.is_some()
|
|
1092
|
+
{
|
|
1093
|
+
return Err(
|
|
1094
|
+
InternalError::Unreachable {
|
|
1095
|
+
context: "compile/unpack_projection_plan/limit",
|
|
1096
|
+
}
|
|
1097
|
+
.into(),
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
projection.modifiers.limit = Some(expression);
|
|
1101
|
+
Ok(projection)
|
|
1102
|
+
}
|
|
1103
|
+
_ => Err(
|
|
1104
|
+
InternalError::Unreachable {
|
|
1105
|
+
context: "compile/unpack_projection_plan",
|
|
1106
|
+
}
|
|
1107
|
+
.into(),
|
|
1108
|
+
),
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
fn compile_projection_plan(&mut self, logical_plan: LogicalPlan) -> Result<Block>
|
|
1113
|
+
{
|
|
1114
|
+
let projection = Self::unpack_projection_plan(logical_plan)?;
|
|
1115
|
+
let compiled_return_with = self.compile_return_with(
|
|
1116
|
+
projection.all,
|
|
1117
|
+
&projection.expressions,
|
|
1118
|
+
&projection.where_expression,
|
|
1119
|
+
&projection.modifiers,
|
|
1120
|
+
)?;
|
|
1121
|
+
|
|
1122
|
+
match projection.kind
|
|
1123
|
+
{
|
|
1124
|
+
ProjectionKind::Return => Ok(Block::Return {
|
|
1125
|
+
variables: compiled_return_with.variables,
|
|
1126
|
+
filter: compiled_return_with.filter,
|
|
1127
|
+
modifiers: compiled_return_with.modifiers,
|
|
1128
|
+
variables_sizes: compiled_return_with.variables_sizes,
|
|
1129
|
+
}),
|
|
1130
|
+
ProjectionKind::With => Ok(Block::With {
|
|
1131
|
+
variables: compiled_return_with
|
|
1132
|
+
.variables
|
|
1133
|
+
.into_iter()
|
|
1134
|
+
.map(|(_, v)| v)
|
|
1135
|
+
.collect(),
|
|
1136
|
+
filter: compiled_return_with.filter,
|
|
1137
|
+
modifiers: compiled_return_with.modifiers,
|
|
1138
|
+
variables_sizes: compiled_return_with.variables_sizes,
|
|
1139
|
+
}),
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
fn compile_updates(&mut self, updates: &[ast::OneUpdate])
|
|
1144
|
+
-> Result<Vec<instructions::UpdateOne>>
|
|
1145
|
+
{
|
|
1146
|
+
updates
|
|
1147
|
+
.iter()
|
|
1148
|
+
.map(|x| match x
|
|
1149
|
+
{
|
|
1150
|
+
ast::OneUpdate::SetProperty(update_property)
|
|
1151
|
+
| ast::OneUpdate::AddProperty(update_property) =>
|
|
1152
|
+
{
|
|
1153
|
+
let mut instructions = Instructions::new();
|
|
1154
|
+
self.compile_expression(&update_property.expression, &mut instructions, &mut None)?;
|
|
1155
|
+
|
|
1156
|
+
match x
|
|
1157
|
+
{
|
|
1158
|
+
ast::OneUpdate::SetProperty(_) => Ok(instructions::UpdateOne::SetProperty {
|
|
1159
|
+
target: self
|
|
1160
|
+
.variables_manager
|
|
1161
|
+
.get_variable_index(&update_property.target)?,
|
|
1162
|
+
path: update_property.path.to_owned(),
|
|
1163
|
+
instructions,
|
|
1164
|
+
}),
|
|
1165
|
+
ast::OneUpdate::AddProperty(_) => Ok(instructions::UpdateOne::AddProperty {
|
|
1166
|
+
target: self
|
|
1167
|
+
.variables_manager
|
|
1168
|
+
.get_variable_index(&update_property.target)?,
|
|
1169
|
+
path: update_property.path.to_owned(),
|
|
1170
|
+
instructions,
|
|
1171
|
+
}),
|
|
1172
|
+
_ => Err(
|
|
1173
|
+
InternalError::Unreachable {
|
|
1174
|
+
context: "compile_updates/SetAddProperty",
|
|
1175
|
+
}
|
|
1176
|
+
.into(),
|
|
1177
|
+
),
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
ast::OneUpdate::RemoveProperty(remove_property) =>
|
|
1181
|
+
{
|
|
1182
|
+
Ok(instructions::UpdateOne::RemoveProperty {
|
|
1183
|
+
target: self
|
|
1184
|
+
.variables_manager
|
|
1185
|
+
.get_variable_index(&remove_property.target)?,
|
|
1186
|
+
path: remove_property.path.to_owned(),
|
|
1187
|
+
})
|
|
1188
|
+
}
|
|
1189
|
+
ast::OneUpdate::AddLabels(add_labels) => Ok(instructions::UpdateOne::AddLabels {
|
|
1190
|
+
target: self
|
|
1191
|
+
.variables_manager
|
|
1192
|
+
.get_variable_index(&add_labels.target)?,
|
|
1193
|
+
labels: add_labels.labels.to_owned(),
|
|
1194
|
+
}),
|
|
1195
|
+
ast::OneUpdate::RemoveLabels(rm_labels) => Ok(instructions::UpdateOne::RemoveLabels {
|
|
1196
|
+
target: self
|
|
1197
|
+
.variables_manager
|
|
1198
|
+
.get_variable_index(&rm_labels.target)?,
|
|
1199
|
+
labels: rm_labels.labels.to_owned(),
|
|
1200
|
+
}),
|
|
1201
|
+
})
|
|
1202
|
+
.collect::<Result<_>>()
|
|
1203
|
+
}
|
|
923
1204
|
}
|
|
924
1205
|
|
|
925
1206
|
pub(crate) fn compile(
|
|
926
1207
|
function_manager: &functions::Manager,
|
|
927
|
-
|
|
1208
|
+
logical_plans: LogicalPlans,
|
|
928
1209
|
) -> Result<interpreter::Program>
|
|
929
1210
|
{
|
|
930
1211
|
let mut compiler = Compiler {
|
|
@@ -932,93 +1213,64 @@ pub(crate) fn compile(
|
|
|
932
1213
|
function_manager: function_manager.clone(),
|
|
933
1214
|
temporary_variables: 0,
|
|
934
1215
|
};
|
|
935
|
-
let
|
|
936
|
-
|
|
937
|
-
.
|
|
938
|
-
.map(|stmt| {
|
|
1216
|
+
let program = logical_plans
|
|
1217
|
+
.into_iter()
|
|
1218
|
+
.map(|logical_plan| {
|
|
939
1219
|
compiler.temporary_variables = 0;
|
|
940
|
-
compiler.variables_manager.analyse(
|
|
941
|
-
match
|
|
1220
|
+
compiler.variables_manager.analyse(&logical_plan)?;
|
|
1221
|
+
match logical_plan
|
|
942
1222
|
{
|
|
943
|
-
|
|
944
|
-
name
|
|
945
|
-
if_not_exists
|
|
946
|
-
}
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
if_exists: drop_graph.if_exists,
|
|
1223
|
+
LogicalPlan::CreateGraph {
|
|
1224
|
+
name,
|
|
1225
|
+
if_not_exists,
|
|
1226
|
+
} => Ok(Block::CreateGraph {
|
|
1227
|
+
name,
|
|
1228
|
+
if_not_exists,
|
|
950
1229
|
}),
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
}),
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
&match_statement.patterns,
|
|
957
|
-
&match_statement.where_expression,
|
|
958
|
-
match_statement.optional,
|
|
959
|
-
),
|
|
960
|
-
ast::Statement::Return(return_statement) =>
|
|
1230
|
+
LogicalPlan::DropGraph { name, if_exists } => Ok(Block::DropGraph { name, if_exists }),
|
|
1231
|
+
LogicalPlan::UseGraph { name } => Ok(Block::UseGraph { name }),
|
|
1232
|
+
LogicalPlan::Create { patterns } => compiler.compile_create_patterns(patterns),
|
|
1233
|
+
LogicalPlan::NodeScan { .. } => compiler.compile_scan_plan(logical_plan),
|
|
1234
|
+
LogicalPlan::Filter { ref source, .. } if is_scan_plan(source.as_ref()) =>
|
|
961
1235
|
{
|
|
962
|
-
|
|
963
|
-
return_statement.all,
|
|
964
|
-
&return_statement.expressions,
|
|
965
|
-
&return_statement.where_expression,
|
|
966
|
-
&return_statement.modifiers,
|
|
967
|
-
)?;
|
|
968
|
-
Ok(Block::Return {
|
|
969
|
-
variables: compiled_return_with.variables,
|
|
970
|
-
filter: compiled_return_with.filter,
|
|
971
|
-
modifiers: compiled_return_with.modifiers,
|
|
972
|
-
variables_sizes: compiled_return_with.variables_sizes,
|
|
973
|
-
})
|
|
1236
|
+
compiler.compile_scan_plan(logical_plan)
|
|
974
1237
|
}
|
|
975
|
-
|
|
1238
|
+
LogicalPlan::Projection { .. }
|
|
1239
|
+
| LogicalPlan::Sort { .. }
|
|
1240
|
+
| LogicalPlan::Skip { .. }
|
|
1241
|
+
| LogicalPlan::Limit { .. }
|
|
1242
|
+
| LogicalPlan::Filter { .. } => compiler.compile_projection_plan(logical_plan),
|
|
1243
|
+
LogicalPlan::Call { name, arguments } =>
|
|
976
1244
|
{
|
|
977
1245
|
let mut instructions = Instructions::new();
|
|
978
|
-
for e in
|
|
1246
|
+
for e in arguments.iter().rev()
|
|
979
1247
|
{
|
|
980
1248
|
compiler.compile_expression(e, &mut instructions, &mut None)?;
|
|
981
1249
|
}
|
|
982
1250
|
Ok(Block::Call {
|
|
983
1251
|
arguments: instructions,
|
|
984
|
-
name
|
|
1252
|
+
name,
|
|
985
1253
|
})
|
|
986
1254
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
&with.expressions,
|
|
992
|
-
&with.where_expression,
|
|
993
|
-
&with.modifiers,
|
|
994
|
-
)?;
|
|
995
|
-
Ok(Block::With {
|
|
996
|
-
variables: compiled_return_with
|
|
997
|
-
.variables
|
|
998
|
-
.into_iter()
|
|
999
|
-
.map(|(_, v)| v)
|
|
1000
|
-
.collect(),
|
|
1001
|
-
filter: compiled_return_with.filter,
|
|
1002
|
-
modifiers: compiled_return_with.modifiers,
|
|
1003
|
-
variables_sizes: compiled_return_with.variables_sizes,
|
|
1004
|
-
})
|
|
1005
|
-
}
|
|
1006
|
-
ast::Statement::Unwind(unwind) =>
|
|
1255
|
+
LogicalPlan::Unwind {
|
|
1256
|
+
identifier,
|
|
1257
|
+
expression,
|
|
1258
|
+
} =>
|
|
1007
1259
|
{
|
|
1008
1260
|
let mut instructions = Instructions::new();
|
|
1009
|
-
compiler.compile_expression(&
|
|
1261
|
+
compiler.compile_expression(&expression, &mut instructions, &mut None)?;
|
|
1010
1262
|
Ok(Block::Unwind {
|
|
1011
|
-
col_id: compiler
|
|
1012
|
-
.variables_manager
|
|
1013
|
-
.get_variable_index(&unwind.identifier)?,
|
|
1263
|
+
col_id: compiler.variables_manager.get_variable_index(&identifier)?,
|
|
1014
1264
|
instructions,
|
|
1015
1265
|
variables_size: compiler.variables_size(),
|
|
1016
1266
|
})
|
|
1017
1267
|
}
|
|
1018
|
-
|
|
1019
|
-
detach
|
|
1020
|
-
|
|
1021
|
-
|
|
1268
|
+
LogicalPlan::Delete {
|
|
1269
|
+
detach,
|
|
1270
|
+
expressions,
|
|
1271
|
+
} => Ok(Block::Delete {
|
|
1272
|
+
detach,
|
|
1273
|
+
instructions: expressions
|
|
1022
1274
|
.iter()
|
|
1023
1275
|
.map(|expr| {
|
|
1024
1276
|
let mut instructions = Instructions::new();
|
|
@@ -1039,84 +1291,112 @@ pub(crate) fn compile(
|
|
|
1039
1291
|
})
|
|
1040
1292
|
.collect::<Result<_>>()?,
|
|
1041
1293
|
}),
|
|
1042
|
-
|
|
1043
|
-
updates:
|
|
1044
|
-
.updates
|
|
1045
|
-
.iter()
|
|
1046
|
-
.map(|x| match x
|
|
1047
|
-
{
|
|
1048
|
-
ast::OneUpdate::SetProperty(update_property)
|
|
1049
|
-
| ast::OneUpdate::AddProperty(update_property) =>
|
|
1050
|
-
{
|
|
1051
|
-
let mut instructions = Instructions::new();
|
|
1052
|
-
compiler.compile_expression(
|
|
1053
|
-
&update_property.expression,
|
|
1054
|
-
&mut instructions,
|
|
1055
|
-
&mut None,
|
|
1056
|
-
)?;
|
|
1057
|
-
|
|
1058
|
-
match x
|
|
1059
|
-
{
|
|
1060
|
-
ast::OneUpdate::SetProperty(_) => Ok(instructions::UpdateOne::SetProperty {
|
|
1061
|
-
target: compiler
|
|
1062
|
-
.variables_manager
|
|
1063
|
-
.get_variable_index(&update_property.target)?,
|
|
1064
|
-
path: update_property.path.to_owned(),
|
|
1065
|
-
instructions,
|
|
1066
|
-
}),
|
|
1067
|
-
ast::OneUpdate::AddProperty(_) => Ok(instructions::UpdateOne::AddProperty {
|
|
1068
|
-
target: compiler
|
|
1069
|
-
.variables_manager
|
|
1070
|
-
.get_variable_index(&update_property.target)?,
|
|
1071
|
-
path: update_property.path.to_owned(),
|
|
1072
|
-
instructions,
|
|
1073
|
-
}),
|
|
1074
|
-
_ => Err(
|
|
1075
|
-
InternalError::Unreachable {
|
|
1076
|
-
context: "compile/Update/SetAddProperty",
|
|
1077
|
-
}
|
|
1078
|
-
.into(),
|
|
1079
|
-
),
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
ast::OneUpdate::RemoveProperty(remove_property) =>
|
|
1083
|
-
{
|
|
1084
|
-
Ok(instructions::UpdateOne::RemoveProperty {
|
|
1085
|
-
target: compiler
|
|
1086
|
-
.variables_manager
|
|
1087
|
-
.get_variable_index(&remove_property.target)?,
|
|
1088
|
-
path: remove_property.path.to_owned(),
|
|
1089
|
-
})
|
|
1090
|
-
}
|
|
1091
|
-
ast::OneUpdate::AddLabels(add_labels) => Ok(instructions::UpdateOne::AddLabels {
|
|
1092
|
-
target: compiler
|
|
1093
|
-
.variables_manager
|
|
1094
|
-
.get_variable_index(&add_labels.target)?,
|
|
1095
|
-
labels: add_labels.labels.to_owned(),
|
|
1096
|
-
}),
|
|
1097
|
-
ast::OneUpdate::RemoveLabels(rm_labels) =>
|
|
1098
|
-
{
|
|
1099
|
-
Ok(instructions::UpdateOne::RemoveLabels {
|
|
1100
|
-
target: compiler
|
|
1101
|
-
.variables_manager
|
|
1102
|
-
.get_variable_index(&rm_labels.target)?,
|
|
1103
|
-
labels: rm_labels.labels.to_owned(),
|
|
1104
|
-
})
|
|
1105
|
-
}
|
|
1106
|
-
})
|
|
1107
|
-
.collect::<Result<_>>()?,
|
|
1294
|
+
LogicalPlan::Update { updates } => Ok(Block::Update {
|
|
1295
|
+
updates: compiler.compile_updates(&updates)?,
|
|
1108
1296
|
variables_size: compiler.variables_size(),
|
|
1109
1297
|
}),
|
|
1298
|
+
LogicalPlan::VectorSearch {
|
|
1299
|
+
index,
|
|
1300
|
+
query,
|
|
1301
|
+
k,
|
|
1302
|
+
result_var,
|
|
1303
|
+
score_var,
|
|
1304
|
+
} =>
|
|
1305
|
+
{
|
|
1306
|
+
let mut query_instructions = Instructions::new();
|
|
1307
|
+
let ei = expression_analyser::Analyser::new(
|
|
1308
|
+
&compiler.variables_manager,
|
|
1309
|
+
&compiler.function_manager,
|
|
1310
|
+
)
|
|
1311
|
+
.analyse(&query)?;
|
|
1312
|
+
if ei.aggregation_result
|
|
1313
|
+
{
|
|
1314
|
+
return Err(CompileTimeError::InvalidAggregation.into());
|
|
1315
|
+
}
|
|
1316
|
+
match ei.expression_type
|
|
1317
|
+
{
|
|
1318
|
+
ExpressionType::Array | ExpressionType::Tensor | ExpressionType::Variant =>
|
|
1319
|
+
{}
|
|
1320
|
+
_ => return Err(CompileTimeError::InvalidVectorInput.into()),
|
|
1321
|
+
}
|
|
1322
|
+
compiler.compile_expression(&query, &mut query_instructions, &mut None)?;
|
|
1323
|
+
|
|
1324
|
+
// Get the column IDs for the output variables from the variables manager
|
|
1325
|
+
let out_node_col_id = compiler.variables_manager.get_variable_index(&result_var)?;
|
|
1326
|
+
let out_score_col_id = compiler
|
|
1327
|
+
.variables_manager
|
|
1328
|
+
.get_variable_index_option(&score_var)?;
|
|
1329
|
+
|
|
1330
|
+
Ok(Block::VectorSearch {
|
|
1331
|
+
index,
|
|
1332
|
+
query_instructions,
|
|
1333
|
+
k,
|
|
1334
|
+
out_node_col_id,
|
|
1335
|
+
out_score_col_id,
|
|
1336
|
+
variables_size: compiler.variables_size(),
|
|
1337
|
+
})
|
|
1338
|
+
}
|
|
1339
|
+
LogicalPlan::Merge {
|
|
1340
|
+
patterns,
|
|
1341
|
+
on_create,
|
|
1342
|
+
on_match,
|
|
1343
|
+
} =>
|
|
1344
|
+
{
|
|
1345
|
+
// 1. Compile the match side
|
|
1346
|
+
let Block::Match {
|
|
1347
|
+
blocks: match_blocks,
|
|
1348
|
+
filter: match_filter,
|
|
1349
|
+
..
|
|
1350
|
+
} = compiler.compile_match_patterns(&patterns, &None, false)?
|
|
1351
|
+
else
|
|
1352
|
+
{
|
|
1353
|
+
unreachable!()
|
|
1354
|
+
};
|
|
1355
|
+
|
|
1356
|
+
// 2. Compile the create side
|
|
1357
|
+
let Block::Create {
|
|
1358
|
+
actions: create_actions,
|
|
1359
|
+
..
|
|
1360
|
+
} = compiler.compile_create_patterns(patterns)?
|
|
1361
|
+
else
|
|
1362
|
+
{
|
|
1363
|
+
unreachable!()
|
|
1364
|
+
};
|
|
1365
|
+
|
|
1366
|
+
// 3. Compile ON CREATE / ON MATCH updates
|
|
1367
|
+
let on_create_updates = compiler.compile_updates(&on_create)?;
|
|
1368
|
+
let on_match_updates = compiler.compile_updates(&on_match)?;
|
|
1369
|
+
|
|
1370
|
+
Ok(Block::Merge {
|
|
1371
|
+
match_blocks,
|
|
1372
|
+
match_filter,
|
|
1373
|
+
create_actions,
|
|
1374
|
+
on_create_updates,
|
|
1375
|
+
on_match_updates,
|
|
1376
|
+
variables_size: compiler.variables_size(),
|
|
1377
|
+
})
|
|
1378
|
+
}
|
|
1379
|
+
LogicalPlan::CreateVectorIndex {
|
|
1380
|
+
name,
|
|
1381
|
+
label,
|
|
1382
|
+
property,
|
|
1383
|
+
dimension,
|
|
1384
|
+
metric,
|
|
1385
|
+
if_not_exists,
|
|
1386
|
+
} => Ok(Block::CreateVectorIndex {
|
|
1387
|
+
name,
|
|
1388
|
+
label,
|
|
1389
|
+
property,
|
|
1390
|
+
dimension,
|
|
1391
|
+
metric,
|
|
1392
|
+
if_not_exists,
|
|
1393
|
+
}),
|
|
1110
1394
|
}
|
|
1111
1395
|
})
|
|
1112
|
-
.
|
|
1113
|
-
gp.map_err(|e| **err = Err(e)).ok()
|
|
1114
|
-
});
|
|
1115
|
-
let program = program.collect::<interpreter::Program>();
|
|
1116
|
-
statements_err?;
|
|
1396
|
+
.collect::<Result<interpreter::Program>>()?;
|
|
1117
1397
|
if crate::consts::SHOW_PROGRAM
|
|
1118
1398
|
{
|
|
1119
|
-
|
|
1399
|
+
log::debug!("program = {:#?}", program);
|
|
1120
1400
|
}
|
|
1121
1401
|
Ok(program)
|
|
1122
1402
|
}
|