gqlite 1.5.0 → 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.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +12 -6
  3. data/ext/db-index/Cargo.toml +29 -0
  4. data/ext/db-index/src/hnsw/error.rs +66 -0
  5. data/ext/db-index/src/hnsw/graph_store.rs +272 -0
  6. data/ext/db-index/src/hnsw/id.rs +36 -0
  7. data/ext/db-index/src/hnsw/implementation.rs +1517 -0
  8. data/ext/db-index/src/hnsw/kernels.rs +1228 -0
  9. data/ext/db-index/src/hnsw/metric.rs +244 -0
  10. data/ext/db-index/src/hnsw/scalar.rs +72 -0
  11. data/ext/db-index/src/hnsw/simple_store.rs +140 -0
  12. data/ext/db-index/src/hnsw/store.rs +472 -0
  13. data/ext/db-index/src/hnsw/vector.rs +105 -0
  14. data/ext/db-index/src/hnsw/vectors.rs +568 -0
  15. data/ext/db-index/src/hnsw.rs +42 -0
  16. data/ext/db-index/src/lib.rs +3 -0
  17. data/ext/gqlitedb/Cargo.toml +19 -8
  18. data/ext/gqlitedb/benches/common/pokec.rs +62 -2
  19. data/ext/gqlitedb/benches/pokec_divan.rs +66 -2
  20. data/ext/gqlitedb/benches/pokec_iai.rs +60 -3
  21. data/ext/gqlitedb/release.toml +2 -2
  22. data/ext/gqlitedb/src/aggregators/arithmetic.rs +3 -1
  23. data/ext/gqlitedb/src/aggregators/containers.rs +1 -1
  24. data/ext/gqlitedb/src/aggregators/stats.rs +21 -12
  25. data/ext/gqlitedb/src/capi.rs +20 -24
  26. data/ext/gqlitedb/src/compiler/expression_analyser.rs +28 -20
  27. data/ext/gqlitedb/src/compiler/variables_manager.rs +104 -38
  28. data/ext/gqlitedb/src/compiler.rs +506 -227
  29. data/ext/gqlitedb/src/connection.rs +151 -11
  30. data/ext/gqlitedb/src/consts.rs +1 -2
  31. data/ext/gqlitedb/src/error.rs +123 -61
  32. data/ext/gqlitedb/src/functions/common.rs +64 -0
  33. data/ext/gqlitedb/src/functions/containers.rs +2 -46
  34. data/ext/gqlitedb/src/functions/edge.rs +1 -1
  35. data/ext/gqlitedb/src/functions/math.rs +87 -15
  36. data/ext/gqlitedb/src/functions/node.rs +1 -1
  37. data/ext/gqlitedb/src/functions/path.rs +48 -11
  38. data/ext/gqlitedb/src/functions/scalar.rs +47 -4
  39. data/ext/gqlitedb/src/functions/string.rs +123 -1
  40. data/ext/gqlitedb/src/functions/value.rs +1 -1
  41. data/ext/gqlitedb/src/functions.rs +165 -28
  42. data/ext/gqlitedb/src/graph.rs +1 -9
  43. data/ext/gqlitedb/src/interpreter/evaluators.rs +968 -130
  44. data/ext/gqlitedb/src/interpreter/instructions.rs +39 -2
  45. data/ext/gqlitedb/src/lib.rs +5 -4
  46. data/ext/gqlitedb/src/parser/gql.pest +1 -1
  47. data/ext/gqlitedb/src/planner.rs +329 -0
  48. data/ext/gqlitedb/src/prelude.rs +3 -3
  49. data/ext/gqlitedb/src/store/pgrx.rs +1 -1
  50. data/ext/gqlitedb/src/store/postgres.rs +742 -16
  51. data/ext/gqlitedb/src/store/redb/hnsw_store.rs +702 -0
  52. data/ext/gqlitedb/src/store/redb/index.rs +274 -0
  53. data/ext/gqlitedb/src/store/redb.rs +1268 -113
  54. data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +28 -0
  55. data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +103 -0
  56. data/ext/gqlitedb/src/store/sqlbase.rs +146 -16
  57. data/ext/gqlitedb/src/store/sqlite.rs +576 -14
  58. data/ext/gqlitedb/src/store/vector_extract.rs +56 -0
  59. data/ext/gqlitedb/src/store.rs +140 -29
  60. data/ext/gqlitedb/src/tests/compiler.rs +207 -10
  61. data/ext/gqlitedb/src/tests/connection/postgres.rs +38 -3
  62. data/ext/gqlitedb/src/tests/connection/redb.rs +23 -0
  63. data/ext/gqlitedb/src/tests/connection/sqlite.rs +31 -0
  64. data/ext/gqlitedb/src/tests/connection.rs +61 -1
  65. data/ext/gqlitedb/src/tests/evaluators.rs +162 -7
  66. data/ext/gqlitedb/src/tests/parser.rs +54 -23
  67. data/ext/gqlitedb/src/tests/planner.rs +511 -0
  68. data/ext/gqlitedb/src/tests/store/postgres.rs +7 -0
  69. data/ext/gqlitedb/src/tests/store/redb.rs +8 -0
  70. data/ext/gqlitedb/src/tests/store/sqlite.rs +8 -0
  71. data/ext/gqlitedb/src/tests/store/vector_index/postgres.rs +182 -0
  72. data/ext/gqlitedb/src/tests/store/vector_index/redb.rs +386 -0
  73. data/ext/gqlitedb/src/tests/store/vector_index/sqlite.rs +166 -0
  74. data/ext/gqlitedb/src/tests/store/vector_index.rs +2313 -0
  75. data/ext/gqlitedb/src/tests/store.rs +78 -14
  76. data/ext/gqlitedb/src/tests/templates/ast.rs +92 -16
  77. data/ext/gqlitedb/src/tests/templates/programs.rs +14 -7
  78. data/ext/gqlitedb/src/tests.rs +15 -9
  79. data/ext/gqlitedb/src/utils.rs +6 -1
  80. data/ext/gqlitedb/src/value/compare.rs +61 -3
  81. data/ext/gqlitedb/src/value.rs +136 -7
  82. data/ext/gqlitedb/templates/sql/postgres/metadata_delete.sql +1 -0
  83. data/ext/gqlitedb/templates/sql/postgres/node_select.sql +1 -1
  84. data/ext/gqlitedb/templates/sql/sqlite/metadata_delete.sql +1 -0
  85. data/ext/gqliterb/src/lib.rs +53 -8
  86. data/ext/gqlparser/Cargo.toml +25 -0
  87. data/ext/gqlparser/README.MD +9 -0
  88. data/ext/gqlparser/benches/pokec_divan.rs +34 -0
  89. data/ext/gqlparser/src/common.rs +69 -0
  90. data/ext/gqlparser/src/gqls/ast.rs +69 -0
  91. data/ext/gqlparser/src/gqls/constraint.rs +79 -0
  92. data/ext/gqlparser/src/gqls/error.rs +22 -0
  93. data/ext/gqlparser/src/gqls/parser.rs +813 -0
  94. data/ext/gqlparser/src/gqls/prelude.rs +8 -0
  95. data/ext/gqlparser/src/gqls/properties.rs +115 -0
  96. data/ext/gqlparser/src/gqls/resolve.rs +207 -0
  97. data/ext/gqlparser/src/gqls.rs +265 -0
  98. data/ext/gqlparser/src/lib.rs +7 -0
  99. data/ext/gqlparser/src/oc/ast.rs +680 -0
  100. data/ext/gqlparser/src/oc/error.rs +172 -0
  101. data/ext/gqlparser/src/oc/lexer.rs +429 -0
  102. data/ext/gqlparser/src/oc/parser/tests.rs +2284 -0
  103. data/ext/gqlparser/src/oc/parser.rs +2005 -0
  104. data/ext/gqlparser/src/oc.rs +33 -0
  105. data/ext/gqlparser/src/prelude.rs +3 -0
  106. data/ext/graphcore/Cargo.toml +1 -0
  107. data/ext/graphcore/src/error.rs +26 -0
  108. data/ext/graphcore/src/graph.rs +177 -51
  109. data/ext/graphcore/src/lib.rs +4 -2
  110. data/ext/graphcore/src/open_cypher.rs +12 -0
  111. data/ext/graphcore/src/table.rs +50 -2
  112. data/ext/graphcore/src/timestamp.rs +127 -104
  113. data/ext/graphcore/src/value/tensor.rs +739 -0
  114. data/ext/graphcore/src/value/value_map.rs +1 -1
  115. data/ext/graphcore/src/value.rs +343 -19
  116. metadata +93 -28
  117. data/ext/gqlitedb/src/parser/ast.rs +0 -604
  118. data/ext/gqlitedb/src/parser/parser_impl.rs +0 -1213
  119. data/ext/gqlitedb/src/parser.rs +0 -4
@@ -1,9 +1,42 @@
1
- use rand::Rng;
1
+ use rand::RngExt;
2
2
 
3
3
  use crate::prelude::*;
4
4
 
5
5
  use super::FResult;
6
6
 
7
+ trait Extra
8
+ {
9
+ fn cot(self) -> Self;
10
+ }
11
+
12
+ impl Extra for f64
13
+ {
14
+ fn cot(self) -> Self
15
+ {
16
+ self.cos() / self.sin()
17
+ }
18
+ }
19
+
20
+ macro_rules! declare_constant {
21
+ ($name: ident, $class_name: ident, $rust_const: ident) => {
22
+ #[derive(Debug, Default)]
23
+ pub(super) struct $class_name {}
24
+
25
+ impl $class_name
26
+ {
27
+ fn call_impl() -> FResult<f64>
28
+ {
29
+ Ok(std::f64::consts::$rust_const)
30
+ }
31
+ }
32
+
33
+ super::declare_function!($name, $class_name, call_impl() -> f64);
34
+ };
35
+ }
36
+
37
+ declare_constant!(pi, Pi, PI);
38
+ declare_constant!(e, E, E);
39
+
7
40
  #[derive(Debug, Default)]
8
41
  pub(super) struct Rand {}
9
42
 
@@ -15,30 +48,69 @@ impl Rand
15
48
  }
16
49
  }
17
50
 
18
- super::declare_function!(rand, Rand, call_impl() -> Vec<f64>);
51
+ super::declare_function!(rand, Rand, call_impl() -> Vec<f64>, non_deterministic);
52
+
53
+ macro_rules! define_f64_function {
54
+ ($name: ident, $class_name: ident, $rust_func: ident $(, $arg0: expr)*) => {
55
+ #[derive(Debug, Default)]
56
+ pub(super) struct $class_name {}
57
+
58
+ impl $class_name
59
+ {
60
+ fn call_impl(value: f64) -> FResult<f64>
61
+ {
62
+ Ok(value.$rust_func($($arg0)*))
63
+ }
64
+ }
65
+
66
+ super::declare_function!($name, $class_name, call_impl(f64) -> f64);
67
+
68
+ };
69
+ ($name: ident, $class_name: ident) => {
70
+ define_f64_function!($name, $class_name, $name);
71
+ };
72
+ }
73
+
74
+ define_f64_function!(exp, Exp);
75
+ define_f64_function!(log, Log, ln);
76
+ define_f64_function!(log10, Log10, log10);
77
+ define_f64_function!(sin, Sin);
78
+ define_f64_function!(cos, Cos);
79
+ define_f64_function!(tan, Tan);
80
+ define_f64_function!(cot, Cot, cot);
81
+ define_f64_function!(acos, Acos);
82
+ define_f64_function!(asin, Asin);
83
+ define_f64_function!(atan, Atan);
84
+ define_f64_function!(floor, Floor);
85
+ define_f64_function!(ceil, Ceil);
86
+ define_f64_function!(degrees, Degrees, to_degrees);
87
+ define_f64_function!(radians, Radians, to_radians);
19
88
 
20
89
  #[derive(Debug, Default)]
21
- pub(super) struct Ceil {}
90
+ pub(super) struct Atan2 {}
22
91
 
23
- impl Ceil
92
+ impl Atan2
24
93
  {
25
- fn call_impl(value: f64) -> FResult<f64>
94
+ fn call_impl(x: f64, y: f64) -> FResult<f64>
26
95
  {
27
- Ok(value.ceil())
96
+ Ok(x.atan2(y))
28
97
  }
29
98
  }
30
99
 
31
- super::declare_function!(ceil, Ceil, call_impl(f64) -> f64);
32
-
33
- #[derive(Debug, Default)]
34
- pub(super) struct Floor {}
100
+ super::declare_function!(atan2, Atan2, call_impl(f64, f64) -> f64);
35
101
 
36
- impl Floor
102
+ #[cfg(test)]
103
+ mod test
37
104
  {
38
- fn call_impl(value: f64) -> FResult<f64>
105
+ use crate::functions::math::{Extra as _, Rand};
106
+ #[test]
107
+ fn test_cot()
39
108
  {
40
- Ok(value.floor())
109
+ assert_eq!(0.5_f64.cot(), 1.830487721712452);
110
+ }
111
+ #[test]
112
+ fn test_rand()
113
+ {
114
+ assert!(!Rand::create().1.is_deterministic());
41
115
  }
42
116
  }
43
-
44
- super::declare_function!(floor, Floor, call_impl(f64) -> f64);
@@ -13,4 +13,4 @@ impl Labels
13
13
  }
14
14
  }
15
15
 
16
- super::declare_function!(labels, Labels, call_impl(crate::graph::Node) -> Vec<String>);
16
+ super::declare_function!(labels, Labels, call_impl(crate::graph::Node) -> Vec<String>, null_handling(null_returns_null));
@@ -20,7 +20,8 @@ impl super::FunctionTrait for Length
20
20
  {
21
21
  value::Value::Array(arr) => Ok((arr.len() as i64).into()),
22
22
  value::Value::Map(obj) => Ok((obj.len() as i64).into()),
23
- value::Value::Path(..) => Ok(1.into()),
23
+ value::Value::SinglePath(_) => Ok((1_i64).into()),
24
+ value::Value::Path(path) => Ok((path.elements_count() as i64).into()),
24
25
  _ => Err(
25
26
  RunTimeError::InvalidArgument {
26
27
  function_name: "length",
@@ -49,27 +50,63 @@ pub(super) struct Nodes {}
49
50
 
50
51
  impl Nodes
51
52
  {
52
- fn call_impl(path: graph::Path) -> FResult<Vec<graph::Node>>
53
+ fn call_impl(path: value::Value) -> FResult<Vec<graph::Node>>
53
54
  {
54
- Ok(vec![path.source().clone(), path.destination().clone()])
55
+ match path
56
+ {
57
+ value::Value::SinglePath(p) =>
58
+ {
59
+ let (node, _, destination) = p.unpack();
60
+ Ok(vec![node, destination])
61
+ }
62
+ value::Value::Path(p) =>
63
+ {
64
+ let (source, elements) = p.unpack();
65
+ Ok(
66
+ std::iter::once(source)
67
+ .chain(elements.into_iter().map(|(_, node)| node))
68
+ .collect(),
69
+ )
70
+ }
71
+ o => Err(RunTimeError::InvalidArgument {
72
+ function_name: "nodes",
73
+ index: 0,
74
+ expected_type: "path",
75
+ value: format!("{:?}", o),
76
+ }),
77
+ }
55
78
  }
56
79
  }
57
80
 
58
- super::declare_function!(nodes, Nodes, call_impl(crate::graph::Path) -> Vec<graph::Node>);
81
+ super::declare_function!(nodes, Nodes, call_impl(value::Value) -> Vec<graph::Node>);
59
82
 
60
83
  #[derive(Debug, Default)]
61
84
  pub(super) struct Edges {}
62
85
 
63
86
  impl Edges
64
87
  {
65
- fn call_impl(path: graph::Path) -> FResult<Vec<graph::Edge>>
88
+ fn call_impl(path: value::Value) -> FResult<Vec<graph::Edge>>
66
89
  {
67
- Ok(vec![graph::Edge::new(
68
- path.key(),
69
- path.labels().clone(),
70
- path.properties().clone(),
71
- )])
90
+ match path
91
+ {
92
+ value::Value::SinglePath(p) =>
93
+ {
94
+ let (_, edge, _) = p.unpack();
95
+ Ok(vec![edge])
96
+ }
97
+ value::Value::Path(p) =>
98
+ {
99
+ let (_, elements) = p.unpack();
100
+ Ok(elements.into_iter().map(|(edge, _)| edge).collect())
101
+ }
102
+ o => Err(RunTimeError::InvalidArgument {
103
+ function_name: "edges",
104
+ index: 0,
105
+ expected_type: "path",
106
+ value: format!("{:?}", o),
107
+ }),
108
+ }
72
109
  }
73
110
  }
74
111
 
75
- super::declare_function!(edges, Edges, call_impl(crate::graph::Path) -> Vec<graph::Edge>);
112
+ super::declare_function!(edges, Edges, call_impl(value::Value) -> Vec<graph::Edge>);
@@ -2,6 +2,34 @@ use crate::prelude::*;
2
2
 
3
3
  use super::{ExpressionType, FResult, FunctionTypeTrait};
4
4
 
5
+ #[derive(Debug, Default)]
6
+ pub(super) struct Abs {}
7
+
8
+ impl Abs
9
+ {
10
+ fn call_impl(value: value::Value) -> FResult<value::Value>
11
+ {
12
+ match value
13
+ {
14
+ value::Value::Integer(i) => Ok(i.abs().into()),
15
+ value::Value::Float(f) => Ok(f.abs().into()),
16
+ o => Err(RunTimeError::InvalidArgument {
17
+ function_name: "abs",
18
+ index: 0,
19
+ expected_type: "integer or float",
20
+ value: format!("{:?}", o),
21
+ }),
22
+ }
23
+ }
24
+ }
25
+
26
+ super::declare_function!(
27
+ abs, Abs,
28
+ call_impl(value::Value) -> value::Value,
29
+ null_handling(null_returns_null),
30
+ validate_args(ExpressionType::Integer | ExpressionType::Float)
31
+ );
32
+
5
33
  #[derive(Debug, Default)]
6
34
  pub(super) struct Coalesce {}
7
35
 
@@ -82,7 +110,12 @@ impl ToBoolean
82
110
  }
83
111
  }
84
112
 
85
- super::declare_function!(toboolean, ToBoolean, call_impl(crate::value::Value) -> value::Value);
113
+ super::declare_function!(
114
+ toboolean, ToBoolean,
115
+ call_impl(crate::value::Value) -> bool,
116
+ null_handling(null_returns_null),
117
+ validate_args(ExpressionType::Boolean | ExpressionType::Integer | ExpressionType::Float | ExpressionType::String)
118
+ );
86
119
 
87
120
  #[derive(Debug, Default)]
88
121
  pub(super) struct ToFloat {}
@@ -110,7 +143,12 @@ impl ToFloat
110
143
  }
111
144
  }
112
145
 
113
- super::declare_function!(tofloat, ToFloat, call_impl(crate::value::Value) -> value::Value);
146
+ super::declare_function!(
147
+ tofloat, ToFloat,
148
+ call_impl(crate::value::Value) -> f64,
149
+ null_handling(null_returns_null),
150
+ validate_args(ExpressionType::Boolean | ExpressionType::Integer | ExpressionType::Float | ExpressionType::String)
151
+ );
114
152
 
115
153
  #[derive(Debug, Default)]
116
154
  pub(super) struct ToInteger {}
@@ -138,7 +176,12 @@ impl ToInteger
138
176
  }
139
177
  }
140
178
 
141
- super::declare_function!(tointeger, ToInteger, call_impl(crate::value::Value) -> value::Value);
179
+ super::declare_function!(
180
+ tointeger, ToInteger,
181
+ call_impl(crate::value::Value) -> i64,
182
+ null_handling(null_returns_null),
183
+ validate_args(ExpressionType::Boolean | ExpressionType::Integer | ExpressionType::Float | ExpressionType::String)
184
+ );
142
185
 
143
186
  #[derive(Debug, Default)]
144
187
  pub(super) struct Properties {}
@@ -162,4 +205,4 @@ impl Properties
162
205
  }
163
206
  }
164
207
 
165
- super::declare_function!(properties, Properties, call_impl(crate::value::Value) -> value::ValueMap, validate_args(ExpressionType::Map | ExpressionType::Node | ExpressionType::Edge | ExpressionType::Null));
208
+ super::declare_function!(properties, Properties, call_impl(crate::value::Value) -> value::ValueMap, null_handling(null_returns_null), validate_args(ExpressionType::Map | ExpressionType::Node | ExpressionType::Edge | ExpressionType::Null));
@@ -2,6 +2,123 @@ use crate::prelude::*;
2
2
 
3
3
  use super::{ExpressionType, FResult, FunctionTypeTrait};
4
4
 
5
+ #[derive(Debug, Default)]
6
+ pub(super) struct ToLower {}
7
+
8
+ impl ToLower
9
+ {
10
+ fn call_impl(string: String) -> FResult<String>
11
+ {
12
+ Ok(string.to_lowercase())
13
+ }
14
+ }
15
+
16
+ super::declare_function!(tolower, ToLower, call_impl(String) -> String, null_handling(null_returns_null));
17
+
18
+ #[derive(Debug, Default)]
19
+ pub(super) struct ToUpper {}
20
+
21
+ impl ToUpper
22
+ {
23
+ fn call_impl(string: String) -> FResult<String>
24
+ {
25
+ Ok(string.to_uppercase())
26
+ }
27
+ }
28
+
29
+ super::declare_function!(toupper, ToUpper, call_impl(String) -> String, null_handling(null_returns_null));
30
+
31
+ #[derive(Debug, Default)]
32
+ pub(super) struct LTrim {}
33
+
34
+ impl LTrim
35
+ {
36
+ fn call_impl(string: String) -> FResult<String>
37
+ {
38
+ Ok(string.trim_start().to_string())
39
+ }
40
+ }
41
+
42
+ super::declare_function!(ltrim, LTrim, call_impl(String) -> String, null_handling(null_returns_null));
43
+
44
+ #[derive(Debug, Default)]
45
+ pub(super) struct RTrim {}
46
+
47
+ impl RTrim
48
+ {
49
+ fn call_impl(string: String) -> FResult<String>
50
+ {
51
+ Ok(string.trim_end().to_string())
52
+ }
53
+ }
54
+
55
+ super::declare_function!(rtrim, RTrim, call_impl(String) -> String, null_handling(null_returns_null));
56
+
57
+ #[derive(Debug, Default)]
58
+ pub(super) struct Trim {}
59
+
60
+ impl Trim
61
+ {
62
+ fn call_impl(string: String) -> FResult<String>
63
+ {
64
+ Ok(string.trim().to_string())
65
+ }
66
+ }
67
+
68
+ super::declare_function!(trim, Trim, call_impl(String) -> String, null_handling(null_returns_null));
69
+
70
+ #[derive(Debug, Default)]
71
+ pub(super) struct Reverse {}
72
+
73
+ impl Reverse
74
+ {
75
+ fn call_impl(string: String) -> FResult<String>
76
+ {
77
+ Ok(string.chars().rev().collect())
78
+ }
79
+ }
80
+
81
+ super::declare_function!(reverse, Reverse, call_impl(String) -> String, null_handling(null_returns_null));
82
+
83
+ #[derive(Debug, Default)]
84
+ pub(super) struct Split {}
85
+
86
+ impl Split
87
+ {
88
+ fn call_impl(string: String, pat: String) -> FResult<Vec<graphcore::Value>>
89
+ {
90
+ Ok(string.split(&pat).map(|x: &str| x.into()).collect())
91
+ }
92
+ }
93
+
94
+ super::declare_function!(
95
+ split, Split, call_impl(String, String) -> String,
96
+ null_handling(null_returns_null, ignore, ignore)
97
+ );
98
+
99
+ #[derive(Debug, Default)]
100
+ pub(super) struct Substring {}
101
+
102
+ impl Substring
103
+ {
104
+ fn call_impl(string: String, start: i64, length: i64) -> FResult<String>
105
+ {
106
+ use substring::Substring;
107
+ Ok(
108
+ string
109
+ .substring(start as usize, length as usize)
110
+ .to_string(),
111
+ )
112
+ }
113
+ }
114
+
115
+ super::declare_function!(
116
+ substring, Substring, call_impl(String, i64, i64) -> String,
117
+ null_handling(null_returns_null, ignore, ignore),
118
+ validate_args(ExpressionType::String | ExpressionType::Null, ExpressionType::Integer, ExpressionType::Integer),
119
+ default_args(2, i64::MAX)
120
+ );
121
+
5
122
  #[derive(Debug, Default)]
6
123
  pub(super) struct ToString {}
7
124
 
@@ -25,4 +142,9 @@ impl ToString
25
142
  }
26
143
  }
27
144
 
28
- super::declare_function!(tostring, ToString, call_impl(crate::value::Value) -> String, validate_args(ExpressionType::Boolean | ExpressionType::Integer | ExpressionType::Float | ExpressionType::String | ExpressionType::Null));
145
+ super::declare_function!(
146
+ tostring, ToString,
147
+ call_impl(crate::value::Value) -> String,
148
+ null_handling(null_returns_null),
149
+ validate_args(ExpressionType::Boolean | ExpressionType::Integer | ExpressionType::Float | ExpressionType::String)
150
+ );
@@ -79,7 +79,7 @@ impl super::FunctionTrait for HasLabels
79
79
  value: format!("{:?}", label),
80
80
  }
81
81
  .into(),
82
- )
82
+ );
83
83
  }
84
84
  }
85
85
  }