gqlite 1.2.2 → 1.3.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.
- checksums.yaml +4 -4
- data/ext/Cargo.toml +20 -0
- data/ext/gqlitedb/Cargo.toml +77 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/pokec.rs +30 -20
- data/ext/gqlitedb/gqlite_bench_data/README.MD +6 -0
- data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +85 -0
- data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +34 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/release.toml +2 -2
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/arithmetic.rs +1 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/stats.rs +27 -49
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators.rs +7 -7
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/capi.rs +34 -10
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/expression_analyser.rs +10 -4
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler/variables_manager.rs +36 -39
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/compiler.rs +46 -41
- data/ext/gqlitedb/src/connection.rs +300 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/error.rs +113 -50
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/containers.rs +21 -26
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/edge.rs +3 -3
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/math.rs +3 -3
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/node.rs +2 -2
- data/ext/gqlitedb/src/functions/path.rs +75 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/scalar.rs +3 -3
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/string.rs +1 -1
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions/value.rs +7 -7
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/functions.rs +29 -31
- data/ext/gqlitedb/src/graph.rs +11 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/evaluators.rs +178 -224
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/instructions.rs +8 -2
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/lib.rs +9 -5
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/ast.rs +54 -76
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/parser/gql.pest +9 -4
- data/ext/{gqliterb/vendor/gqlitedb/src/parser/parser.rs → gqlitedb/src/parser/parser_impl.rs} +86 -34
- data/ext/gqlitedb/src/parser.rs +4 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/prelude.rs +3 -2
- data/ext/gqlitedb/src/query_result.rs +88 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/redb.rs +260 -170
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/sqlite.rs +157 -142
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store.rs +30 -23
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/evaluators.rs +41 -85
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/redb.rs +12 -5
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store/sqlite.rs +12 -5
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/store.rs +106 -114
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/ast.rs +29 -29
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates/programs.rs +4 -4
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/compare.rs +13 -20
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value/contains.rs +2 -2
- data/ext/gqlitedb/src/value.rs +225 -0
- data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/value_table.rs +22 -18
- data/ext/gqliterb/Cargo.toml +12 -34
- data/ext/gqliterb/src/lib.rs +67 -39
- data/ext/graphcore/Cargo.toml +19 -0
- data/ext/graphcore/README.MD +4 -0
- data/ext/graphcore/release.toml +1 -0
- data/ext/graphcore/src/error.rs +28 -0
- data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/graph.rs +146 -35
- data/ext/graphcore/src/lib.rs +16 -0
- data/ext/graphcore/src/prelude.rs +4 -0
- data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/serialize_with.rs +2 -2
- data/ext/graphcore/src/table.rs +272 -0
- data/ext/{gqliterb/vendor/gqlitedb → graphcore}/src/value/value_map.rs +44 -49
- data/ext/graphcore/src/value.rs +413 -0
- metadata +94 -83
- data/ext/gqliterb/.cargo/config.toml +0 -2
- data/ext/gqliterb/Cargo.lock +0 -1109
- data/ext/gqliterb/vendor/gqlitedb/Cargo.lock +0 -2060
- data/ext/gqliterb/vendor/gqlitedb/Cargo.toml +0 -132
- data/ext/gqliterb/vendor/gqlitedb/src/connection.rs +0 -208
- data/ext/gqliterb/vendor/gqlitedb/src/functions/path.rs +0 -48
- data/ext/gqliterb/vendor/gqlitedb/src/parser.rs +0 -4
- data/ext/gqliterb/vendor/gqlitedb/src/value.rs +0 -559
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/askama.toml +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/common/mod.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_divan.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/benches/pokec_iai.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/containers.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/aggregators/count.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/consts.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/interpreter/mod.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/store/pgql.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/compiler.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/parser.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests/templates.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/tests.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/src/utils.rs +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/call_stats.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_count_for_node.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_create.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_delete_by_nodes.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_select.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/edge_update.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_create.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/graph_delete.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_create_table.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_get.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/metadata_set.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_create.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_delete.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_select.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/node_update.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/table_exists.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_from_1_01.sql +0 -0
- /data/ext/{gqliterb/vendor/gqlitedb → gqlitedb}/templates/sql/sqlite/upgrade_graph_from_1_01.sql +0 -0
@@ -114,9 +114,16 @@ pub extern "C" fn gqlite_connection_create_from_file(
|
|
114
114
|
check_error(context);
|
115
115
|
let options = get_value(options);
|
116
116
|
let path = unsafe { std::ffi::CStr::from_ptr(filename) };
|
117
|
+
|
117
118
|
if let Ok(path) = handle_error(context, path.to_str())
|
118
119
|
{
|
119
|
-
if let Ok(c) = handle_error(
|
120
|
+
if let Ok(c) = handle_error(
|
121
|
+
context,
|
122
|
+
crate::Connection::builder()
|
123
|
+
.options(options.into_map())
|
124
|
+
.path(path)
|
125
|
+
.create(),
|
126
|
+
)
|
120
127
|
{
|
121
128
|
return Box::into_raw(Box::new(GqliteConnectionT { connection: c }));
|
122
129
|
}
|
@@ -124,6 +131,22 @@ pub extern "C" fn gqlite_connection_create_from_file(
|
|
124
131
|
std::ptr::null::<GqliteConnectionT>() as *mut GqliteConnectionT
|
125
132
|
}
|
126
133
|
|
134
|
+
#[no_mangle]
|
135
|
+
pub extern "C" fn gqlite_connection_create(
|
136
|
+
context: *mut GqliteApiContextT,
|
137
|
+
options: *mut GqliteValueT,
|
138
|
+
) -> *mut GqliteConnectionT
|
139
|
+
{
|
140
|
+
check_error(context);
|
141
|
+
let options = get_value(options);
|
142
|
+
|
143
|
+
if let Ok(c) = handle_error(context, crate::Connection::create(options.into_map()))
|
144
|
+
{
|
145
|
+
return Box::into_raw(Box::new(GqliteConnectionT { connection: c }));
|
146
|
+
}
|
147
|
+
std::ptr::null::<GqliteConnectionT>() as *mut GqliteConnectionT
|
148
|
+
}
|
149
|
+
|
127
150
|
#[no_mangle]
|
128
151
|
pub extern "C" fn gqlite_connection_destroy(
|
129
152
|
_context: *mut GqliteApiContextT,
|
@@ -150,11 +173,13 @@ pub extern "C" fn gqlite_connection_query(
|
|
150
173
|
let conn = unsafe { Box::from_raw(connection) };
|
151
174
|
let result = conn
|
152
175
|
.connection
|
153
|
-
.
|
176
|
+
.execute_oc_query(query, get_value(bindings).into_map());
|
154
177
|
let _ = Box::into_raw(conn);
|
155
178
|
if let Ok(v) = handle_error(context, result)
|
156
179
|
{
|
157
|
-
return Box::into_raw(Box::new(GqliteValueT {
|
180
|
+
return Box::into_raw(Box::new(GqliteValueT {
|
181
|
+
value: v.into_value(),
|
182
|
+
}));
|
158
183
|
}
|
159
184
|
}
|
160
185
|
std::ptr::null::<GqliteValueT>() as *mut GqliteValueT
|
@@ -199,7 +224,7 @@ pub extern "C" fn gqlite_value_to_json(
|
|
199
224
|
return r;
|
200
225
|
}
|
201
226
|
let _ = Box::into_raw(value);
|
202
|
-
|
227
|
+
std::ptr::null()
|
203
228
|
}
|
204
229
|
|
205
230
|
#[no_mangle]
|
@@ -218,7 +243,7 @@ pub extern "C" fn gqlite_value_from_json(
|
|
218
243
|
return Box::into_raw(Box::new(GqliteValueT { value: v }));
|
219
244
|
}
|
220
245
|
}
|
221
|
-
|
246
|
+
std::ptr::null::<GqliteValueT>() as *mut GqliteValueT
|
222
247
|
}
|
223
248
|
|
224
249
|
#[no_mangle]
|
@@ -228,9 +253,8 @@ pub extern "C" fn gqlite_value_is_valid(
|
|
228
253
|
) -> bool
|
229
254
|
{
|
230
255
|
check_error(context);
|
231
|
-
|
232
|
-
|
233
|
-
crate::value::Value::Null
|
234
|
-
|
235
|
-
}
|
256
|
+
!matches!(
|
257
|
+
unsafe { (*value).value.borrow() },
|
258
|
+
crate::value::Value::Null
|
259
|
+
)
|
236
260
|
}
|
@@ -11,6 +11,7 @@ use crate::{compiler::variables_manager::VariablesManager, parser::ast, prelude:
|
|
11
11
|
pub(crate) enum ExpressionType
|
12
12
|
{
|
13
13
|
Array,
|
14
|
+
Key,
|
14
15
|
Map,
|
15
16
|
Node,
|
16
17
|
Edge,
|
@@ -134,7 +135,7 @@ where
|
|
134
135
|
}
|
135
136
|
}
|
136
137
|
|
137
|
-
impl<
|
138
|
+
impl<VT> ExpressionAnalyser for (&ast::Expression, VT)
|
138
139
|
where
|
139
140
|
VT: Fn(ExpressionInfo) -> Result<ExpressionInfo>,
|
140
141
|
{
|
@@ -188,8 +189,8 @@ impl ExpressionInfo
|
|
188
189
|
let dependents = dependents.into();
|
189
190
|
Self {
|
190
191
|
expression_type,
|
191
|
-
constant: dependents.iter().all(|x| x.constant
|
192
|
-
aggregation_result: dependents.into_iter().any(|x| x.aggregation_result
|
192
|
+
constant: dependents.iter().all(|x| x.constant),
|
193
|
+
aggregation_result: dependents.into_iter().any(|x| x.aggregation_result),
|
193
194
|
}
|
194
195
|
}
|
195
196
|
}
|
@@ -253,7 +254,7 @@ impl<'b> Analyser<'b>
|
|
253
254
|
arguments.iter().map(|x| x.expression_type).collect(),
|
254
255
|
)?,
|
255
256
|
self.functions_manager.is_deterministic(&call.name)?
|
256
|
-
&& arguments.iter().all(|x| x.constant
|
257
|
+
&& arguments.iter().all(|x| x.constant),
|
257
258
|
self.functions_manager.is_aggregate(&call.name)?,
|
258
259
|
))
|
259
260
|
}
|
@@ -349,6 +350,10 @@ impl<'b> Analyser<'b>
|
|
349
350
|
ExpressionType::Variant,
|
350
351
|
([&ri.left, &ri.right].into_iter(), validators::any).analyse(self)?,
|
351
352
|
)),
|
353
|
+
ast::Expression::Exponent(ri) => Ok(ExpressionInfo::new_type(
|
354
|
+
ExpressionType::Variant,
|
355
|
+
([&ri.left, &ri.right].into_iter(), validators::any).analyse(self)?,
|
356
|
+
)),
|
352
357
|
ast::Expression::Map(map) => Ok(ExpressionInfo::new_type(
|
353
358
|
ExpressionType::Map,
|
354
359
|
(map.map.iter().map(|(_, v)| v), validators::any).analyse(self)?,
|
@@ -404,6 +409,7 @@ impl<'b> Analyser<'b>
|
|
404
409
|
match val.value
|
405
410
|
{
|
406
411
|
value::Value::Array(_) => ExpressionType::Array,
|
412
|
+
value::Value::Key(_) => ExpressionType::Key,
|
407
413
|
value::Value::Boolean(_) => ExpressionType::Boolean,
|
408
414
|
value::Value::Edge(_) => ExpressionType::Edge,
|
409
415
|
value::Value::Node(_) => ExpressionType::Node,
|
@@ -20,6 +20,7 @@ fn unknown_variable_error(name: &ast::VariableIdentifier) -> ErrorType
|
|
20
20
|
// \_/ \__,_|_| |_|\__,_|_.__/|_|\___|
|
21
21
|
|
22
22
|
#[derive(Debug, Clone)]
|
23
|
+
#[allow(clippy::large_enum_variant)]
|
23
24
|
pub(crate) enum VariableContent
|
24
25
|
{
|
25
26
|
Node(ast::NodePattern),
|
@@ -137,14 +138,14 @@ impl VariablesManager
|
|
137
138
|
{
|
138
139
|
identifier
|
139
140
|
.as_ref()
|
140
|
-
.
|
141
|
+
.is_some_and(|identifier| self.variables.contains_key(identifier))
|
141
142
|
}
|
142
143
|
/// Get the index of the variable in the row of variables
|
143
144
|
pub(crate) fn get_variable_index(&self, identifier: &ast::VariableIdentifier) -> Result<usize>
|
144
145
|
{
|
145
146
|
self
|
146
147
|
.variables
|
147
|
-
.get(
|
148
|
+
.get(identifier)
|
148
149
|
.ok_or_else(|| unknown_variable_error(identifier))
|
149
150
|
.map(|x| x.col_id)
|
150
151
|
}
|
@@ -175,7 +176,7 @@ impl VariablesManager
|
|
175
176
|
var_id.as_ref().map_or(Ok(false), |name| {
|
176
177
|
self
|
177
178
|
.variables
|
178
|
-
.get(
|
179
|
+
.get(name)
|
179
180
|
.ok_or_else(|| unknown_variable_error(name))
|
180
181
|
.map(|x| x.is_set)
|
181
182
|
})
|
@@ -190,7 +191,7 @@ impl VariablesManager
|
|
190
191
|
{
|
191
192
|
self
|
192
193
|
.variables
|
193
|
-
.get_mut(
|
194
|
+
.get_mut(var_id)
|
194
195
|
.ok_or_else(|| unknown_variable_error(var_id))
|
195
196
|
.map(|x| x.is_set = true)
|
196
197
|
}
|
@@ -205,7 +206,7 @@ impl VariablesManager
|
|
205
206
|
expression_type: ExpressionType,
|
206
207
|
) -> Result<()>
|
207
208
|
{
|
208
|
-
if self.variables.contains_key(
|
209
|
+
if self.variables.contains_key(var_id)
|
209
210
|
{
|
210
211
|
Err(
|
211
212
|
CompileTimeError::VariableAlreadyBound {
|
@@ -228,7 +229,7 @@ impl VariablesManager
|
|
228
229
|
{
|
229
230
|
if let Some(var_id) = &node.variable
|
230
231
|
{
|
231
|
-
if let Some(var) = self.variables.get(
|
232
|
+
if let Some(var) = self.variables.get(var_id)
|
232
233
|
{
|
233
234
|
match var.variable_type
|
234
235
|
{
|
@@ -236,7 +237,7 @@ impl VariablesManager
|
|
236
237
|
{
|
237
238
|
VariableContent::Node(var_node) =>
|
238
239
|
{
|
239
|
-
if (!node.labels.is_none() ||
|
240
|
+
if (!node.labels.is_none() || node.properties.is_some())
|
240
241
|
&& (node.labels != var_node.labels || node.properties != var_node.properties)
|
241
242
|
{
|
242
243
|
Err(
|
@@ -271,7 +272,7 @@ impl VariablesManager
|
|
271
272
|
{
|
272
273
|
if let Some(props) = &node.properties
|
273
274
|
{
|
274
|
-
expression_analyser::Analyser::new(
|
275
|
+
expression_analyser::Analyser::new(self, &self.function_manager).analyse(props)?;
|
275
276
|
}
|
276
277
|
self.variables.insert(
|
277
278
|
var_id.clone(),
|
@@ -291,7 +292,7 @@ impl VariablesManager
|
|
291
292
|
self.validate_node(&edge.destination)?;
|
292
293
|
if let Some(var_id) = &edge.variable
|
293
294
|
{
|
294
|
-
if let Some(var) = self.variables.get(
|
295
|
+
if let Some(var) = self.variables.get(var_id)
|
295
296
|
{
|
296
297
|
match var.content
|
297
298
|
{
|
@@ -313,7 +314,7 @@ impl VariablesManager
|
|
313
314
|
{
|
314
315
|
if let Some(props) = &edge.properties
|
315
316
|
{
|
316
|
-
expression_analyser::Analyser::new(
|
317
|
+
expression_analyser::Analyser::new(self, &self.function_manager).analyse(props)?;
|
317
318
|
}
|
318
319
|
self.variables.insert(
|
319
320
|
var_id.clone(),
|
@@ -333,7 +334,7 @@ impl VariablesManager
|
|
333
334
|
{
|
334
335
|
if let Some(var_id) = &node.variable
|
335
336
|
{
|
336
|
-
if let Some(var) = self.variables.get(
|
337
|
+
if let Some(var) = self.variables.get(var_id)
|
337
338
|
{
|
338
339
|
match var.variable_type
|
339
340
|
{
|
@@ -341,7 +342,7 @@ impl VariablesManager
|
|
341
342
|
{
|
342
343
|
VariableContent::Node(var_node) =>
|
343
344
|
{
|
344
|
-
if (!node.labels.is_none() ||
|
345
|
+
if (!node.labels.is_none() || node.properties.is_some())
|
345
346
|
&& (node.labels != var_node.labels || node.properties != var_node.properties)
|
346
347
|
{
|
347
348
|
Err(
|
@@ -388,7 +389,7 @@ impl VariablesManager
|
|
388
389
|
{
|
389
390
|
if let Some(var_id) = &edge.variable
|
390
391
|
{
|
391
|
-
if let Some(var) = self.variables.get(
|
392
|
+
if let Some(var) = self.variables.get(var_id)
|
392
393
|
{
|
393
394
|
match var.variable_type
|
394
395
|
{
|
@@ -396,7 +397,7 @@ impl VariablesManager
|
|
396
397
|
{
|
397
398
|
VariableContent::Edge(var_edge) =>
|
398
399
|
{
|
399
|
-
if (!edge.labels.is_none() ||
|
400
|
+
if (!edge.labels.is_none() || edge.properties.is_some())
|
400
401
|
&& (var_edge.labels != edge.labels || var_edge.properties != edge.properties)
|
401
402
|
{
|
402
403
|
Err(
|
@@ -474,7 +475,7 @@ impl VariablesManager
|
|
474
475
|
{
|
475
476
|
self.validate_node(&edge.destination)?;
|
476
477
|
}
|
477
|
-
if is_create || !self.is_valid_existing_edge(
|
478
|
+
if is_create || !self.is_valid_existing_edge(edge)?
|
478
479
|
{
|
479
480
|
self.validate_edge(edge)?;
|
480
481
|
}
|
@@ -507,7 +508,7 @@ impl VariablesManager
|
|
507
508
|
named_expression: &ast::NamedExpression,
|
508
509
|
) -> Result<usize>
|
509
510
|
{
|
510
|
-
let expression_info = expression_analyser::Analyser::new(
|
511
|
+
let expression_info = expression_analyser::Analyser::new(self, &self.function_manager)
|
511
512
|
.analyse(&named_expression.expression)?;
|
512
513
|
let col_id = self
|
513
514
|
.variables
|
@@ -529,7 +530,7 @@ impl VariablesManager
|
|
529
530
|
{
|
530
531
|
let mut var = self
|
531
532
|
.variables
|
532
|
-
.remove(
|
533
|
+
.remove(var_id)
|
533
534
|
.ok_or_else(|| unknown_variable_error(var_id))?;
|
534
535
|
var.col_id = col_id;
|
535
536
|
new_variables.insert(var_id.clone(), var.mark_set());
|
@@ -539,7 +540,7 @@ impl VariablesManager
|
|
539
540
|
}
|
540
541
|
pub(crate) fn analyse(&mut self, statement: &ast::Statement) -> Result<()>
|
541
542
|
{
|
542
|
-
if self.variables.iter().any(|(_, var)| var.is_set
|
543
|
+
if self.variables.iter().any(|(_, var)| !var.is_set)
|
543
544
|
{
|
544
545
|
return Err(
|
545
546
|
InternalError::NotAllVariablesAreSet {
|
@@ -558,33 +559,29 @@ impl VariablesManager
|
|
558
559
|
.into(),
|
559
560
|
);
|
560
561
|
}
|
561
|
-
#[allow(unused_variables)]
|
562
562
|
match statement
|
563
563
|
{
|
564
|
-
ast::Statement::CreateGraph(
|
564
|
+
ast::Statement::CreateGraph(..) =>
|
565
565
|
{}
|
566
|
-
ast::Statement::
|
566
|
+
ast::Statement::DropGraph(..) =>
|
567
|
+
{}
|
568
|
+
ast::Statement::UseGraph(..) =>
|
567
569
|
{}
|
568
570
|
ast::Statement::Create(create) =>
|
569
571
|
{
|
570
572
|
for pattern in create.patterns.iter()
|
571
573
|
{
|
572
|
-
|
574
|
+
if let ast::Pattern::Node(n) = &pattern
|
573
575
|
{
|
574
|
-
|
576
|
+
if self.has_variable(&n.variable)
|
575
577
|
{
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
.into(),
|
583
|
-
);
|
584
|
-
}
|
578
|
+
return Err(
|
579
|
+
CompileTimeError::VariableAlreadyBound {
|
580
|
+
name: n.variable.clone().unwrap().name().clone(),
|
581
|
+
}
|
582
|
+
.into(),
|
583
|
+
);
|
585
584
|
}
|
586
|
-
_ =>
|
587
|
-
{}
|
588
585
|
}
|
589
586
|
self.analyse_pattern(pattern, true)?;
|
590
587
|
}
|
@@ -596,11 +593,11 @@ impl VariablesManager
|
|
596
593
|
self.analyse_pattern(pattern, false)?;
|
597
594
|
}
|
598
595
|
}
|
599
|
-
ast::Statement::Return(
|
596
|
+
ast::Statement::Return(..) =>
|
600
597
|
{}
|
601
|
-
ast::Statement::Call(
|
598
|
+
ast::Statement::Call(..) =>
|
602
599
|
{}
|
603
|
-
ast::Statement::With(
|
600
|
+
ast::Statement::With(..) =>
|
604
601
|
{}
|
605
602
|
ast::Statement::Unwind(unwind) =>
|
606
603
|
{
|
@@ -610,9 +607,9 @@ impl VariablesManager
|
|
610
607
|
)?;
|
611
608
|
self.mark_variables_as_set(&unwind.identifier)?;
|
612
609
|
}
|
613
|
-
ast::Statement::Delete(
|
610
|
+
ast::Statement::Delete(..) =>
|
614
611
|
{}
|
615
|
-
ast::Statement::Update(
|
612
|
+
ast::Statement::Update(..) =>
|
616
613
|
{}
|
617
614
|
}
|
618
615
|
Ok(())
|
@@ -52,7 +52,7 @@ impl Compiler
|
|
52
52
|
) -> Result<()>
|
53
53
|
{
|
54
54
|
expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
|
55
|
-
.analyse(
|
55
|
+
.analyse(expression)?;
|
56
56
|
|
57
57
|
let expr = match expression
|
58
58
|
{
|
@@ -83,7 +83,7 @@ impl Compiler
|
|
83
83
|
self.compile_expression(
|
84
84
|
function_call
|
85
85
|
.arguments
|
86
|
-
.
|
86
|
+
.first()
|
87
87
|
.ok_or(error::InternalError::MissingAggregationArgument)?,
|
88
88
|
&mut argument_instructions,
|
89
89
|
aggregations,
|
@@ -141,7 +141,7 @@ impl Compiler
|
|
141
141
|
self.compile_expression(v, instructions, aggregations)?;
|
142
142
|
keys.push(k.to_owned());
|
143
143
|
}
|
144
|
-
Instruction::CreateMap { keys
|
144
|
+
Instruction::CreateMap { keys }
|
145
145
|
}
|
146
146
|
ast::Expression::MemberAccess(member_access) =>
|
147
147
|
{
|
@@ -261,6 +261,11 @@ impl Compiler
|
|
261
261
|
compile_binary_op!(self, modulo, instructions, aggregations);
|
262
262
|
Instruction::ModuloBinaryOperator
|
263
263
|
}
|
264
|
+
ast::Expression::Exponent(exponent) =>
|
265
|
+
{
|
266
|
+
compile_binary_op!(self, exponent, instructions, aggregations);
|
267
|
+
Instruction::ExponentBinaryOperator
|
268
|
+
}
|
264
269
|
ast::Expression::Negation(logical_negation) =>
|
265
270
|
{
|
266
271
|
self.compile_expression(&logical_negation.value, instructions, aggregations)?;
|
@@ -323,33 +328,32 @@ impl Compiler
|
|
323
328
|
.mark_variables_as_set(&node.variable)?;
|
324
329
|
self.compile_optional_expression(&node.properties, instructions)?;
|
325
330
|
let mut labels = Default::default();
|
326
|
-
|
331
|
+
Self::compile_labels_expression(&mut labels, &node.labels)?;
|
327
332
|
instructions.push(Instruction::CreateNodeLiteral { labels });
|
328
333
|
Ok(())
|
329
334
|
}
|
330
335
|
|
331
336
|
fn compile_labels_expression(
|
332
|
-
&mut self,
|
333
337
|
labels: &mut Vec<String>,
|
334
338
|
label_expressions: &ast::LabelExpression,
|
335
339
|
) -> Result<()>
|
336
340
|
{
|
337
|
-
match
|
341
|
+
match label_expressions
|
338
342
|
{
|
339
|
-
|
343
|
+
ast::LabelExpression::And(expressions) =>
|
340
344
|
{
|
341
345
|
for expr in expressions.iter()
|
342
346
|
{
|
343
|
-
|
347
|
+
Self::compile_labels_expression(labels, expr)?;
|
344
348
|
}
|
345
349
|
Ok(())
|
346
350
|
}
|
347
|
-
|
351
|
+
ast::LabelExpression::String(label) =>
|
348
352
|
{
|
349
353
|
labels.push(label.to_owned());
|
350
354
|
Ok(())
|
351
355
|
}
|
352
|
-
|
356
|
+
ast::LabelExpression::None => Ok(()),
|
353
357
|
_ => Err(
|
354
358
|
InternalError::InvalidCreateLabels {
|
355
359
|
context: "compile_create_labels",
|
@@ -361,21 +365,20 @@ impl Compiler
|
|
361
365
|
|
362
366
|
// Assume top of the stack contains an edge or node
|
363
367
|
fn compile_filter_labels(
|
364
|
-
&mut self,
|
365
368
|
instructions: &mut Instructions,
|
366
369
|
label_expressions: &ast::LabelExpression,
|
367
370
|
has_label_function: &functions::Function,
|
368
371
|
) -> Result<()>
|
369
372
|
{
|
370
|
-
match
|
373
|
+
match label_expressions
|
371
374
|
{
|
372
|
-
|
375
|
+
ast::LabelExpression::And(expressions) =>
|
373
376
|
{
|
374
377
|
instructions.push(Instruction::Push { value: true.into() });
|
375
378
|
instructions.push(Instruction::Swap);
|
376
379
|
for expr in expressions.iter()
|
377
380
|
{
|
378
|
-
|
381
|
+
Self::compile_filter_labels(instructions, expr, has_label_function)?;
|
379
382
|
// stack contains (a: bool) (b: labels) (c: bool)
|
380
383
|
instructions.push(Instruction::InverseRot3);
|
381
384
|
// stack contains (c: bool) (a: bool) (b: labels)
|
@@ -386,7 +389,7 @@ impl Compiler
|
|
386
389
|
}
|
387
390
|
Ok(())
|
388
391
|
}
|
389
|
-
|
392
|
+
ast::LabelExpression::Or(expressions) =>
|
390
393
|
{
|
391
394
|
instructions.push(Instruction::Push {
|
392
395
|
value: false.into(),
|
@@ -394,7 +397,7 @@ impl Compiler
|
|
394
397
|
instructions.push(Instruction::Swap);
|
395
398
|
for expr in expressions.iter()
|
396
399
|
{
|
397
|
-
|
400
|
+
Self::compile_filter_labels(instructions, expr, has_label_function)?;
|
398
401
|
// stack contains (a: bool) (b: labels) (c: bool)
|
399
402
|
instructions.push(Instruction::InverseRot3);
|
400
403
|
// stack contains (c: bool) (a: bool) (b: labels)
|
@@ -405,13 +408,13 @@ impl Compiler
|
|
405
408
|
}
|
406
409
|
Ok(())
|
407
410
|
}
|
408
|
-
|
411
|
+
ast::LabelExpression::Not(expr) =>
|
409
412
|
{
|
410
|
-
|
413
|
+
Self::compile_filter_labels(instructions, expr, has_label_function)?;
|
411
414
|
instructions.push(Instruction::NotUnaryOperator);
|
412
415
|
Ok(())
|
413
416
|
}
|
414
|
-
|
417
|
+
ast::LabelExpression::String(label) =>
|
415
418
|
{
|
416
419
|
instructions.push(Instruction::Duplicate);
|
417
420
|
instructions.push(Instruction::Push {
|
@@ -423,7 +426,7 @@ impl Compiler
|
|
423
426
|
});
|
424
427
|
Ok(())
|
425
428
|
}
|
426
|
-
|
429
|
+
ast::LabelExpression::None =>
|
427
430
|
{
|
428
431
|
instructions.push(Instruction::Push { value: true.into() });
|
429
432
|
Ok(())
|
@@ -431,10 +434,7 @@ impl Compiler
|
|
431
434
|
}
|
432
435
|
}
|
433
436
|
|
434
|
-
fn compile_create_patterns(
|
435
|
-
&mut self,
|
436
|
-
patterns: &Vec<crate::parser::ast::Pattern>,
|
437
|
-
) -> Result<Block>
|
437
|
+
fn compile_create_patterns(&mut self, patterns: &[crate::parser::ast::Pattern]) -> Result<Block>
|
438
438
|
{
|
439
439
|
let actions = patterns.iter().map(|c| {
|
440
440
|
let mut instructions = Instructions::new();
|
@@ -500,7 +500,7 @@ impl Compiler
|
|
500
500
|
Err(CompileTimeError::NoSingleRelationshipType)?;
|
501
501
|
}
|
502
502
|
let mut labels = Default::default();
|
503
|
-
|
503
|
+
Self::compile_labels_expression(&mut labels, &edge.labels)?;
|
504
504
|
instructions.push(Instruction::CreateEdgeLiteral { labels });
|
505
505
|
}
|
506
506
|
crate::parser::ast::Pattern::Path(_) =>
|
@@ -533,7 +533,7 @@ impl Compiler
|
|
533
533
|
let mut labels = Default::default();
|
534
534
|
if node.labels.is_all_inclusive()
|
535
535
|
{
|
536
|
-
|
536
|
+
Self::compile_labels_expression(&mut labels, &node.labels)?;
|
537
537
|
}
|
538
538
|
else
|
539
539
|
{
|
@@ -550,7 +550,7 @@ impl Compiler
|
|
550
550
|
let has_label_function = self
|
551
551
|
.function_manager
|
552
552
|
.get_function::<CompileTimeError>("has_label")?;
|
553
|
-
|
553
|
+
Self::compile_filter_labels(filter, &node.labels, &has_label_function)?;
|
554
554
|
filter.push(Instruction::Rot3);
|
555
555
|
filter.push(Instruction::AndBinaryOperator);
|
556
556
|
filter.push(Instruction::Swap);
|
@@ -629,14 +629,14 @@ impl Compiler
|
|
629
629
|
let mut labels = Default::default();
|
630
630
|
if edge.labels.is_all_inclusive()
|
631
631
|
{
|
632
|
-
|
632
|
+
Self::compile_labels_expression(&mut labels, &edge.labels)?;
|
633
633
|
}
|
634
634
|
else
|
635
635
|
{
|
636
636
|
let has_label_function = self
|
637
637
|
.function_manager
|
638
638
|
.get_function::<CompileTimeError>("has_label")?;
|
639
|
-
|
639
|
+
Self::compile_filter_labels(&mut filter, &edge.labels, &has_label_function)?;
|
640
640
|
filter.push(Instruction::Rot3);
|
641
641
|
filter.push(Instruction::AndBinaryOperator);
|
642
642
|
filter.push(Instruction::Swap);
|
@@ -685,7 +685,7 @@ impl Compiler
|
|
685
685
|
.mark_variables_as_set(&path_variable)?;
|
686
686
|
// Create block
|
687
687
|
Ok(BlockMatch::MatchEdge {
|
688
|
-
instructions
|
688
|
+
instructions,
|
689
689
|
left_variable: self
|
690
690
|
.variables_manager
|
691
691
|
.get_variable_index_option(&source_variable)?,
|
@@ -701,10 +701,11 @@ impl Compiler
|
|
701
701
|
})
|
702
702
|
}
|
703
703
|
|
704
|
+
#[allow(clippy::type_complexity)]
|
704
705
|
fn compile_return_with(
|
705
706
|
&mut self,
|
706
707
|
all: bool,
|
707
|
-
expressions: &
|
708
|
+
expressions: &[ast::NamedExpression],
|
708
709
|
where_expression: &Option<ast::Expression>,
|
709
710
|
modifiers: &ast::Modifiers,
|
710
711
|
) -> Result<(
|
@@ -750,7 +751,7 @@ impl Compiler
|
|
750
751
|
.into(),
|
751
752
|
);
|
752
753
|
}
|
753
|
-
let col_id = self.variables_manager.analyse_named_expression(
|
754
|
+
let col_id = self.variables_manager.analyse_named_expression(e)?;
|
754
755
|
variables.push((
|
755
756
|
e.identifier.clone(),
|
756
757
|
RWExpression {
|
@@ -773,7 +774,7 @@ impl Compiler
|
|
773
774
|
self.compile_expression(where_expression, &mut filter, &mut None)?;
|
774
775
|
}
|
775
776
|
|
776
|
-
let modifiers = self.compile_modifiers(
|
777
|
+
let modifiers = self.compile_modifiers(modifiers)?;
|
777
778
|
let variables_size = self.variables_size();
|
778
779
|
self
|
779
780
|
.variables_manager
|
@@ -788,7 +789,7 @@ impl Compiler
|
|
788
789
|
|
789
790
|
fn compile_match_patterns(
|
790
791
|
&mut self,
|
791
|
-
patterns: &
|
792
|
+
patterns: &[crate::parser::ast::Pattern],
|
792
793
|
where_expression: &Option<crate::parser::ast::Expression>,
|
793
794
|
optional: bool,
|
794
795
|
) -> Result<Block>
|
@@ -806,7 +807,7 @@ impl Compiler
|
|
806
807
|
.variables_manager
|
807
808
|
.mark_variables_as_set(&node.variable)?;
|
808
809
|
Ok(BlockMatch::MatchNode {
|
809
|
-
instructions
|
810
|
+
instructions,
|
810
811
|
variable: self
|
811
812
|
.variables_manager
|
812
813
|
.get_variable_index_option(&node.variable)?,
|
@@ -815,7 +816,7 @@ impl Compiler
|
|
815
816
|
}
|
816
817
|
crate::parser::ast::Pattern::Edge(edge) =>
|
817
818
|
{
|
818
|
-
self.compile_match_edge(None,
|
819
|
+
self.compile_match_edge(None, edge, is_single_match, &mut edge_variables)
|
819
820
|
}
|
820
821
|
crate::parser::ast::Pattern::Path(path) => self.compile_match_edge(
|
821
822
|
Some(path.variable.to_owned()),
|
@@ -836,7 +837,7 @@ impl Compiler
|
|
836
837
|
}
|
837
838
|
self.compile_expression(where_expression, &mut filter, &mut None)?;
|
838
839
|
}
|
839
|
-
Ok(Block::
|
840
|
+
Ok(Block::Match {
|
840
841
|
blocks,
|
841
842
|
filter,
|
842
843
|
optional,
|
@@ -847,7 +848,7 @@ impl Compiler
|
|
847
848
|
fn check_for_constant_integer_expression(&mut self, x: &ast::Expression) -> Result<()>
|
848
849
|
{
|
849
850
|
let ei = expression_analyser::Analyser::new(&self.variables_manager, &self.function_manager)
|
850
|
-
.analyse(
|
851
|
+
.analyse(x)?;
|
851
852
|
if !ei.constant
|
852
853
|
{
|
853
854
|
Err(error::CompileTimeError::NonConstantExpression.into())
|
@@ -874,7 +875,7 @@ impl Compiler
|
|
874
875
|
.map(|x| {
|
875
876
|
self.check_for_constant_integer_expression(x)?;
|
876
877
|
let mut instructions = Instructions::new();
|
877
|
-
self.compile_expression(
|
878
|
+
self.compile_expression(x, &mut instructions, &mut None)?;
|
878
879
|
Ok::<_, ErrorType>(instructions)
|
879
880
|
})
|
880
881
|
.transpose()?;
|
@@ -884,7 +885,7 @@ impl Compiler
|
|
884
885
|
.map(|x| {
|
885
886
|
self.check_for_constant_integer_expression(x)?;
|
886
887
|
let mut instructions = Instructions::new();
|
887
|
-
self.compile_expression(
|
888
|
+
self.compile_expression(x, &mut instructions, &mut None)?;
|
888
889
|
Ok::<_, ErrorType>(instructions)
|
889
890
|
})
|
890
891
|
.transpose()?;
|
@@ -935,6 +936,10 @@ pub(crate) fn compile(
|
|
935
936
|
ast::Statement::CreateGraph(create_graph) => Ok(Block::CreateGraph {
|
936
937
|
name: create_graph.name.to_owned(),
|
937
938
|
}),
|
939
|
+
ast::Statement::DropGraph(drop_graph) => Ok(Block::DropGraph {
|
940
|
+
name: drop_graph.name.to_owned(),
|
941
|
+
if_exists: drop_graph.if_exists,
|
942
|
+
}),
|
938
943
|
ast::Statement::UseGraph(use_graph) => Ok(Block::UseGraph {
|
939
944
|
name: use_graph.name.to_owned(),
|
940
945
|
}),
|
@@ -1014,7 +1019,7 @@ pub(crate) fn compile(
|
|
1014
1019
|
| expression_analyser::ExpressionType::Edge
|
1015
1020
|
| expression_analyser::ExpressionType::Variant =>
|
1016
1021
|
{
|
1017
|
-
compiler.compile_expression(
|
1022
|
+
compiler.compile_expression(expr, &mut instructions, &mut None)?
|
1018
1023
|
}
|
1019
1024
|
_ => Err(CompileTimeError::InvalidDelete)?,
|
1020
1025
|
}
|