gqlite 1.2.0 → 1.2.3
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 +152 -135
- data/ext/gqliterb/Cargo.toml +4 -6
- data/ext/gqliterb/src/lib.rs +8 -2
- data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +2115 -0
- data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +138 -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 +259 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler/expression_analyser.rs +431 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler/variables_manager.rs +621 -0
- data/ext/gqliterb/vendor/gqlitedb/src/compiler.rs +1115 -0
- data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +342 -0
- data/ext/gqliterb/vendor/gqlitedb/src/consts.rs +10 -0
- data/ext/gqliterb/vendor/gqlitedb/src/error.rs +613 -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 +80 -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 +410 -0
- data/ext/gqliterb/vendor/gqlitedb/src/graph.rs +283 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/evaluators.rs +1776 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/instructions.rs +267 -0
- data/ext/gqliterb/vendor/gqlitedb/src/interpreter/mod.rs +4 -0
- data/ext/gqliterb/vendor/gqlitedb/src/lib.rs +41 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/ast.rs +611 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/gql.pest +196 -0
- data/ext/gqliterb/vendor/gqlitedb/src/parser/parser.rs +1183 -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 +1262 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store/sqlite.rs +1026 -0
- data/ext/gqliterb/vendor/gqlitedb/src/store.rs +439 -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 +46 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store/sqlite.rs +46 -0
- data/ext/gqliterb/vendor/gqlitedb/src/tests/store.rs +470 -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 +609 -0
- data/ext/gqliterb/vendor/gqlitedb/src/value_table.rs +610 -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
- metadata +82 -2
@@ -0,0 +1,410 @@
|
|
1
|
+
use std::{collections::HashMap, fmt::Debug, sync::Arc};
|
2
|
+
|
3
|
+
mod containers;
|
4
|
+
mod edge;
|
5
|
+
mod math;
|
6
|
+
mod node;
|
7
|
+
mod path;
|
8
|
+
mod scalar;
|
9
|
+
mod string;
|
10
|
+
mod value;
|
11
|
+
|
12
|
+
pub(crate) type FResult<T> = std::result::Result<T, error::RunTimeError>;
|
13
|
+
|
14
|
+
use crate::prelude::*;
|
15
|
+
use ccutils::sync::ArcRwLock;
|
16
|
+
use compiler::expression_analyser::ExpressionType;
|
17
|
+
|
18
|
+
pub(crate) trait FunctionTypeTrait
|
19
|
+
{
|
20
|
+
fn result_type() -> ExpressionType;
|
21
|
+
}
|
22
|
+
|
23
|
+
impl FunctionTypeTrait for crate::value::Value
|
24
|
+
{
|
25
|
+
fn result_type() -> ExpressionType
|
26
|
+
{
|
27
|
+
ExpressionType::Variant
|
28
|
+
}
|
29
|
+
}
|
30
|
+
impl FunctionTypeTrait for bool
|
31
|
+
{
|
32
|
+
fn result_type() -> ExpressionType
|
33
|
+
{
|
34
|
+
ExpressionType::Boolean
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
impl FunctionTypeTrait for String
|
39
|
+
{
|
40
|
+
fn result_type() -> ExpressionType
|
41
|
+
{
|
42
|
+
ExpressionType::String
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
impl FunctionTypeTrait for i64
|
47
|
+
{
|
48
|
+
fn result_type() -> ExpressionType
|
49
|
+
{
|
50
|
+
ExpressionType::Integer
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
impl FunctionTypeTrait for f64
|
55
|
+
{
|
56
|
+
fn result_type() -> ExpressionType
|
57
|
+
{
|
58
|
+
ExpressionType::Float
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
impl<T> FunctionTypeTrait for Vec<T>
|
63
|
+
{
|
64
|
+
fn result_type() -> ExpressionType
|
65
|
+
{
|
66
|
+
ExpressionType::Array
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
impl<T> FunctionTypeTrait for HashMap<String, T>
|
71
|
+
{
|
72
|
+
fn result_type() -> ExpressionType
|
73
|
+
{
|
74
|
+
ExpressionType::Map
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
impl FunctionTypeTrait for crate::value::ValueMap
|
79
|
+
{
|
80
|
+
fn result_type() -> ExpressionType
|
81
|
+
{
|
82
|
+
ExpressionType::Map
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
// _____ _ _ _____ _ _
|
87
|
+
// | ___| _ _ __ ___| |_(_) ___ _ _|_ _| __ __ _(_) |_
|
88
|
+
// | |_ | | | | '_ \ / __| __| |/ _ \| '_ \| || '__/ _` | | __|
|
89
|
+
// | _|| |_| | | | | (__| |_| | (_) | | | | || | | (_| | | |_
|
90
|
+
// |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|_||_| \__,_|_|\__|
|
91
|
+
|
92
|
+
pub(crate) trait FunctionTrait: Debug + Sync + Send
|
93
|
+
{
|
94
|
+
fn call(&self, arguments: Vec<crate::value::Value>) -> Result<crate::value::Value>;
|
95
|
+
fn validate_arguments(&self, arguments: Vec<ExpressionType>) -> Result<ExpressionType>;
|
96
|
+
fn is_deterministic(&self) -> bool;
|
97
|
+
}
|
98
|
+
|
99
|
+
// _____ _ _
|
100
|
+
// | ___| _ _ __ ___| |_(_) ___ _ __
|
101
|
+
// | |_ | | | | '_ \ / __| __| |/ _ \| '_ \
|
102
|
+
// | _|| |_| | | | | (__| |_| | (_) | | | |
|
103
|
+
// |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
|
104
|
+
|
105
|
+
pub(crate) type Function = Arc<Box<dyn FunctionTrait>>;
|
106
|
+
|
107
|
+
// __ __
|
108
|
+
// | \/ | __ _ _ __ __ _ __ _ ___ _ __
|
109
|
+
// | |\/| |/ _` | '_ \ / _` |/ _` |/ _ \ '__|
|
110
|
+
// | | | | (_| | | | | (_| | (_| | __/ |
|
111
|
+
// |_| |_|\__,_|_| |_|\__,_|\__, |\___|_|
|
112
|
+
// |___/
|
113
|
+
|
114
|
+
#[derive(Debug)]
|
115
|
+
struct ManagerInner
|
116
|
+
{
|
117
|
+
functions: HashMap<String, Function>,
|
118
|
+
aggregators: HashMap<String, aggregators::Aggregator>,
|
119
|
+
}
|
120
|
+
|
121
|
+
#[derive(Debug, Clone)]
|
122
|
+
pub(crate) struct Manager
|
123
|
+
{
|
124
|
+
inner: ArcRwLock<ManagerInner>,
|
125
|
+
}
|
126
|
+
|
127
|
+
ccutils::assert_impl_all!(Manager: Sync, Send);
|
128
|
+
|
129
|
+
impl Manager
|
130
|
+
{
|
131
|
+
pub(crate) fn new() -> Self
|
132
|
+
{
|
133
|
+
Self {
|
134
|
+
inner: ManagerInner {
|
135
|
+
functions: HashMap::from([
|
136
|
+
containers::Head::new(),
|
137
|
+
containers::Keys::new(),
|
138
|
+
containers::Range::new(),
|
139
|
+
containers::Size::new(),
|
140
|
+
edge::Type::new(),
|
141
|
+
math::Ceil::new(),
|
142
|
+
math::Floor::new(),
|
143
|
+
math::Rand::new(),
|
144
|
+
node::Labels::new(),
|
145
|
+
path::Length::new(),
|
146
|
+
path::Nodes::new(),
|
147
|
+
path::Edges::new(),
|
148
|
+
scalar::Coalesce::new(),
|
149
|
+
scalar::Properties::new(),
|
150
|
+
scalar::ToInteger::new(),
|
151
|
+
string::ToString::new(),
|
152
|
+
value::HasLabel::new(),
|
153
|
+
value::HasLabels::new(),
|
154
|
+
]),
|
155
|
+
aggregators: aggregators::init_aggregators(),
|
156
|
+
}
|
157
|
+
.into(),
|
158
|
+
}
|
159
|
+
}
|
160
|
+
pub(crate) fn get_function<E: error::GenericErrors>(&self, name: &str) -> Result<Function>
|
161
|
+
{
|
162
|
+
Ok(
|
163
|
+
self
|
164
|
+
.inner
|
165
|
+
.read()?
|
166
|
+
.functions
|
167
|
+
.get(&name.to_lowercase())
|
168
|
+
.ok_or_else(|| E::unknown_function(name).into())?
|
169
|
+
.clone(),
|
170
|
+
)
|
171
|
+
}
|
172
|
+
pub(crate) fn get_aggregator<E: error::GenericErrors>(
|
173
|
+
&self,
|
174
|
+
name: &str,
|
175
|
+
) -> Result<aggregators::Aggregator>
|
176
|
+
{
|
177
|
+
Ok(
|
178
|
+
self
|
179
|
+
.inner
|
180
|
+
.read()?
|
181
|
+
.aggregators
|
182
|
+
.get(&name.to_lowercase())
|
183
|
+
.ok_or_else(|| E::unknown_function(name).into())?
|
184
|
+
.clone(),
|
185
|
+
)
|
186
|
+
}
|
187
|
+
pub(crate) fn is_deterministic(&self, name: impl Into<String>) -> Result<bool>
|
188
|
+
{
|
189
|
+
let name = name.into();
|
190
|
+
let fun = self.get_function::<crate::error::CompileTimeError>(&name);
|
191
|
+
match fun
|
192
|
+
{
|
193
|
+
Ok(fun) => Ok(fun.is_deterministic()),
|
194
|
+
Err(_) =>
|
195
|
+
{
|
196
|
+
self.get_aggregator::<crate::error::CompileTimeError>(&name)?;
|
197
|
+
Ok(false)
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
201
|
+
pub(crate) fn is_aggregate(&self, name: &String) -> Result<bool>
|
202
|
+
{
|
203
|
+
Ok(self.inner.read()?.aggregators.contains_key(name))
|
204
|
+
}
|
205
|
+
|
206
|
+
pub(crate) fn validate_arguments(
|
207
|
+
&self,
|
208
|
+
name: impl Into<String>,
|
209
|
+
arguments: Vec<ExpressionType>,
|
210
|
+
) -> Result<ExpressionType>
|
211
|
+
{
|
212
|
+
let name = name.into();
|
213
|
+
let fun = self.get_function::<crate::error::CompileTimeError>(&name);
|
214
|
+
match fun
|
215
|
+
{
|
216
|
+
Ok(fun) => fun.validate_arguments(arguments),
|
217
|
+
Err(_) => self
|
218
|
+
.get_aggregator::<crate::error::CompileTimeError>(&name)?
|
219
|
+
.validate_arguments(arguments),
|
220
|
+
}
|
221
|
+
}
|
222
|
+
}
|
223
|
+
|
224
|
+
macro_rules! make_function_argument {
|
225
|
+
($function_name: ident, $arguments: ident, $index: expr, $arg_type: ty) => {
|
226
|
+
$arguments[$index]
|
227
|
+
.try_into_ref()
|
228
|
+
.map_err(|_| RunTimeError::InvalidArgument {
|
229
|
+
function_name: stringify!($function_name),
|
230
|
+
index: $index,
|
231
|
+
expected_type: stringify!($arg_type),
|
232
|
+
value: format!("{:?}", $arguments[$index]),
|
233
|
+
})?
|
234
|
+
};
|
235
|
+
}
|
236
|
+
|
237
|
+
macro_rules! make_function_call {
|
238
|
+
($function_name: ident, $function: expr, $arguments: ident, $arg_type_0: ty, ) => {
|
239
|
+
$function($crate::functions::make_function_argument!(
|
240
|
+
$function_name,
|
241
|
+
$arguments,
|
242
|
+
0,
|
243
|
+
$arg_type_0
|
244
|
+
))
|
245
|
+
};
|
246
|
+
($function_name: ident, $function: expr, $arguments: ident, $arg_type_0: ty, $arg_type_1: ty, ) => {
|
247
|
+
$function(
|
248
|
+
$crate::functions::make_function_argument!($function_name, $arguments, 0, $arg_type_0),
|
249
|
+
$crate::functions::make_function_argument!($function_name, $arguments, 1, $arg_type_1),
|
250
|
+
)
|
251
|
+
};
|
252
|
+
($function_name: ident, $function: expr, $arguments: ident, ) => {
|
253
|
+
$function()
|
254
|
+
};
|
255
|
+
}
|
256
|
+
|
257
|
+
macro_rules! count_arguments {
|
258
|
+
($count: expr, ) => {
|
259
|
+
$count
|
260
|
+
};
|
261
|
+
($count: expr, $arg_type_0: ty, $( $arg_type: ty , )*) => {
|
262
|
+
$crate::functions::count_arguments!($count + 1, $( $arg_type, )*)
|
263
|
+
};
|
264
|
+
($( $arg_type: ty $(,)? )* ) => {
|
265
|
+
$crate::functions::count_arguments!(0, $( $arg_type, )*)
|
266
|
+
};
|
267
|
+
}
|
268
|
+
|
269
|
+
macro_rules! count_patterns {
|
270
|
+
($count: expr, ) => {
|
271
|
+
$count
|
272
|
+
};
|
273
|
+
($count: expr, $arg_type_0: pat, $( $arg_pat: pat , )*) => {
|
274
|
+
$crate::functions::count_patterns!($count + 1, $( $arg_pat, )*)
|
275
|
+
};
|
276
|
+
($( $arg_pat: pat $(,)? )* ) => {
|
277
|
+
$crate::functions::count_patterns!(0, $( $arg_pat, )*)
|
278
|
+
};
|
279
|
+
}
|
280
|
+
|
281
|
+
#[rustfmt::skip]
|
282
|
+
macro_rules! default_validate_ {
|
283
|
+
($function_name: ident, $ret_type: ty) => {
|
284
|
+
|_: Vec<$crate::compiler::expression_analyser::ExpressionType>|
|
285
|
+
-> crate::Result<$crate::compiler::expression_analyser::ExpressionType>
|
286
|
+
{
|
287
|
+
// TODO
|
288
|
+
use $crate::functions::FunctionTypeTrait;
|
289
|
+
Ok(<$ret_type>::result_type())
|
290
|
+
}
|
291
|
+
};
|
292
|
+
}
|
293
|
+
|
294
|
+
#[rustfmt::skip]
|
295
|
+
macro_rules! validate_args_ {
|
296
|
+
($function_name: ident, $ret_type: ty, $( $expression_type: pat ),* ) => {
|
297
|
+
|args: Vec<$crate::compiler::expression_analyser::ExpressionType>|
|
298
|
+
-> crate::Result<$crate::compiler::expression_analyser::ExpressionType>
|
299
|
+
{
|
300
|
+
const ARG_COUNT: usize = $crate::functions::count_patterns!($( $expression_type,)*);
|
301
|
+
if args.len() != ARG_COUNT
|
302
|
+
{
|
303
|
+
Err(crate::error::CompileTimeError::InvalidNumberOfArguments {
|
304
|
+
function_name: stringify!($function_name),
|
305
|
+
got: args.len(),
|
306
|
+
expected: ARG_COUNT
|
307
|
+
})?;
|
308
|
+
}
|
309
|
+
let mut it = args.into_iter();
|
310
|
+
$(
|
311
|
+
match it.next().unwrap()
|
312
|
+
{
|
313
|
+
$expression_type | ExpressionType::Variant =>
|
314
|
+
Ok(<$ret_type>::result_type()),
|
315
|
+
_ => Err(crate::error::CompileTimeError::InvalidArgumentType.into())
|
316
|
+
}
|
317
|
+
)*
|
318
|
+
}
|
319
|
+
};
|
320
|
+
}
|
321
|
+
|
322
|
+
macro_rules! declare_function_ {
|
323
|
+
($function_name: ident, $type_name: ty, $f_name: ident ( $( $arg_type: ty $(,)? )* ) -> $ret_type: ty, $allow_null: expr, $validator: block ) => {
|
324
|
+
impl $type_name
|
325
|
+
{
|
326
|
+
pub(super) fn new() -> (String, crate::functions::Function)
|
327
|
+
{
|
328
|
+
(
|
329
|
+
stringify!($function_name).to_string(),
|
330
|
+
std::sync::Arc::new(Box::new(Self {})),
|
331
|
+
)
|
332
|
+
}
|
333
|
+
}
|
334
|
+
impl crate::functions::FunctionTrait for $type_name
|
335
|
+
{
|
336
|
+
fn call(&self, arguments: Vec<crate::value::Value>) -> crate::Result<crate::value::Value>
|
337
|
+
{
|
338
|
+
const ARG_COUNT: usize = $crate::functions::count_arguments!($( $arg_type,)*);
|
339
|
+
if arguments.len() == ARG_COUNT
|
340
|
+
{
|
341
|
+
if !$allow_null && ARG_COUNT > 0 && arguments.iter().all(|x| x.is_null())
|
342
|
+
{
|
343
|
+
return Ok(crate::value::Value::Null)
|
344
|
+
}
|
345
|
+
#[allow(unused_imports)]
|
346
|
+
use crate::value::ValueTryIntoRef;
|
347
|
+
Ok(
|
348
|
+
$crate::functions::make_function_call!($function_name, Self::$f_name, arguments, $( $arg_type,)*)
|
349
|
+
.map(|r| -> crate::value::Value { r.into() })?,
|
350
|
+
)
|
351
|
+
}
|
352
|
+
else
|
353
|
+
{
|
354
|
+
Err(RunTimeError::InvalidNumberOfArguments { function_name: stringify!($function_name), got: arguments.len(), expected: ARG_COUNT }.into())
|
355
|
+
}
|
356
|
+
}
|
357
|
+
fn validate_arguments(
|
358
|
+
&self,
|
359
|
+
args: Vec<$crate::compiler::expression_analyser::ExpressionType>,
|
360
|
+
) -> crate::Result<$crate::compiler::expression_analyser::ExpressionType>
|
361
|
+
{
|
362
|
+
let val_fn = $validator;
|
363
|
+
val_fn(args)
|
364
|
+
}
|
365
|
+
fn is_deterministic(&self) -> bool
|
366
|
+
{
|
367
|
+
true
|
368
|
+
}
|
369
|
+
}
|
370
|
+
};
|
371
|
+
}
|
372
|
+
|
373
|
+
macro_rules! declare_function {
|
374
|
+
($function_name: ident, $type_name: ty, $f_name: ident ( $( $arg_type: ty $(,)? )* ) -> $ret_type: ty ) => {
|
375
|
+
$crate::functions::declare_function_!($function_name, $type_name,
|
376
|
+
$f_name ( $( $arg_type, )* ) -> $ret_type, false,
|
377
|
+
{$crate::functions::default_validate_!($function_name, $ret_type)} );
|
378
|
+
};
|
379
|
+
($function_name: ident, $type_name: ty, $f_name: ident ( $( $arg_type: ty $(,)? )* ) -> $ret_type: ty, accept_null ) => {
|
380
|
+
$crate::functions::declare_function_!($function_name, $type_name,
|
381
|
+
$f_name ( $( $arg_type, )* ) -> $ret_type, true,
|
382
|
+
{$crate::functions::default_validate_!($function_name, $ret_type)} );
|
383
|
+
};
|
384
|
+
($function_name: ident, $type_name: ty, $f_name: ident ( $( $arg_type: ty $(,)? )* ) -> $ret_type: ty, validate_args( $( $expression_types: pat ),+ ) ) => {
|
385
|
+
$crate::functions::declare_function_!($function_name, $type_name,
|
386
|
+
$f_name ( $( $arg_type, )* ) -> $ret_type, false,
|
387
|
+
{$crate::functions::validate_args_!($function_name, $ret_type, $( $expression_types ),+ )} );
|
388
|
+
};
|
389
|
+
($function_name: ident, $type_name: ty, custom_trait ) => {
|
390
|
+
impl $type_name
|
391
|
+
{
|
392
|
+
pub(super) fn new() -> (String, crate::functions::Function)
|
393
|
+
{
|
394
|
+
(
|
395
|
+
stringify!($function_name).to_string(),
|
396
|
+
std::sync::Arc::new(Box::new(Self {})),
|
397
|
+
)
|
398
|
+
}
|
399
|
+
}
|
400
|
+
};
|
401
|
+
}
|
402
|
+
|
403
|
+
pub(crate) use count_arguments;
|
404
|
+
pub(crate) use count_patterns;
|
405
|
+
pub(crate) use declare_function;
|
406
|
+
pub(crate) use declare_function_;
|
407
|
+
pub(crate) use default_validate_;
|
408
|
+
pub(crate) use make_function_argument;
|
409
|
+
pub(crate) use make_function_call;
|
410
|
+
pub(crate) use validate_args_;
|
@@ -0,0 +1,283 @@
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
2
|
+
use std::borrow::Borrow;
|
3
|
+
|
4
|
+
use crate::prelude::*;
|
5
|
+
|
6
|
+
#[derive(Debug, Clone, Copy)]
|
7
|
+
pub(crate) enum EdgeDirectivity
|
8
|
+
{
|
9
|
+
Undirected,
|
10
|
+
Directed,
|
11
|
+
}
|
12
|
+
|
13
|
+
#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
|
14
|
+
pub struct Key
|
15
|
+
{
|
16
|
+
pub(crate) uuid: u128,
|
17
|
+
}
|
18
|
+
|
19
|
+
impl Serialize for Key
|
20
|
+
{
|
21
|
+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
22
|
+
where
|
23
|
+
S: serde::Serializer,
|
24
|
+
{
|
25
|
+
serializer.serialize_u128(self.uuid)
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
impl<'de> Deserialize<'de> for Key
|
30
|
+
{
|
31
|
+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
32
|
+
where
|
33
|
+
D: serde::Deserializer<'de>,
|
34
|
+
{
|
35
|
+
Ok(Self {
|
36
|
+
uuid: u128::deserialize(deserializer)?,
|
37
|
+
})
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
impl Default for Key
|
42
|
+
{
|
43
|
+
fn default() -> Self
|
44
|
+
{
|
45
|
+
Key {
|
46
|
+
uuid: uuid::Uuid::new_v4().as_u128(),
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
impl From<&Key> for u128
|
52
|
+
{
|
53
|
+
fn from(value: &Key) -> Self
|
54
|
+
{
|
55
|
+
value.uuid
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
impl From<Key> for u128
|
60
|
+
{
|
61
|
+
fn from(value: Key) -> Self
|
62
|
+
{
|
63
|
+
value.uuid
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
/// Represent a Node in the graph
|
68
|
+
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
|
69
|
+
#[serde(tag = "type", rename = "node")]
|
70
|
+
pub struct Node
|
71
|
+
{
|
72
|
+
/// uuid for the Node.
|
73
|
+
pub(crate) key: Key,
|
74
|
+
/// Vector of labels.
|
75
|
+
pub(crate) labels: Vec<String>,
|
76
|
+
/// Properties.
|
77
|
+
pub(crate) properties: value::ValueMap,
|
78
|
+
}
|
79
|
+
|
80
|
+
impl Node
|
81
|
+
{
|
82
|
+
/// uuid for the Node.
|
83
|
+
pub fn key(&self) -> Key
|
84
|
+
{
|
85
|
+
self.key
|
86
|
+
}
|
87
|
+
/// Vector of labels.
|
88
|
+
pub fn labels(&self) -> &Vec<String>
|
89
|
+
{
|
90
|
+
&self.labels
|
91
|
+
}
|
92
|
+
/// Properties.
|
93
|
+
pub fn properties(&self) -> &value::ValueMap
|
94
|
+
{
|
95
|
+
&self.properties
|
96
|
+
}
|
97
|
+
/// Unpack Node in key, labels and properties.
|
98
|
+
pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
|
99
|
+
{
|
100
|
+
(self.key, self.labels, self.properties)
|
101
|
+
}
|
102
|
+
/// Convert into value map representation
|
103
|
+
pub fn into_value_map(self) -> value::ValueMap
|
104
|
+
{
|
105
|
+
crate::map!("labels" => self.labels, "properties" => self.properties, "type" => "node")
|
106
|
+
}
|
107
|
+
}
|
108
|
+
|
109
|
+
impl std::fmt::Display for Node
|
110
|
+
{
|
111
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
112
|
+
{
|
113
|
+
if self.labels.is_empty()
|
114
|
+
{
|
115
|
+
write!(f, "(")?;
|
116
|
+
}
|
117
|
+
else
|
118
|
+
{
|
119
|
+
write!(f, "(:{} ", self.labels.join(":"))?;
|
120
|
+
}
|
121
|
+
write!(f, "{}", self.properties.borrow())?;
|
122
|
+
write!(f, ")")
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
/// Directed edge of the graph.
|
127
|
+
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
|
128
|
+
#[serde(tag = "type", rename = "edge")]
|
129
|
+
pub struct Edge
|
130
|
+
{
|
131
|
+
/// uuid for the Edge.
|
132
|
+
pub(crate) key: Key,
|
133
|
+
#[serde(skip_serializing)]
|
134
|
+
/// source node for the Edge, this property is used internally by the engine, but is not exported in query results, and not part of the public API.
|
135
|
+
pub(crate) source: Node,
|
136
|
+
/// destination node for the Edge, this property is used internally by the engine, but is not exported in query results, and not part of the public API.
|
137
|
+
#[serde(skip_serializing)]
|
138
|
+
pub(crate) destination: Node,
|
139
|
+
/// Labels for the Edge.
|
140
|
+
pub(crate) labels: Vec<String>,
|
141
|
+
/// Properties for the Edge.
|
142
|
+
pub(crate) properties: value::ValueMap,
|
143
|
+
}
|
144
|
+
|
145
|
+
impl Edge
|
146
|
+
{
|
147
|
+
/// uuid for the Node.
|
148
|
+
pub fn key(&self) -> Key
|
149
|
+
{
|
150
|
+
self.key
|
151
|
+
}
|
152
|
+
/// Vector of labels.
|
153
|
+
pub fn labels(&self) -> &Vec<String>
|
154
|
+
{
|
155
|
+
&self.labels
|
156
|
+
}
|
157
|
+
/// Properties.
|
158
|
+
pub fn properties(&self) -> &value::ValueMap
|
159
|
+
{
|
160
|
+
&self.properties
|
161
|
+
}
|
162
|
+
/// Unpack Edge in key, labels and properties.
|
163
|
+
pub fn unpack(self) -> (Key, Vec<String>, value::ValueMap)
|
164
|
+
{
|
165
|
+
(self.key, self.labels, self.properties)
|
166
|
+
}
|
167
|
+
/// Convert into value map representation
|
168
|
+
pub fn into_value_map(self) -> value::ValueMap
|
169
|
+
{
|
170
|
+
crate::map!( "labels" => self.labels, "properties" => self.properties, "type" => "edge")
|
171
|
+
}
|
172
|
+
}
|
173
|
+
|
174
|
+
impl std::fmt::Display for Edge
|
175
|
+
{
|
176
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
177
|
+
{
|
178
|
+
write!(f, "[:{} ", self.labels.join(":"))?;
|
179
|
+
write!(f, "{}", self.properties.borrow())?;
|
180
|
+
write!(f, "])")
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
impl Into<Path> for Edge
|
185
|
+
{
|
186
|
+
fn into(self) -> Path
|
187
|
+
{
|
188
|
+
Path {
|
189
|
+
key: self.key,
|
190
|
+
source: self.source,
|
191
|
+
destination: self.destination,
|
192
|
+
labels: self.labels,
|
193
|
+
properties: self.properties,
|
194
|
+
}
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
/// Path in the graph.
|
199
|
+
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone, Hash)]
|
200
|
+
#[serde(tag = "type", rename = "path")]
|
201
|
+
pub struct Path
|
202
|
+
{
|
203
|
+
/// uuid for the path.
|
204
|
+
pub(crate) key: Key,
|
205
|
+
/// source node for the path.
|
206
|
+
pub(crate) source: Node,
|
207
|
+
/// destination node for the path.
|
208
|
+
pub(crate) destination: Node,
|
209
|
+
/// Labels for the path.
|
210
|
+
pub(crate) labels: Vec<String>,
|
211
|
+
/// Properties for the path.
|
212
|
+
pub(crate) properties: value::ValueMap,
|
213
|
+
}
|
214
|
+
|
215
|
+
impl Path
|
216
|
+
{
|
217
|
+
/// uuid for the Node.
|
218
|
+
pub fn key(&self) -> Key
|
219
|
+
{
|
220
|
+
self.key
|
221
|
+
}
|
222
|
+
/// uuid for the Node.
|
223
|
+
pub fn source(&self) -> &Node
|
224
|
+
{
|
225
|
+
&self.source
|
226
|
+
}
|
227
|
+
/// uuid for the Node.
|
228
|
+
pub fn destination(&self) -> &Node
|
229
|
+
{
|
230
|
+
&self.destination
|
231
|
+
}
|
232
|
+
/// Vector of labels.
|
233
|
+
pub fn labels(&self) -> &Vec<String>
|
234
|
+
{
|
235
|
+
&self.labels
|
236
|
+
}
|
237
|
+
/// Properties.
|
238
|
+
pub fn properties(&self) -> &value::ValueMap
|
239
|
+
{
|
240
|
+
&self.properties
|
241
|
+
}
|
242
|
+
/// Unpack Node in key, labels and properties.
|
243
|
+
pub fn unpack(self) -> (Key, Node, Vec<String>, value::ValueMap, Node)
|
244
|
+
{
|
245
|
+
(
|
246
|
+
self.key,
|
247
|
+
self.source,
|
248
|
+
self.labels,
|
249
|
+
self.properties,
|
250
|
+
self.destination,
|
251
|
+
)
|
252
|
+
}
|
253
|
+
/// Convert into value map representation
|
254
|
+
pub fn into_value_map(self) -> value::ValueMap
|
255
|
+
{
|
256
|
+
crate::map!( "source" => self.source, "labels" => self.labels, "properties" => self.properties, "destination" => self.destination, "type" => "path")
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
impl std::fmt::Display for Path
|
261
|
+
{
|
262
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
|
263
|
+
{
|
264
|
+
write!(f, "{}-[:{} ", self.source, self.labels.join(":"))?;
|
265
|
+
write!(f, "{}", self.properties.borrow())?;
|
266
|
+
write!(f, "])->{}", self.destination)
|
267
|
+
}
|
268
|
+
}
|
269
|
+
|
270
|
+
#[cfg(test)]
|
271
|
+
macro_rules! labels {
|
272
|
+
// match a list of expressions separated by comma:
|
273
|
+
($($str:expr),*) => (
|
274
|
+
{
|
275
|
+
// create a Vec with this list of expressions,
|
276
|
+
// calling String::from on each:
|
277
|
+
vec![$(String::from($str),)*] as Vec<String>
|
278
|
+
}
|
279
|
+
);
|
280
|
+
}
|
281
|
+
|
282
|
+
#[cfg(test)]
|
283
|
+
pub(crate) use labels;
|