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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c6ebd6bd26d6614d8d3edd02d592c4bfd125a5dc3bf8170cb69c3f7e22dd48a7
|
|
4
|
+
data.tar.gz: 1c9f08c8d98976a104166ddc321e23a81e3a66d36fa16c97dcff0aa81adc735f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b524bcae9534be01d0d7b5ba78430058c736314c2f57770ca5774edb888b9192653fa23f1664bd62833c27745b29004dc1d78d280c769def4819e54ba5ff8a41
|
|
7
|
+
data.tar.gz: 73f5e717c9e6dc74c19389c939a2c5933c16b4a47da74756fab937e4ece53922e8fe25c8b4979a1d60e6be0d5a7c2701b4747bc5ff803789fa54b3b56132874e
|
data/ext/Cargo.toml
CHANGED
|
@@ -3,26 +3,26 @@ resolver = "3"
|
|
|
3
3
|
members = ["gqliterb", "gqlitedb", "graphcore"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.
|
|
6
|
+
version = "0.13.0"
|
|
7
7
|
edition = "2024"
|
|
8
8
|
license = "MIT"
|
|
9
9
|
homepage = "https://gqlite.org"
|
|
10
10
|
repository = "https://gitlab.com/gqlite/gqlite"
|
|
11
11
|
|
|
12
12
|
[workspace.dependencies]
|
|
13
|
-
graphcore = { version = "0.
|
|
14
|
-
gqlitedb = { version = "0.
|
|
15
|
-
gqlparser = { version = "0.
|
|
16
|
-
db-index = { version = "0.
|
|
13
|
+
graphcore = { version = "0.13.0", path = "graphcore" }
|
|
14
|
+
gqlitedb = { version = "0.13.0", path = "gqlitedb" }
|
|
15
|
+
gqlparser = { version = "0.13.0", path = "gqlparser" }
|
|
16
|
+
db-index = { version = "0.13.0", path = "db-index" }
|
|
17
17
|
|
|
18
|
-
askama = { version = "0.
|
|
18
|
+
askama = { version = "0.16" }
|
|
19
19
|
ccutils = { version = "0.4" }
|
|
20
20
|
ciborium = "0.2"
|
|
21
21
|
divan = "0.1"
|
|
22
22
|
indexmap = "2"
|
|
23
|
-
itertools = "0.
|
|
23
|
+
itertools = "0.15"
|
|
24
24
|
log = "0.4"
|
|
25
|
-
rusqlite = { version = "0.
|
|
25
|
+
rusqlite = { version = "0.40", features = ["load_extension"] }
|
|
26
26
|
serde = "1"
|
|
27
27
|
thiserror = "2"
|
|
28
28
|
uuid = { version = "1", features = ["v4"] }
|
data/ext/gqlitedb/Cargo.toml
CHANGED
|
@@ -38,8 +38,6 @@ db-index = { workspace = true, optional = true }
|
|
|
38
38
|
indexmap = { version = "2", features = ["serde"] }
|
|
39
39
|
itertools = { workspace = true }
|
|
40
40
|
log = { workspace = true }
|
|
41
|
-
pest = "2"
|
|
42
|
-
pest_derive = "2"
|
|
43
41
|
pgrx = { version = "0.18", optional = true }
|
|
44
42
|
postgres = { version = "0.19", optional = true, features = [
|
|
45
43
|
"with-uuid-1",
|
|
@@ -2,7 +2,10 @@ use std::collections::HashMap;
|
|
|
2
2
|
|
|
3
3
|
use gqlparser::oc::ast;
|
|
4
4
|
|
|
5
|
-
use crate::{
|
|
5
|
+
use crate::{
|
|
6
|
+
planner::{self, LogicalPlan},
|
|
7
|
+
prelude::*,
|
|
8
|
+
};
|
|
6
9
|
|
|
7
10
|
use compiler::expression_analyser::{self, ExpressionType};
|
|
8
11
|
|
|
@@ -72,14 +75,17 @@ impl Variable
|
|
|
72
75
|
variable: None,
|
|
73
76
|
labels: ast::LabelExpression::None,
|
|
74
77
|
properties: None,
|
|
78
|
+
predicate: None,
|
|
75
79
|
},
|
|
76
80
|
destination: ast::NodePattern {
|
|
77
81
|
variable: None,
|
|
78
82
|
labels: ast::LabelExpression::None,
|
|
79
83
|
properties: None,
|
|
84
|
+
predicate: None,
|
|
80
85
|
},
|
|
81
86
|
directivity: graphcore::EdgeDirectivity::Directed,
|
|
82
|
-
|
|
87
|
+
|
|
88
|
+
predicate: None,
|
|
83
89
|
}),
|
|
84
90
|
variable_type: ExpressionType::Edge,
|
|
85
91
|
col_id,
|
|
@@ -90,6 +96,8 @@ impl Variable
|
|
|
90
96
|
variable: None,
|
|
91
97
|
labels: ast::LabelExpression::None,
|
|
92
98
|
properties: None,
|
|
99
|
+
|
|
100
|
+
predicate: None,
|
|
93
101
|
}),
|
|
94
102
|
variable_type: ExpressionType::Node,
|
|
95
103
|
col_id,
|
|
@@ -484,23 +492,101 @@ impl VariablesManager
|
|
|
484
492
|
Ok(())
|
|
485
493
|
}
|
|
486
494
|
|
|
487
|
-
fn analyse_pattern(&mut self, pattern: &
|
|
495
|
+
fn analyse_pattern(&mut self, pattern: &planner::PlannedPattern, is_create: bool) -> Result<()>
|
|
488
496
|
{
|
|
489
497
|
match pattern
|
|
490
498
|
{
|
|
491
|
-
|
|
499
|
+
planner::PlannedPattern::Node(node) =>
|
|
492
500
|
{
|
|
493
501
|
self.validate_node(node)?;
|
|
494
502
|
}
|
|
495
|
-
|
|
503
|
+
planner::PlannedPattern::Edge(edge) =>
|
|
496
504
|
{
|
|
497
505
|
self.analyse_edge_path(None, edge, is_create)?;
|
|
498
506
|
}
|
|
499
|
-
|
|
507
|
+
planner::PlannedPattern::Path(path) =>
|
|
500
508
|
{
|
|
501
509
|
self.analyse_edge_path(None, &path.edge, is_create)?;
|
|
502
510
|
self.declare_variable(&path.variable, ExpressionType::Path)?;
|
|
503
511
|
}
|
|
512
|
+
planner::PlannedPattern::QuantifiedPath { pattern: qp, .. } =>
|
|
513
|
+
{
|
|
514
|
+
if qp.group.len() != 1
|
|
515
|
+
{
|
|
516
|
+
// Multi-element groups: declare path variable and outer anchors
|
|
517
|
+
if let Some(path_variable) = &qp.variable
|
|
518
|
+
{
|
|
519
|
+
self.declare_variable(path_variable, ExpressionType::Path)?;
|
|
520
|
+
}
|
|
521
|
+
if !self.is_valid_existing_node(&qp.source)?
|
|
522
|
+
{
|
|
523
|
+
self.validate_node(&qp.source)?;
|
|
524
|
+
}
|
|
525
|
+
if !self.is_valid_existing_node(&qp.destination)?
|
|
526
|
+
{
|
|
527
|
+
self.validate_node(&qp.destination)?;
|
|
528
|
+
}
|
|
529
|
+
// Multi-element groups: analyze all patterns in the group
|
|
530
|
+
for pattern in &qp.group
|
|
531
|
+
{
|
|
532
|
+
match pattern
|
|
533
|
+
{
|
|
534
|
+
ast::Pattern::Node(node) =>
|
|
535
|
+
{
|
|
536
|
+
self.validate_node(node)?;
|
|
537
|
+
}
|
|
538
|
+
ast::Pattern::Edge(edge) =>
|
|
539
|
+
{
|
|
540
|
+
self.validate_edge(edge)?;
|
|
541
|
+
}
|
|
542
|
+
ast::Pattern::Path(path) =>
|
|
543
|
+
{
|
|
544
|
+
self.declare_variable(&path.variable, ExpressionType::Path)?;
|
|
545
|
+
self.validate_edge(&path.edge)?;
|
|
546
|
+
}
|
|
547
|
+
ast::Pattern::QuantifiedPath(_) =>
|
|
548
|
+
{
|
|
549
|
+
return Err(InternalError::Unimplemented("nested quantified path patterns").into());
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
else
|
|
555
|
+
{
|
|
556
|
+
if let Some(edge) = super::as_plain_quantifier(qp)
|
|
557
|
+
{
|
|
558
|
+
self.analyse_edge_path(qp.variable.clone(), edge, is_create)?;
|
|
559
|
+
}
|
|
560
|
+
else
|
|
561
|
+
{
|
|
562
|
+
// Explicit group: outer anchors differ from inner nodes
|
|
563
|
+
// Need to declare the outer anchors
|
|
564
|
+
if let Some(path_variable) = &qp.variable
|
|
565
|
+
{
|
|
566
|
+
self.declare_variable(path_variable, ExpressionType::Path)?;
|
|
567
|
+
}
|
|
568
|
+
if !self.is_valid_existing_node(&qp.source)?
|
|
569
|
+
{
|
|
570
|
+
self.validate_node(&qp.source)?;
|
|
571
|
+
}
|
|
572
|
+
if !self.is_valid_existing_node(&qp.destination)?
|
|
573
|
+
{
|
|
574
|
+
self.validate_node(&qp.destination)?;
|
|
575
|
+
}
|
|
576
|
+
// Validate every inner edge, not just the first - group.len() may be
|
|
577
|
+
// > 1 for multi-element groups (e.g. ((n)-[r1]->(x)-[r2]->(m))), and
|
|
578
|
+
// only checking group[0] would silently skip every subsequent edge's
|
|
579
|
+
// label/property/predicate constraints.
|
|
580
|
+
for pattern in &qp.group
|
|
581
|
+
{
|
|
582
|
+
if let ast::Pattern::Edge(edge) = pattern
|
|
583
|
+
{
|
|
584
|
+
self.validate_edge(edge)?;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
}
|
|
504
590
|
}
|
|
505
591
|
Ok(())
|
|
506
592
|
}
|
|
@@ -573,7 +659,7 @@ impl VariablesManager
|
|
|
573
659
|
{
|
|
574
660
|
for pattern in patterns.iter()
|
|
575
661
|
{
|
|
576
|
-
if let
|
|
662
|
+
if let planner::PlannedPattern::Node(n) = pattern
|
|
577
663
|
&& self.has_variable(&n.variable)
|
|
578
664
|
{
|
|
579
665
|
return Err(
|
|
@@ -617,7 +703,7 @@ impl VariablesManager
|
|
|
617
703
|
{
|
|
618
704
|
match pattern
|
|
619
705
|
{
|
|
620
|
-
|
|
706
|
+
planner::PlannedPattern::Node(n) =>
|
|
621
707
|
{
|
|
622
708
|
if self.has_variable(&n.variable)
|
|
623
709
|
{
|
|
@@ -629,7 +715,7 @@ impl VariablesManager
|
|
|
629
715
|
);
|
|
630
716
|
}
|
|
631
717
|
}
|
|
632
|
-
|
|
718
|
+
planner::PlannedPattern::Edge(e) =>
|
|
633
719
|
{
|
|
634
720
|
if self.has_variable(&e.variable)
|
|
635
721
|
{
|
|
@@ -641,7 +727,7 @@ impl VariablesManager
|
|
|
641
727
|
);
|
|
642
728
|
}
|
|
643
729
|
}
|
|
644
|
-
|
|
730
|
+
planner::PlannedPattern::Path(p) =>
|
|
645
731
|
{
|
|
646
732
|
if self.has_variable(&Some(p.variable.clone()))
|
|
647
733
|
{
|
|
@@ -653,6 +739,19 @@ impl VariablesManager
|
|
|
653
739
|
);
|
|
654
740
|
}
|
|
655
741
|
}
|
|
742
|
+
planner::PlannedPattern::QuantifiedPath { pattern: qp, .. } =>
|
|
743
|
+
{
|
|
744
|
+
if let Some(var) = &qp.variable
|
|
745
|
+
&& self.has_variable(&Some(var.clone()))
|
|
746
|
+
{
|
|
747
|
+
return Err(
|
|
748
|
+
CompileTimeError::VariableAlreadyBound {
|
|
749
|
+
name: var.name().clone(),
|
|
750
|
+
}
|
|
751
|
+
.into(),
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
656
755
|
}
|
|
657
756
|
self.analyse_pattern(pattern, false)?;
|
|
658
757
|
}
|