gqlite 1.8.1 → 1.8.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.
- checksums.yaml +4 -4
- data/ext/Cargo.toml +8 -8
- data/ext/gqlitedb/Cargo.toml +0 -2
- data/ext/gqlitedb/src/compiler/variables_manager.rs +109 -10
- data/ext/gqlitedb/src/compiler.rs +481 -47
- data/ext/gqlitedb/src/connection.rs +12 -0
- data/ext/gqlitedb/src/consts.rs +1 -1
- data/ext/gqlitedb/src/error.rs +24 -0
- data/ext/gqlitedb/src/interpreter/evaluators.rs +91 -325
- data/ext/gqlitedb/src/interpreter/instructions.rs +72 -0
- data/ext/gqlitedb/src/interpreter/mod.rs +1 -0
- data/ext/gqlitedb/src/interpreter/path/bfs.rs +494 -0
- data/ext/gqlitedb/src/interpreter/path/dfs.rs +267 -0
- data/ext/gqlitedb/src/interpreter/path/group.rs +418 -0
- data/ext/gqlitedb/src/interpreter/path.rs +542 -0
- data/ext/gqlitedb/src/planner.rs +218 -6
- data/ext/gqlitedb/src/query_result.rs +19 -4
- data/ext/gqlitedb/src/tests/compiler.rs +2453 -1
- data/ext/gqlitedb/src/tests/connection/redb.rs +8 -0
- data/ext/gqlitedb/src/tests/connection.rs +37 -0
- data/ext/gqlitedb/src/tests/evaluators.rs +2206 -1
- data/ext/gqlitedb/src/tests/parser.rs +1225 -0
- data/ext/gqlitedb/src/tests/planner.rs +432 -2
- data/ext/gqlitedb/src/tests/store/vector_index/postgres.rs +5 -5
- data/ext/gqlitedb/src/tests/store/vector_index/sqlite.rs +3 -1
- data/ext/gqlitedb/src/tests/templates/ast.rs +284 -1
- data/ext/gqlitedb/src/tests/templates/programs.rs +306 -0
- data/ext/gqliterb/Cargo.toml +0 -1
- data/ext/gqlparser/src/oc/ast.rs +52 -3
- data/ext/gqlparser/src/oc/error.rs +18 -0
- data/ext/gqlparser/src/oc/lexer.rs +146 -0
- data/ext/gqlparser/src/oc/parser/tests.rs +365 -20
- data/ext/gqlparser/src/oc/parser.rs +1196 -143
- data/ext/graphcore/src/value.rs +12 -1
- metadata +5 -2
- data/ext/gqlitedb/src/parser/gql.pest +0 -198
|
@@ -27,6 +27,8 @@ pub(crate) fn simple_create_node() -> Statements
|
|
|
27
27
|
variable: None,
|
|
28
28
|
labels: LabelExpression::None,
|
|
29
29
|
properties: None,
|
|
30
|
+
|
|
31
|
+
predicate: None,
|
|
30
32
|
})],
|
|
31
33
|
}
|
|
32
34
|
.into(),
|
|
@@ -54,6 +56,8 @@ pub(crate) fn create_named_node() -> Statements
|
|
|
54
56
|
}
|
|
55
57
|
.into(),
|
|
56
58
|
),
|
|
59
|
+
|
|
60
|
+
predicate: None,
|
|
57
61
|
})],
|
|
58
62
|
}
|
|
59
63
|
.into(),
|
|
@@ -106,6 +110,8 @@ pub(crate) fn create_named_node_double_return() -> Statements
|
|
|
106
110
|
}
|
|
107
111
|
.into(),
|
|
108
112
|
),
|
|
113
|
+
|
|
114
|
+
predicate: None,
|
|
109
115
|
})],
|
|
110
116
|
}
|
|
111
117
|
.into(),
|
|
@@ -233,16 +239,19 @@ pub(crate) fn match_loop() -> Statements
|
|
|
233
239
|
variable: Some(var_ids.create_variable_from_name("n")),
|
|
234
240
|
labels: LabelExpression::None,
|
|
235
241
|
properties: None,
|
|
242
|
+
predicate: None,
|
|
236
243
|
},
|
|
237
244
|
destination: NodePattern {
|
|
238
245
|
variable: Some(var_ids.create_variable_from_name("n")),
|
|
239
246
|
labels: LabelExpression::None,
|
|
240
247
|
properties: None,
|
|
248
|
+
predicate: None,
|
|
241
249
|
},
|
|
242
250
|
labels: LabelExpression::None,
|
|
243
251
|
properties: None,
|
|
244
252
|
directivity: graphcore::EdgeDirectivity::Directed,
|
|
245
|
-
|
|
253
|
+
|
|
254
|
+
predicate: None,
|
|
246
255
|
})],
|
|
247
256
|
where_expression: None,
|
|
248
257
|
optional: false,
|
|
@@ -263,6 +272,8 @@ pub(crate) fn optional_match() -> Statements
|
|
|
263
272
|
variable: Some(var_ids.create_variable_from_name("a")),
|
|
264
273
|
labels: LabelExpression::None,
|
|
265
274
|
properties: None,
|
|
275
|
+
|
|
276
|
+
predicate: None,
|
|
266
277
|
})],
|
|
267
278
|
where_expression: None,
|
|
268
279
|
optional: true,
|
|
@@ -283,6 +294,8 @@ pub(crate) fn match_count() -> Statements
|
|
|
283
294
|
variable: Some(var_ids.create_variable_from_name("a")),
|
|
284
295
|
labels: LabelExpression::None,
|
|
285
296
|
properties: None,
|
|
297
|
+
|
|
298
|
+
predicate: None,
|
|
286
299
|
})],
|
|
287
300
|
where_expression: None,
|
|
288
301
|
optional: false,
|
|
@@ -322,6 +335,8 @@ pub(crate) fn aggregation() -> Statements
|
|
|
322
335
|
variable: Some(var_ids.create_variable_from_name("n")),
|
|
323
336
|
labels: LabelExpression::None,
|
|
324
337
|
properties: None,
|
|
338
|
+
|
|
339
|
+
predicate: None,
|
|
325
340
|
})],
|
|
326
341
|
where_expression: None,
|
|
327
342
|
optional: false,
|
|
@@ -400,6 +415,8 @@ pub(crate) fn match_with_vector_search(index_name: &str) -> Statements
|
|
|
400
415
|
variable: Some(n.clone()),
|
|
401
416
|
labels: LabelExpression::String("Doc".to_string()),
|
|
402
417
|
properties: None,
|
|
418
|
+
|
|
419
|
+
predicate: None,
|
|
403
420
|
})],
|
|
404
421
|
where_expression: None,
|
|
405
422
|
optional: false,
|
|
@@ -440,3 +457,269 @@ pub(crate) fn match_with_vector_search(index_name: &str) -> Statements
|
|
|
440
457
|
.into(),
|
|
441
458
|
]
|
|
442
459
|
}
|
|
460
|
+
|
|
461
|
+
/// AST for `MATCH (a) ((n)-[:R]->(m)){1,3} (b) RETURN a, b`
|
|
462
|
+
/// AST for `MATCH (a) ((n)-[:R]->(m)){1,3} (b) RETURN a, b`
|
|
463
|
+
pub(crate) fn group_single_edge_range() -> Statements
|
|
464
|
+
{
|
|
465
|
+
let var_ids = VariableIdentifiers::default();
|
|
466
|
+
let a = var_ids.create_variable_from_name("a");
|
|
467
|
+
let n = var_ids.create_variable_from_name("n");
|
|
468
|
+
let m = var_ids.create_variable_from_name("m");
|
|
469
|
+
let b = var_ids.create_variable_from_name("b");
|
|
470
|
+
let edge_anon = var_ids.create_variable_from_name("anonymous_4");
|
|
471
|
+
vec![
|
|
472
|
+
Match {
|
|
473
|
+
patterns: vec![Pattern::QuantifiedPath(QuantifiedPathPattern {
|
|
474
|
+
variable: None,
|
|
475
|
+
source: NodePattern {
|
|
476
|
+
variable: Some(a.clone()),
|
|
477
|
+
labels: LabelExpression::None,
|
|
478
|
+
properties: None,
|
|
479
|
+
predicate: None,
|
|
480
|
+
},
|
|
481
|
+
group: vec![Pattern::Edge(EdgePattern {
|
|
482
|
+
variable: Some(edge_anon),
|
|
483
|
+
source: NodePattern {
|
|
484
|
+
variable: Some(n),
|
|
485
|
+
labels: LabelExpression::None,
|
|
486
|
+
properties: None,
|
|
487
|
+
predicate: None,
|
|
488
|
+
},
|
|
489
|
+
destination: NodePattern {
|
|
490
|
+
variable: Some(m),
|
|
491
|
+
labels: LabelExpression::None,
|
|
492
|
+
properties: None,
|
|
493
|
+
predicate: None,
|
|
494
|
+
},
|
|
495
|
+
directivity: graphcore::EdgeDirectivity::Directed,
|
|
496
|
+
labels: LabelExpression::String("R".to_string()),
|
|
497
|
+
properties: None,
|
|
498
|
+
predicate: None,
|
|
499
|
+
})],
|
|
500
|
+
group_where: None,
|
|
501
|
+
path_where: None,
|
|
502
|
+
quantifier: Some(1..3),
|
|
503
|
+
destination: NodePattern {
|
|
504
|
+
variable: Some(b.clone()),
|
|
505
|
+
labels: LabelExpression::None,
|
|
506
|
+
properties: None,
|
|
507
|
+
predicate: None,
|
|
508
|
+
},
|
|
509
|
+
selector: PathSelector::All,
|
|
510
|
+
})],
|
|
511
|
+
where_expression: None,
|
|
512
|
+
optional: false,
|
|
513
|
+
search: None,
|
|
514
|
+
}
|
|
515
|
+
.into(),
|
|
516
|
+
Return {
|
|
517
|
+
all: false,
|
|
518
|
+
expressions: vec![
|
|
519
|
+
NamedExpression {
|
|
520
|
+
identifier: a.clone(),
|
|
521
|
+
expression: Variable { identifier: a }.into(),
|
|
522
|
+
},
|
|
523
|
+
NamedExpression {
|
|
524
|
+
identifier: b.clone(),
|
|
525
|
+
expression: Variable { identifier: b }.into(),
|
|
526
|
+
},
|
|
527
|
+
],
|
|
528
|
+
modifiers: Modifiers {
|
|
529
|
+
distinct: false,
|
|
530
|
+
skip: None,
|
|
531
|
+
limit: None,
|
|
532
|
+
order_by: None,
|
|
533
|
+
},
|
|
534
|
+
where_expression: None,
|
|
535
|
+
}
|
|
536
|
+
.into(),
|
|
537
|
+
]
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/// AST for `MATCH (a) ((n)-[:R1]->(x)-[:R2]->(m)){1,3} (b) RETURN a, b`
|
|
541
|
+
pub(crate) fn group_two_edges_range() -> Statements
|
|
542
|
+
{
|
|
543
|
+
let var_ids = VariableIdentifiers::default();
|
|
544
|
+
let a = var_ids.create_variable_from_name("a");
|
|
545
|
+
let n = var_ids.create_variable_from_name("n");
|
|
546
|
+
let x = var_ids.create_variable_from_name("x");
|
|
547
|
+
let m = var_ids.create_variable_from_name("m");
|
|
548
|
+
let b = var_ids.create_variable_from_name("b");
|
|
549
|
+
let edge1_anon = var_ids.create_variable_from_name("anonymous_5");
|
|
550
|
+
let edge2_anon = var_ids.create_variable_from_name("anonymous_6");
|
|
551
|
+
vec![
|
|
552
|
+
Match {
|
|
553
|
+
patterns: vec![Pattern::QuantifiedPath(QuantifiedPathPattern {
|
|
554
|
+
variable: None,
|
|
555
|
+
source: NodePattern {
|
|
556
|
+
variable: Some(a.clone()),
|
|
557
|
+
labels: LabelExpression::None,
|
|
558
|
+
properties: None,
|
|
559
|
+
predicate: None,
|
|
560
|
+
},
|
|
561
|
+
group: vec![
|
|
562
|
+
Pattern::Edge(EdgePattern {
|
|
563
|
+
variable: Some(edge1_anon),
|
|
564
|
+
source: NodePattern {
|
|
565
|
+
variable: Some(n),
|
|
566
|
+
labels: LabelExpression::None,
|
|
567
|
+
properties: None,
|
|
568
|
+
predicate: None,
|
|
569
|
+
},
|
|
570
|
+
destination: NodePattern {
|
|
571
|
+
variable: Some(x.clone()),
|
|
572
|
+
labels: LabelExpression::None,
|
|
573
|
+
properties: None,
|
|
574
|
+
predicate: None,
|
|
575
|
+
},
|
|
576
|
+
directivity: graphcore::EdgeDirectivity::Directed,
|
|
577
|
+
labels: LabelExpression::String("R1".to_string()),
|
|
578
|
+
properties: None,
|
|
579
|
+
predicate: None,
|
|
580
|
+
}),
|
|
581
|
+
Pattern::Edge(EdgePattern {
|
|
582
|
+
variable: Some(edge2_anon),
|
|
583
|
+
source: NodePattern {
|
|
584
|
+
variable: Some(x),
|
|
585
|
+
labels: LabelExpression::None,
|
|
586
|
+
properties: None,
|
|
587
|
+
predicate: None,
|
|
588
|
+
},
|
|
589
|
+
destination: NodePattern {
|
|
590
|
+
variable: Some(m),
|
|
591
|
+
labels: LabelExpression::None,
|
|
592
|
+
properties: None,
|
|
593
|
+
predicate: None,
|
|
594
|
+
},
|
|
595
|
+
directivity: graphcore::EdgeDirectivity::Directed,
|
|
596
|
+
labels: LabelExpression::String("R2".to_string()),
|
|
597
|
+
properties: None,
|
|
598
|
+
predicate: None,
|
|
599
|
+
}),
|
|
600
|
+
],
|
|
601
|
+
group_where: None,
|
|
602
|
+
path_where: None,
|
|
603
|
+
quantifier: Some(1..3),
|
|
604
|
+
destination: NodePattern {
|
|
605
|
+
variable: Some(b.clone()),
|
|
606
|
+
labels: LabelExpression::None,
|
|
607
|
+
properties: None,
|
|
608
|
+
predicate: None,
|
|
609
|
+
},
|
|
610
|
+
selector: PathSelector::All,
|
|
611
|
+
})],
|
|
612
|
+
where_expression: None,
|
|
613
|
+
optional: false,
|
|
614
|
+
search: None,
|
|
615
|
+
}
|
|
616
|
+
.into(),
|
|
617
|
+
Return {
|
|
618
|
+
all: false,
|
|
619
|
+
expressions: vec![
|
|
620
|
+
NamedExpression {
|
|
621
|
+
identifier: a.clone(),
|
|
622
|
+
expression: Variable { identifier: a }.into(),
|
|
623
|
+
},
|
|
624
|
+
NamedExpression {
|
|
625
|
+
identifier: b.clone(),
|
|
626
|
+
expression: Variable { identifier: b }.into(),
|
|
627
|
+
},
|
|
628
|
+
],
|
|
629
|
+
modifiers: Modifiers {
|
|
630
|
+
distinct: false,
|
|
631
|
+
skip: None,
|
|
632
|
+
limit: None,
|
|
633
|
+
order_by: None,
|
|
634
|
+
},
|
|
635
|
+
where_expression: None,
|
|
636
|
+
}
|
|
637
|
+
.into(),
|
|
638
|
+
]
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/// AST for `MATCH p = SHORTEST 1 (a)-[:R]-+(b) RETURN a, b, length(p)`
|
|
642
|
+
pub(crate) fn shortest_single_edge_full_return() -> Statements
|
|
643
|
+
{
|
|
644
|
+
let var_ids = VariableIdentifiers::default();
|
|
645
|
+
let a = var_ids.create_variable_from_name("a");
|
|
646
|
+
let b = var_ids.create_variable_from_name("b");
|
|
647
|
+
let edge_anon = var_ids.create_variable_from_name("anonymous_2");
|
|
648
|
+
let p = var_ids.create_variable_from_name("p");
|
|
649
|
+
vec![
|
|
650
|
+
Match {
|
|
651
|
+
patterns: vec![Pattern::QuantifiedPath(QuantifiedPathPattern {
|
|
652
|
+
variable: Some(p.clone()),
|
|
653
|
+
source: NodePattern {
|
|
654
|
+
variable: Some(a.clone()),
|
|
655
|
+
labels: LabelExpression::None,
|
|
656
|
+
properties: None,
|
|
657
|
+
predicate: None,
|
|
658
|
+
},
|
|
659
|
+
group: vec![Pattern::Edge(EdgePattern {
|
|
660
|
+
variable: Some(edge_anon),
|
|
661
|
+
source: NodePattern {
|
|
662
|
+
variable: Some(a.clone()),
|
|
663
|
+
labels: LabelExpression::None,
|
|
664
|
+
properties: None,
|
|
665
|
+
predicate: None,
|
|
666
|
+
},
|
|
667
|
+
destination: NodePattern {
|
|
668
|
+
variable: Some(b.clone()),
|
|
669
|
+
labels: LabelExpression::None,
|
|
670
|
+
properties: None,
|
|
671
|
+
predicate: None,
|
|
672
|
+
},
|
|
673
|
+
directivity: graphcore::EdgeDirectivity::Undirected,
|
|
674
|
+
labels: LabelExpression::String("R".to_string()),
|
|
675
|
+
properties: None,
|
|
676
|
+
predicate: None,
|
|
677
|
+
})],
|
|
678
|
+
group_where: None,
|
|
679
|
+
path_where: None,
|
|
680
|
+
quantifier: Some(1..usize::MAX),
|
|
681
|
+
destination: NodePattern {
|
|
682
|
+
variable: Some(b.clone()),
|
|
683
|
+
labels: LabelExpression::None,
|
|
684
|
+
properties: None,
|
|
685
|
+
predicate: None,
|
|
686
|
+
},
|
|
687
|
+
selector: PathSelector::Shortest(Value { value: 1.into() }.into()),
|
|
688
|
+
})],
|
|
689
|
+
where_expression: None,
|
|
690
|
+
optional: false,
|
|
691
|
+
search: None,
|
|
692
|
+
}
|
|
693
|
+
.into(),
|
|
694
|
+
Return {
|
|
695
|
+
all: false,
|
|
696
|
+
expressions: vec![
|
|
697
|
+
NamedExpression {
|
|
698
|
+
identifier: a.clone(),
|
|
699
|
+
expression: Variable { identifier: a }.into(),
|
|
700
|
+
},
|
|
701
|
+
NamedExpression {
|
|
702
|
+
identifier: b.clone(),
|
|
703
|
+
expression: Variable { identifier: b }.into(),
|
|
704
|
+
},
|
|
705
|
+
NamedExpression {
|
|
706
|
+
identifier: var_ids.create_variable_from_name("length(p)"),
|
|
707
|
+
expression: FunctionCall {
|
|
708
|
+
name: "length".into(),
|
|
709
|
+
arguments: vec![Variable { identifier: p }.into()],
|
|
710
|
+
distinct: false,
|
|
711
|
+
}
|
|
712
|
+
.into(),
|
|
713
|
+
},
|
|
714
|
+
],
|
|
715
|
+
modifiers: Modifiers {
|
|
716
|
+
distinct: false,
|
|
717
|
+
skip: None,
|
|
718
|
+
limit: None,
|
|
719
|
+
order_by: None,
|
|
720
|
+
},
|
|
721
|
+
where_expression: None,
|
|
722
|
+
}
|
|
723
|
+
.into(),
|
|
724
|
+
]
|
|
725
|
+
}
|
|
@@ -472,3 +472,309 @@ pub(crate) fn aggregation(function_manager: &functions::Manager) -> Program
|
|
|
472
472
|
},
|
|
473
473
|
]
|
|
474
474
|
}
|
|
475
|
+
|
|
476
|
+
/// Program for `MATCH (a) ((n)-[:R]->(m)){1,3} (b) RETURN a, b`.
|
|
477
|
+
/// Uses MatchQuantifiedPath since the group's inner nodes (n, m) differ
|
|
478
|
+
/// from the outer anchors (a, b) - this is an explicit group pattern.
|
|
479
|
+
pub(crate) fn group_single_edge_range() -> Program
|
|
480
|
+
{
|
|
481
|
+
vec![
|
|
482
|
+
Block::Match {
|
|
483
|
+
blocks: vec![BlockMatch::MatchQuantifiedPath {
|
|
484
|
+
source_instructions: vec![
|
|
485
|
+
Instruction::Push {
|
|
486
|
+
value: ValueMap::default().into(),
|
|
487
|
+
},
|
|
488
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
489
|
+
],
|
|
490
|
+
source_variable: Some(0),
|
|
491
|
+
source_filter: vec![],
|
|
492
|
+
destination_variable: Some(1),
|
|
493
|
+
destination_filter: vec![],
|
|
494
|
+
path_variable: None,
|
|
495
|
+
quantifier: 1..3,
|
|
496
|
+
group_instructions: vec![BlockMatch::MatchEdge {
|
|
497
|
+
instructions: vec![
|
|
498
|
+
Instruction::GetVariable { col_id: 2 },
|
|
499
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
500
|
+
Instruction::Push {
|
|
501
|
+
value: ValueMap::default().into(),
|
|
502
|
+
},
|
|
503
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
504
|
+
Instruction::Push {
|
|
505
|
+
value: ValueMap::default().into(),
|
|
506
|
+
},
|
|
507
|
+
Instruction::CreateEdgeQuery {
|
|
508
|
+
labels: vec!["R".into()],
|
|
509
|
+
},
|
|
510
|
+
],
|
|
511
|
+
left_variable: None,
|
|
512
|
+
edge_variable: Some(4),
|
|
513
|
+
right_variable: Some(3),
|
|
514
|
+
path_variable: None,
|
|
515
|
+
filter: vec![],
|
|
516
|
+
directivity: EdgeDirectivity::Directed,
|
|
517
|
+
recursive_range: None,
|
|
518
|
+
}],
|
|
519
|
+
group_variables: vec![2, 4, 3],
|
|
520
|
+
group_terminal_variable: 3,
|
|
521
|
+
group_entry_variable: 2,
|
|
522
|
+
group_where_filter: None,
|
|
523
|
+
path_filter: None,
|
|
524
|
+
strategy: PathStrategy::Dfs,
|
|
525
|
+
}],
|
|
526
|
+
filter: vec![],
|
|
527
|
+
optional: false,
|
|
528
|
+
variables_size: create_variable_size(5, 0),
|
|
529
|
+
},
|
|
530
|
+
Block::Return {
|
|
531
|
+
variables: vec![
|
|
532
|
+
(
|
|
533
|
+
"a".into(),
|
|
534
|
+
RWExpression {
|
|
535
|
+
col_id: 0,
|
|
536
|
+
instructions: vec![Instruction::GetVariable { col_id: 0 }],
|
|
537
|
+
aggregations: Default::default(),
|
|
538
|
+
},
|
|
539
|
+
),
|
|
540
|
+
(
|
|
541
|
+
"b".into(),
|
|
542
|
+
RWExpression {
|
|
543
|
+
col_id: 1,
|
|
544
|
+
instructions: vec![Instruction::GetVariable { col_id: 1 }],
|
|
545
|
+
aggregations: Default::default(),
|
|
546
|
+
},
|
|
547
|
+
),
|
|
548
|
+
],
|
|
549
|
+
filter: vec![],
|
|
550
|
+
modifiers: Modifiers {
|
|
551
|
+
limit: None,
|
|
552
|
+
skip: None,
|
|
553
|
+
order_by: vec![],
|
|
554
|
+
distinct: false,
|
|
555
|
+
},
|
|
556
|
+
variables_sizes: create_variable_size(5, 0),
|
|
557
|
+
},
|
|
558
|
+
]
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/// Program for `MATCH (a) ((n)-[:R1]->(x)-[:R2]->(m)){1,3} (b) RETURN a, b`.
|
|
562
|
+
/// Two-edge group: compiler allocates edge columns (5, 6) for deduplication,
|
|
563
|
+
/// and adds filter logic to second edge to prevent revisiting the same edge.
|
|
564
|
+
pub(crate) fn group_two_edges_range() -> Program
|
|
565
|
+
{
|
|
566
|
+
vec![
|
|
567
|
+
Block::Match {
|
|
568
|
+
blocks: vec![BlockMatch::MatchQuantifiedPath {
|
|
569
|
+
source_instructions: vec![
|
|
570
|
+
Instruction::Push {
|
|
571
|
+
value: ValueMap::default().into(),
|
|
572
|
+
},
|
|
573
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
574
|
+
],
|
|
575
|
+
source_variable: Some(0),
|
|
576
|
+
source_filter: vec![],
|
|
577
|
+
destination_variable: Some(1),
|
|
578
|
+
destination_filter: vec![],
|
|
579
|
+
path_variable: None,
|
|
580
|
+
quantifier: 1..3,
|
|
581
|
+
group_instructions: vec![
|
|
582
|
+
BlockMatch::MatchEdge {
|
|
583
|
+
instructions: vec![
|
|
584
|
+
Instruction::GetVariable { col_id: 2 },
|
|
585
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
586
|
+
Instruction::Push {
|
|
587
|
+
value: ValueMap::default().into(),
|
|
588
|
+
},
|
|
589
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
590
|
+
Instruction::Push {
|
|
591
|
+
value: ValueMap::default().into(),
|
|
592
|
+
},
|
|
593
|
+
Instruction::CreateEdgeQuery {
|
|
594
|
+
labels: vec!["R1".into()],
|
|
595
|
+
},
|
|
596
|
+
],
|
|
597
|
+
left_variable: None,
|
|
598
|
+
edge_variable: Some(4),
|
|
599
|
+
right_variable: Some(3),
|
|
600
|
+
path_variable: None,
|
|
601
|
+
filter: vec![],
|
|
602
|
+
directivity: EdgeDirectivity::Directed,
|
|
603
|
+
recursive_range: None,
|
|
604
|
+
},
|
|
605
|
+
BlockMatch::MatchEdge {
|
|
606
|
+
instructions: vec![
|
|
607
|
+
Instruction::GetVariable { col_id: 3 },
|
|
608
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
609
|
+
Instruction::Push {
|
|
610
|
+
value: ValueMap::default().into(),
|
|
611
|
+
},
|
|
612
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
613
|
+
Instruction::Push {
|
|
614
|
+
value: ValueMap::default().into(),
|
|
615
|
+
},
|
|
616
|
+
Instruction::CreateEdgeQuery {
|
|
617
|
+
labels: vec!["R2".into()],
|
|
618
|
+
},
|
|
619
|
+
],
|
|
620
|
+
left_variable: None,
|
|
621
|
+
edge_variable: Some(6),
|
|
622
|
+
right_variable: Some(5),
|
|
623
|
+
path_variable: None,
|
|
624
|
+
filter: vec![
|
|
625
|
+
Instruction::Duplicate,
|
|
626
|
+
Instruction::GetVariable { col_id: 4 },
|
|
627
|
+
Instruction::NotEqualBinaryOperator,
|
|
628
|
+
Instruction::InverseRot3,
|
|
629
|
+
Instruction::AndBinaryOperator,
|
|
630
|
+
Instruction::Swap,
|
|
631
|
+
],
|
|
632
|
+
directivity: EdgeDirectivity::Directed,
|
|
633
|
+
recursive_range: None,
|
|
634
|
+
},
|
|
635
|
+
],
|
|
636
|
+
group_variables: vec![2, 4, 3, 3, 6, 5],
|
|
637
|
+
group_terminal_variable: 5,
|
|
638
|
+
group_entry_variable: 2,
|
|
639
|
+
group_where_filter: None,
|
|
640
|
+
path_filter: None,
|
|
641
|
+
strategy: PathStrategy::Dfs,
|
|
642
|
+
}],
|
|
643
|
+
filter: vec![],
|
|
644
|
+
optional: false,
|
|
645
|
+
variables_size: create_variable_size(7, 0),
|
|
646
|
+
},
|
|
647
|
+
Block::Return {
|
|
648
|
+
variables: vec![
|
|
649
|
+
(
|
|
650
|
+
"a".into(),
|
|
651
|
+
RWExpression {
|
|
652
|
+
col_id: 0,
|
|
653
|
+
instructions: vec![Instruction::GetVariable { col_id: 0 }],
|
|
654
|
+
aggregations: Default::default(),
|
|
655
|
+
},
|
|
656
|
+
),
|
|
657
|
+
(
|
|
658
|
+
"b".into(),
|
|
659
|
+
RWExpression {
|
|
660
|
+
col_id: 1,
|
|
661
|
+
instructions: vec![Instruction::GetVariable { col_id: 1 }],
|
|
662
|
+
aggregations: Default::default(),
|
|
663
|
+
},
|
|
664
|
+
),
|
|
665
|
+
],
|
|
666
|
+
filter: vec![],
|
|
667
|
+
modifiers: Modifiers {
|
|
668
|
+
limit: None,
|
|
669
|
+
skip: None,
|
|
670
|
+
order_by: vec![],
|
|
671
|
+
distinct: false,
|
|
672
|
+
},
|
|
673
|
+
variables_sizes: create_variable_size(7, 0),
|
|
674
|
+
},
|
|
675
|
+
]
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/// Program for `MATCH p = SHORTEST 1 (a)-[:R]-+(b) RETURN a, b, length(p)`
|
|
679
|
+
/// Shortest path uses BFS with stop condition. **KEY FINDING**: group_variables
|
|
680
|
+
/// DOES include source/destination columns [1, 2] - this was the open question
|
|
681
|
+
/// in WI721.
|
|
682
|
+
pub(crate) fn shortest_single_edge_full_return(function_manager: &functions::Manager) -> Program
|
|
683
|
+
{
|
|
684
|
+
vec![
|
|
685
|
+
Block::Match {
|
|
686
|
+
blocks: vec![BlockMatch::MatchQuantifiedPath {
|
|
687
|
+
source_instructions: vec![
|
|
688
|
+
Instruction::Push {
|
|
689
|
+
value: ValueMap::default().into(),
|
|
690
|
+
},
|
|
691
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
692
|
+
],
|
|
693
|
+
source_variable: Some(1),
|
|
694
|
+
source_filter: vec![],
|
|
695
|
+
destination_variable: Some(2),
|
|
696
|
+
destination_filter: vec![],
|
|
697
|
+
path_variable: Some(0),
|
|
698
|
+
quantifier: 1..usize::MAX,
|
|
699
|
+
group_instructions: vec![BlockMatch::MatchEdge {
|
|
700
|
+
instructions: vec![
|
|
701
|
+
Instruction::GetVariable { col_id: 1 },
|
|
702
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
703
|
+
Instruction::Push {
|
|
704
|
+
value: ValueMap::default().into(),
|
|
705
|
+
},
|
|
706
|
+
Instruction::CreateNodeQuery { labels: vec![] },
|
|
707
|
+
Instruction::Push {
|
|
708
|
+
value: ValueMap::default().into(),
|
|
709
|
+
},
|
|
710
|
+
Instruction::CreateEdgeQuery {
|
|
711
|
+
labels: vec!["R".into()],
|
|
712
|
+
},
|
|
713
|
+
],
|
|
714
|
+
left_variable: None,
|
|
715
|
+
edge_variable: Some(3),
|
|
716
|
+
right_variable: Some(2),
|
|
717
|
+
path_variable: None,
|
|
718
|
+
filter: vec![],
|
|
719
|
+
directivity: EdgeDirectivity::Undirected,
|
|
720
|
+
recursive_range: None,
|
|
721
|
+
}],
|
|
722
|
+
group_variables: vec![1, 3, 2],
|
|
723
|
+
group_terminal_variable: 2,
|
|
724
|
+
group_entry_variable: 1,
|
|
725
|
+
group_where_filter: None,
|
|
726
|
+
path_filter: None,
|
|
727
|
+
strategy: PathStrategy::Bfs {
|
|
728
|
+
stop_condition: StopCondition::Shortest(vec![Instruction::Push { value: 1.into() }]),
|
|
729
|
+
},
|
|
730
|
+
}],
|
|
731
|
+
filter: vec![],
|
|
732
|
+
optional: false,
|
|
733
|
+
variables_size: create_variable_size(4, 0),
|
|
734
|
+
},
|
|
735
|
+
Block::Return {
|
|
736
|
+
variables: vec![
|
|
737
|
+
(
|
|
738
|
+
"a".into(),
|
|
739
|
+
RWExpression {
|
|
740
|
+
col_id: 1,
|
|
741
|
+
instructions: vec![Instruction::GetVariable { col_id: 1 }],
|
|
742
|
+
aggregations: Default::default(),
|
|
743
|
+
},
|
|
744
|
+
),
|
|
745
|
+
(
|
|
746
|
+
"b".into(),
|
|
747
|
+
RWExpression {
|
|
748
|
+
col_id: 2,
|
|
749
|
+
instructions: vec![Instruction::GetVariable { col_id: 2 }],
|
|
750
|
+
aggregations: Default::default(),
|
|
751
|
+
},
|
|
752
|
+
),
|
|
753
|
+
(
|
|
754
|
+
"length(p)".into(),
|
|
755
|
+
RWExpression {
|
|
756
|
+
col_id: 4,
|
|
757
|
+
instructions: vec![
|
|
758
|
+
Instruction::GetVariable { col_id: 0 },
|
|
759
|
+
Instruction::FunctionCall {
|
|
760
|
+
function: function_manager
|
|
761
|
+
.get_function::<error::CompileTimeError>("length")
|
|
762
|
+
.unwrap(),
|
|
763
|
+
arguments_count: 1,
|
|
764
|
+
},
|
|
765
|
+
],
|
|
766
|
+
aggregations: Default::default(),
|
|
767
|
+
},
|
|
768
|
+
),
|
|
769
|
+
],
|
|
770
|
+
filter: vec![],
|
|
771
|
+
modifiers: Modifiers {
|
|
772
|
+
limit: None,
|
|
773
|
+
skip: None,
|
|
774
|
+
order_by: vec![],
|
|
775
|
+
distinct: false,
|
|
776
|
+
},
|
|
777
|
+
variables_sizes: create_variable_size(5, 0),
|
|
778
|
+
},
|
|
779
|
+
]
|
|
780
|
+
}
|