gqlite 1.1.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.
- checksums.yaml +4 -4
- data/ext/gqliterb/.cargo/config.toml +2 -0
- data/ext/gqliterb/Cargo.lock +1109 -0
- data/ext/gqliterb/Cargo.toml +43 -0
- data/ext/gqliterb/extconf.rb +4 -0
- data/ext/gqliterb/src/lib.rs +260 -0
- data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2060 -0
- data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +132 -0
- data/ext/gqliterb/vendor/gqlitedb/askama.toml +3 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/common/mod.rs +25 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/common/pokec.rs +185 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/pokec_divan.rs +137 -0
- data/ext/gqliterb/vendor/gqlitedb/benches/pokec_iai.rs +122 -0
- data/ext/gqliterb/vendor/gqlitedb/release.toml +7 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/arithmetic.rs +96 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/containers.rs +33 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/count.rs +35 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators/stats.rs +168 -0
- data/ext/gqliterb/vendor/gqlitedb/src/aggregators.rs +74 -0
- data/ext/gqliterb/vendor/gqlitedb/src/capi.rs +236 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +427 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +620 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1106 -0
- data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +208 -0
- data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
- data/ext/gqliterb/vendor/gqlitedb/src/error.rs +621 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/containers.rs +115 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/edge.rs +20 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/math.rs +44 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/node.rs +16 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +48 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/scalar.rs +86 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/string.rs +28 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions/value.rs +99 -0
- data/ext/gqliterb/vendor/gqlitedb/src/functions.rs +412 -0
- data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +268 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1788 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +262 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
- data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +42 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +625 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +191 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1153 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +4 -0
- data/ext/gqliterb/vendor/gqlitedb/src/prelude.rs +8 -0
- data/ext/gqliterb/vendor/gqlitedb/src/serialize_with.rs +94 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/pgql.rs +121 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/redb.rs +1250 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +994 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store.rs +432 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/compiler.rs +92 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/evaluators.rs +227 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/parser.rs +81 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store/redb.rs +39 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +39 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +462 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/ast.rs +356 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/templates/programs.rs +455 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/templates.rs +2 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests.rs +39 -0
- data/ext/gqliterb/vendor/gqlitedb/src/utils.rs +28 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value/compare.rs +212 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value/contains.rs +47 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value/value_map.rs +298 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value.rs +559 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +616 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/call_stats.sql +22 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_count_for_node.sql +3 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_create.sql +6 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_delete_by_nodes.sql +2 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_select.sql +139 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/edge_update.sql +4 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_create.sql +16 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/graph_delete.sql +3 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_create_table.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_get.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/metadata_set.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_create.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_delete.sql +1 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_select.sql +42 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/node_update.sql +4 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/table_exists.sql +5 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_from_1_01.sql +2 -0
- data/ext/gqliterb/vendor/gqlitedb/templates/sql/sqlite/upgrade_graph_from_1_01.sql +65 -0
- data/lib/gqlite.rb +1 -75
- metadata +118 -25
- data/ext/gqlite/extconf.rb +0 -21
- data/ext/gqlite/gqlite-amalgamate.cpp +0 -9599
- data/ext/gqlite/gqlite-c.h +0 -95
- data/ext/gqlite/gqlite.h +0 -141
@@ -0,0 +1,115 @@
|
|
1
|
+
use super::{ExpressionType, FResult, FunctionTypeTrait};
|
2
|
+
use crate::prelude::*;
|
3
|
+
|
4
|
+
#[derive(Debug, Default)]
|
5
|
+
pub(super) struct Head {}
|
6
|
+
|
7
|
+
impl Head
|
8
|
+
{
|
9
|
+
fn call_impl(array: &Vec<value::Value>) -> FResult<value::Value>
|
10
|
+
{
|
11
|
+
Ok(
|
12
|
+
array
|
13
|
+
.first()
|
14
|
+
.map(|x| x.to_owned())
|
15
|
+
.unwrap_or(value::Value::Null),
|
16
|
+
)
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
super::declare_function!(
|
21
|
+
head,
|
22
|
+
Head,
|
23
|
+
call_impl(Vec<crate::value::Value>) -> crate::value::Value,
|
24
|
+
accept_null
|
25
|
+
);
|
26
|
+
|
27
|
+
#[derive(Debug, Default)]
|
28
|
+
pub(super) struct Keys {}
|
29
|
+
|
30
|
+
impl Keys
|
31
|
+
{
|
32
|
+
fn call_impl(container: &value::Value) -> Result<Vec<value::Value>>
|
33
|
+
{
|
34
|
+
match container
|
35
|
+
{
|
36
|
+
value::Value::Map(obj) => Ok(obj.keys().map(|x| x.to_owned().into()).collect()),
|
37
|
+
value::Value::Node(n) => Ok(n.properties.keys().map(|x| x.to_owned().into()).collect()),
|
38
|
+
value::Value::Edge(e) => Ok(e.properties.keys().map(|x| x.to_owned().into()).collect()),
|
39
|
+
_ =>
|
40
|
+
{
|
41
|
+
return Err(
|
42
|
+
RunTimeError::InvalidArgument {
|
43
|
+
function_name: "keys",
|
44
|
+
index: 0,
|
45
|
+
expected_type: "map, node or relationship",
|
46
|
+
value: format!("{:?}", container),
|
47
|
+
}
|
48
|
+
.into(),
|
49
|
+
)
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
super::declare_function!(keys, Keys, call_impl(crate::value::Value) -> Vec<crate::value::Value>, validate_args(ExpressionType::Map | ExpressionType::Node | ExpressionType::Edge | ExpressionType::Null));
|
56
|
+
|
57
|
+
#[derive(Debug, Default)]
|
58
|
+
pub(super) struct Range {}
|
59
|
+
|
60
|
+
impl Range
|
61
|
+
{
|
62
|
+
fn call_impl(min: &i64, max: &i64) -> FResult<Vec<i64>>
|
63
|
+
{
|
64
|
+
Ok((*min..=*max).step_by(1).collect())
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
super::declare_function!(range, Range, call_impl(i64, i64) -> Vec<i64>);
|
69
|
+
|
70
|
+
#[derive(Debug, Default)]
|
71
|
+
pub(super) struct Size {}
|
72
|
+
|
73
|
+
impl super::FunctionTrait for Size
|
74
|
+
{
|
75
|
+
fn call(&self, arguments: Vec<value::Value>) -> Result<value::Value>
|
76
|
+
{
|
77
|
+
let container = arguments
|
78
|
+
.first()
|
79
|
+
.ok_or_else(|| RunTimeError::InvalidNumberOfArguments {
|
80
|
+
function_name: "size",
|
81
|
+
got: arguments.len(),
|
82
|
+
expected: 1,
|
83
|
+
})?;
|
84
|
+
|
85
|
+
match container
|
86
|
+
{
|
87
|
+
value::Value::Null => Ok(value::Value::Null),
|
88
|
+
value::Value::Array(arr) => Ok((arr.len() as i64).into()),
|
89
|
+
value::Value::Map(obj) => Ok((obj.len() as i64).into()),
|
90
|
+
value::Value::Path(..) => Ok(1.into()),
|
91
|
+
_ =>
|
92
|
+
{
|
93
|
+
return Err(
|
94
|
+
RunTimeError::InvalidArgument {
|
95
|
+
function_name: "size",
|
96
|
+
index: 0,
|
97
|
+
expected_type: "array or map",
|
98
|
+
value: format!("{:?}", container),
|
99
|
+
}
|
100
|
+
.into(),
|
101
|
+
)
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
fn validate_arguments(&self, _: Vec<ExpressionType>) -> Result<ExpressionType>
|
106
|
+
{
|
107
|
+
Ok(ExpressionType::Variant)
|
108
|
+
}
|
109
|
+
fn is_deterministic(&self) -> bool
|
110
|
+
{
|
111
|
+
true
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
super::declare_function!(size, Size, custom_trait);
|
@@ -0,0 +1,20 @@
|
|
1
|
+
use crate::prelude::*;
|
2
|
+
|
3
|
+
use super::{FResult, FunctionTypeTrait};
|
4
|
+
|
5
|
+
#[derive(Debug, Default)]
|
6
|
+
pub(super) struct Type {}
|
7
|
+
|
8
|
+
impl Type
|
9
|
+
{
|
10
|
+
fn call_impl(edge: &graph::Edge) -> FResult<String>
|
11
|
+
{
|
12
|
+
edge
|
13
|
+
.labels
|
14
|
+
.first()
|
15
|
+
.ok_or_else(|| RunTimeError::MissingEdgeLabel)
|
16
|
+
.map(|v| v.to_owned())
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
super::declare_function!(type, Type, call_impl(crate::graph::Edge) -> String);
|
@@ -0,0 +1,44 @@
|
|
1
|
+
use rand::Rng;
|
2
|
+
|
3
|
+
use crate::prelude::*;
|
4
|
+
|
5
|
+
use super::{FResult, FunctionTypeTrait};
|
6
|
+
|
7
|
+
#[derive(Debug, Default)]
|
8
|
+
pub(super) struct Rand {}
|
9
|
+
|
10
|
+
impl Rand
|
11
|
+
{
|
12
|
+
fn call_impl() -> FResult<f64>
|
13
|
+
{
|
14
|
+
Ok(rand::rng().random())
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
super::declare_function!(rand, Rand, call_impl() -> Vec<f64>);
|
19
|
+
|
20
|
+
#[derive(Debug, Default)]
|
21
|
+
pub(super) struct Ceil {}
|
22
|
+
|
23
|
+
impl Ceil
|
24
|
+
{
|
25
|
+
fn call_impl(value: &f64) -> FResult<f64>
|
26
|
+
{
|
27
|
+
Ok(value.ceil() as f64)
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
super::declare_function!(ceil, Ceil, call_impl(f64) -> f64);
|
32
|
+
|
33
|
+
#[derive(Debug, Default)]
|
34
|
+
pub(super) struct Floor {}
|
35
|
+
|
36
|
+
impl Floor
|
37
|
+
{
|
38
|
+
fn call_impl(value: &f64) -> FResult<f64>
|
39
|
+
{
|
40
|
+
Ok(value.floor() as f64)
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
super::declare_function!(floor, Floor, call_impl(f64) -> f64);
|
@@ -0,0 +1,16 @@
|
|
1
|
+
use crate::prelude::*;
|
2
|
+
|
3
|
+
use super::{FResult, FunctionTypeTrait};
|
4
|
+
|
5
|
+
#[derive(Debug, Default)]
|
6
|
+
pub(super) struct Labels {}
|
7
|
+
|
8
|
+
impl Labels
|
9
|
+
{
|
10
|
+
fn call_impl(node: &graph::Node) -> FResult<Vec<String>>
|
11
|
+
{
|
12
|
+
Ok(node.labels.to_owned())
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
super::declare_function!(labels, Labels, call_impl(crate::graph::Node) -> Vec<String>);
|
@@ -0,0 +1,48 @@
|
|
1
|
+
use super::ExpressionType;
|
2
|
+
use crate::prelude::*;
|
3
|
+
|
4
|
+
#[derive(Debug, Default)]
|
5
|
+
pub(super) struct Length {}
|
6
|
+
|
7
|
+
impl super::FunctionTrait for Length
|
8
|
+
{
|
9
|
+
fn call(&self, arguments: Vec<value::Value>) -> crate::Result<value::Value>
|
10
|
+
{
|
11
|
+
let container = arguments
|
12
|
+
.first()
|
13
|
+
.ok_or_else(|| RunTimeError::InvalidNumberOfArguments {
|
14
|
+
function_name: "length",
|
15
|
+
got: arguments.len(),
|
16
|
+
expected: 1,
|
17
|
+
})?;
|
18
|
+
|
19
|
+
match container
|
20
|
+
{
|
21
|
+
value::Value::Array(arr) => Ok((arr.len() as i64).into()),
|
22
|
+
value::Value::Map(obj) => Ok((obj.len() as i64).into()),
|
23
|
+
value::Value::Path(..) => Ok(1.into()),
|
24
|
+
_ =>
|
25
|
+
{
|
26
|
+
return Err(
|
27
|
+
RunTimeError::InvalidArgument {
|
28
|
+
function_name: "length",
|
29
|
+
index: 0,
|
30
|
+
expected_type: "array or map",
|
31
|
+
value: format!("{:?}", container),
|
32
|
+
}
|
33
|
+
.into(),
|
34
|
+
)
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
fn validate_arguments(&self, _: Vec<ExpressionType>) -> crate::Result<ExpressionType>
|
39
|
+
{
|
40
|
+
Ok(ExpressionType::Variant)
|
41
|
+
}
|
42
|
+
fn is_deterministic(&self) -> bool
|
43
|
+
{
|
44
|
+
true
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
super::declare_function!(length, Length, custom_trait);
|
@@ -0,0 +1,86 @@
|
|
1
|
+
use crate::prelude::*;
|
2
|
+
|
3
|
+
use super::{ExpressionType, FResult, FunctionTypeTrait};
|
4
|
+
|
5
|
+
#[derive(Debug, Default)]
|
6
|
+
pub(super) struct Coalesce {}
|
7
|
+
|
8
|
+
impl super::FunctionTrait for Coalesce
|
9
|
+
{
|
10
|
+
fn call(&self, arguments: Vec<value::Value>) -> crate::Result<value::Value>
|
11
|
+
{
|
12
|
+
for arg in arguments
|
13
|
+
{
|
14
|
+
match arg
|
15
|
+
{
|
16
|
+
value::Value::Null =>
|
17
|
+
{}
|
18
|
+
other => return Ok(other),
|
19
|
+
}
|
20
|
+
}
|
21
|
+
Ok(value::Value::Null)
|
22
|
+
}
|
23
|
+
fn validate_arguments(&self, _: Vec<ExpressionType>) -> crate::Result<ExpressionType>
|
24
|
+
{
|
25
|
+
Ok(ExpressionType::Variant)
|
26
|
+
}
|
27
|
+
fn is_deterministic(&self) -> bool
|
28
|
+
{
|
29
|
+
true
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
super::declare_function!(coalesce, Coalesce, custom_trait);
|
34
|
+
|
35
|
+
#[derive(Debug, Default)]
|
36
|
+
pub(super) struct ToInteger {}
|
37
|
+
|
38
|
+
impl ToInteger
|
39
|
+
{
|
40
|
+
fn call_impl(value: &value::Value) -> FResult<i64>
|
41
|
+
{
|
42
|
+
match value
|
43
|
+
{
|
44
|
+
value::Value::Integer(i) => Ok(*i),
|
45
|
+
value::Value::Float(f) => Ok(*f as i64),
|
46
|
+
value::Value::String(s) => Ok(s.parse().map_err(|_| RunTimeError::InvalidArgument {
|
47
|
+
function_name: "toInteger",
|
48
|
+
index: 0,
|
49
|
+
expected_type: "A string convertible to integer",
|
50
|
+
value: format!("{:?}", value),
|
51
|
+
})?),
|
52
|
+
_ => Err(RunTimeError::InvalidArgument {
|
53
|
+
function_name: "toInteger",
|
54
|
+
index: 0,
|
55
|
+
expected_type: "integer, float, or string",
|
56
|
+
value: format!("{:?}", value),
|
57
|
+
}),
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
super::declare_function!(toInteger, ToInteger, call_impl(crate::value::Value) -> i64);
|
63
|
+
|
64
|
+
#[derive(Debug, Default)]
|
65
|
+
pub(super) struct Properties {}
|
66
|
+
|
67
|
+
impl Properties
|
68
|
+
{
|
69
|
+
fn call_impl(value: &value::Value) -> FResult<value::ValueMap>
|
70
|
+
{
|
71
|
+
match value
|
72
|
+
{
|
73
|
+
value::Value::Node(n) => Ok(n.properties.to_owned()),
|
74
|
+
value::Value::Edge(e) => Ok(e.properties.to_owned()),
|
75
|
+
value::Value::Map(m) => Ok(m.to_owned()),
|
76
|
+
_ => Err(RunTimeError::InvalidArgument {
|
77
|
+
function_name: "properties",
|
78
|
+
index: 0,
|
79
|
+
expected_type: "node or relationship",
|
80
|
+
value: format!("{:?}", value),
|
81
|
+
}),
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
super::declare_function!(properties, Properties, call_impl(crate::value::Value) -> value::ValueMap, validate_args(ExpressionType::Map | ExpressionType::Node | ExpressionType::Edge | ExpressionType::Null));
|
@@ -0,0 +1,28 @@
|
|
1
|
+
use crate::prelude::*;
|
2
|
+
|
3
|
+
use super::{ExpressionType, FResult, FunctionTypeTrait};
|
4
|
+
|
5
|
+
#[derive(Debug, Default)]
|
6
|
+
pub(super) struct ToString {}
|
7
|
+
|
8
|
+
impl ToString
|
9
|
+
{
|
10
|
+
fn call_impl(value: &value::Value) -> FResult<String>
|
11
|
+
{
|
12
|
+
match value
|
13
|
+
{
|
14
|
+
value::Value::Boolean(b) => Ok(if *b { "true" } else { "false" }.into()),
|
15
|
+
value::Value::Integer(i) => Ok(i.to_string()),
|
16
|
+
value::Value::Float(f) => Ok(f.to_string()),
|
17
|
+
value::Value::String(s) => Ok(s.to_owned()),
|
18
|
+
_ => Err(RunTimeError::InvalidArgument {
|
19
|
+
function_name: "toString",
|
20
|
+
index: 0,
|
21
|
+
expected_type: "boolean or integer or double",
|
22
|
+
value: format!("{:?}", value),
|
23
|
+
}),
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
super::declare_function!(toString, ToString, call_impl(crate::value::Value) -> String, validate_args(ExpressionType::Boolean | ExpressionType::Integer | ExpressionType::Float | ExpressionType::String | ExpressionType::Null));
|
@@ -0,0 +1,99 @@
|
|
1
|
+
use crate::prelude::*;
|
2
|
+
|
3
|
+
use super::{ExpressionType, FResult, FunctionTypeTrait};
|
4
|
+
|
5
|
+
#[derive(Debug, Default)]
|
6
|
+
pub(super) struct HasLabel {}
|
7
|
+
|
8
|
+
impl HasLabel
|
9
|
+
{
|
10
|
+
fn call_impl(value: &value::Value, label: &String) -> FResult<bool>
|
11
|
+
{
|
12
|
+
match value
|
13
|
+
{
|
14
|
+
value::Value::Edge(e) => Ok(e.labels.contains(label)),
|
15
|
+
value::Value::Node(n) => Ok(n.labels.contains(label)),
|
16
|
+
_ => Err(RunTimeError::InvalidArgument {
|
17
|
+
function_name: "has_label",
|
18
|
+
index: 0,
|
19
|
+
expected_type: "node or edege",
|
20
|
+
value: format!("{:?}", value),
|
21
|
+
}),
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
super::declare_function!(has_label, HasLabel, call_impl(crate::graph::Edge, String) -> bool);
|
27
|
+
|
28
|
+
#[derive(Debug, Default)]
|
29
|
+
pub(super) struct HasLabels {}
|
30
|
+
|
31
|
+
impl super::FunctionTrait for HasLabels
|
32
|
+
{
|
33
|
+
fn call(&self, arguments: Vec<value::Value>) -> crate::Result<value::Value>
|
34
|
+
{
|
35
|
+
if arguments.len() < 2
|
36
|
+
{
|
37
|
+
Err(
|
38
|
+
RunTimeError::InvalidNumberOfArguments {
|
39
|
+
function_name: "has_labels",
|
40
|
+
got: arguments.len(),
|
41
|
+
expected: 2,
|
42
|
+
}
|
43
|
+
.into(),
|
44
|
+
)
|
45
|
+
}
|
46
|
+
else
|
47
|
+
{
|
48
|
+
let mut it = arguments.into_iter();
|
49
|
+
let labels = match it.next().unwrap()
|
50
|
+
{
|
51
|
+
value::Value::Edge(e) => e.labels,
|
52
|
+
value::Value::Node(n) => n.labels,
|
53
|
+
value::Value::Null => return Ok(value::Value::Null),
|
54
|
+
_ => Err(RunTimeError::InvalidArgument {
|
55
|
+
function_name: "has_labels",
|
56
|
+
index: 0,
|
57
|
+
expected_type: "node or edge",
|
58
|
+
value: format!("{:?}", it),
|
59
|
+
})?,
|
60
|
+
};
|
61
|
+
for (index, label) in it.enumerate()
|
62
|
+
{
|
63
|
+
match label
|
64
|
+
{
|
65
|
+
value::Value::String(l) =>
|
66
|
+
{
|
67
|
+
if !labels.contains(&l)
|
68
|
+
{
|
69
|
+
return Ok(false.into());
|
70
|
+
}
|
71
|
+
}
|
72
|
+
_ =>
|
73
|
+
{
|
74
|
+
return Err(
|
75
|
+
RunTimeError::InvalidArgument {
|
76
|
+
function_name: "has_labels",
|
77
|
+
index,
|
78
|
+
expected_type: "string",
|
79
|
+
value: format!("{:?}", label),
|
80
|
+
}
|
81
|
+
.into(),
|
82
|
+
)
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
Ok(true.into())
|
87
|
+
}
|
88
|
+
}
|
89
|
+
fn validate_arguments(&self, _: Vec<ExpressionType>) -> crate::Result<ExpressionType>
|
90
|
+
{
|
91
|
+
Ok(ExpressionType::Boolean)
|
92
|
+
}
|
93
|
+
fn is_deterministic(&self) -> bool
|
94
|
+
{
|
95
|
+
true
|
96
|
+
}
|
97
|
+
}
|
98
|
+
|
99
|
+
super::declare_function!(has_labels, HasLabels, custom_trait);
|