gqlite 1.3.0 → 1.4.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/ext/Cargo.toml +4 -3
  3. data/ext/gqlitedb/Cargo.toml +7 -4
  4. data/ext/gqlitedb/src/aggregators/arithmetic.rs +1 -0
  5. data/ext/gqlitedb/src/compiler/expression_analyser.rs +2 -0
  6. data/ext/gqlitedb/src/compiler.rs +31 -19
  7. data/ext/gqlitedb/src/connection.rs +42 -7
  8. data/ext/gqlitedb/src/error.rs +3 -0
  9. data/ext/gqlitedb/src/functions/containers.rs +1 -1
  10. data/ext/gqlitedb/src/functions/path.rs +1 -1
  11. data/ext/gqlitedb/src/functions/scalar.rs +23 -0
  12. data/ext/gqlitedb/src/functions.rs +8 -0
  13. data/ext/gqlitedb/src/interpreter/evaluators.rs +10 -10
  14. data/ext/gqlitedb/src/interpreter/instructions.rs +3 -3
  15. data/ext/gqlitedb/src/lib.rs +1 -3
  16. data/ext/gqlitedb/src/parser/ast.rs +1 -0
  17. data/ext/gqlitedb/src/parser/gql.pest +3 -1
  18. data/ext/gqlitedb/src/parser/parser_impl.rs +8 -0
  19. data/ext/gqlitedb/src/prelude.rs +3 -0
  20. data/ext/gqlitedb/src/store/{pgql.rs → pgrx.rs} +2 -0
  21. data/ext/gqlitedb/src/store/postgres.rs +0 -0
  22. data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +117 -0
  23. data/ext/gqlitedb/src/store/sqlbase/sqlqueries.rs +62 -0
  24. data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +55 -0
  25. data/ext/gqlitedb/src/store/sqlbase/sqlvalue.rs +189 -0
  26. data/ext/gqlitedb/src/store/sqlbase.rs +456 -0
  27. data/ext/gqlitedb/src/store/sqlite.rs +271 -573
  28. data/ext/gqlitedb/src/store.rs +7 -5
  29. data/ext/gqlitedb/src/tests/templates/programs.rs +10 -10
  30. data/ext/gqlitedb/src/utils.rs +25 -0
  31. data/ext/gqlitedb/src/value/compare.rs +6 -0
  32. data/ext/gqlitedb/src/value.rs +18 -2
  33. data/ext/gqlitedb/templates/sql/sqlite/edge_select.sql +18 -18
  34. data/ext/gqlitedb/templates/sql/sqlite/edge_update.sql +3 -3
  35. data/ext/gqlitedb/templates/sql/sqlite/node_select.sql +6 -6
  36. data/ext/gqlitedb/templates/sql/sqlite/node_update.sql +3 -3
  37. data/ext/gqliterb/src/lib.rs +30 -2
  38. data/ext/graphcore/Cargo.toml +3 -2
  39. data/ext/graphcore/src/error.rs +2 -0
  40. data/ext/graphcore/src/lib.rs +2 -1
  41. data/ext/graphcore/src/prelude.rs +1 -1
  42. data/ext/graphcore/src/table.rs +1 -1
  43. data/ext/graphcore/src/timestamp.rs +104 -0
  44. data/ext/graphcore/src/value.rs +106 -23
  45. metadata +10 -7
  46. data/ext/gqlitedb/gqlite_bench_data/README.MD +0 -6
  47. data/ext/gqlitedb/gqlite_bench_data/scripts/generate_smaller_pokec.rb +0 -85
  48. data/ext/gqlitedb/gqlite_bench_data/scripts/to_efficient_pokec.rb +0 -34
  49. data/ext/graphcore/release.toml +0 -1
@@ -0,0 +1,456 @@
1
+ use std::collections::HashSet;
2
+
3
+ use crate::{prelude::*, store::EdgeResult, utils::hex};
4
+
5
+ mod sqlmetadata;
6
+ mod sqlqueries;
7
+ mod sqlstore;
8
+ mod sqlvalue;
9
+
10
+ pub(crate) use sqlmetadata::{SqlMetaDataQueries, SqlMetaDataStore};
11
+ pub(crate) use sqlqueries::SqlQueries;
12
+ pub(crate) use sqlstore::{Row, SqlStore};
13
+ pub(crate) use sqlvalue::{FromSqlValue, IntoBindings, SqlValue};
14
+
15
+ ccutils::alias!(pub(crate) PersistentKey, graph::Key, derive: Debug, PartialEq);
16
+
17
+ /// Implementation of a GQLite store for all type that implements the SqlStore trait
18
+ impl<TStore> store::Store for TStore
19
+ where
20
+ TStore: SqlStore + SqlMetaDataQueries + SqlQueries,
21
+ {
22
+ type TransactionBox = <Self as SqlStore>::TransactionBox;
23
+ fn begin_read(&self) -> Result<Self::TransactionBox>
24
+ {
25
+ <Self as SqlStore>::begin_sql_read(self)
26
+ }
27
+ fn begin_write(&self) -> Result<Self::TransactionBox>
28
+ {
29
+ <Self as SqlStore>::begin_sql_write(self)
30
+ }
31
+ fn graphs_list(&self, transaction: &mut Self::TransactionBox) -> Result<Vec<String>>
32
+ {
33
+ self.get_metadata_value_json(transaction, "graphs")
34
+ }
35
+ fn create_graph(
36
+ &self,
37
+ transaction: &mut Self::TransactionBox,
38
+ graph_name: impl AsRef<str>,
39
+ ignore_if_exists: bool,
40
+ ) -> Result<()>
41
+ {
42
+ let graph_name = graph_name.as_ref();
43
+ let mut graphs_list = self.graphs_list(transaction)?;
44
+ if graphs_list.iter().any(|s| s == graph_name)
45
+ {
46
+ if ignore_if_exists
47
+ {
48
+ return Ok(());
49
+ }
50
+ else
51
+ {
52
+ return Err(
53
+ StoreError::DuplicatedGraph {
54
+ graph_name: graph_name.to_owned(),
55
+ }
56
+ .into(),
57
+ );
58
+ }
59
+ }
60
+ self.execute_batch(transaction, Self::graph_create_query(graph_name)?)?;
61
+ graphs_list.push(graph_name.to_owned());
62
+ self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
63
+ Ok(())
64
+ }
65
+ fn drop_graph(
66
+ &self,
67
+ transaction: &mut Self::TransactionBox,
68
+ graph_name: impl AsRef<str>,
69
+ if_exists: bool,
70
+ ) -> Result<()>
71
+ {
72
+ let graph_name = graph_name.as_ref();
73
+ let mut graphs_list = self.graphs_list(transaction)?;
74
+ if graphs_list.iter().any(|s| s == graph_name)
75
+ {
76
+ self.execute_batch(transaction, Self::graph_delete(graph_name)?)?;
77
+ graphs_list.retain(|x| x != graph_name);
78
+ self.set_metadata_value_json(transaction, "graphs", &graphs_list)?;
79
+
80
+ Ok(())
81
+ }
82
+ else if if_exists
83
+ {
84
+ Ok(())
85
+ }
86
+ else
87
+ {
88
+ Err(
89
+ StoreError::UnknownGraph {
90
+ graph_name: graph_name.to_owned(),
91
+ }
92
+ .into(),
93
+ )
94
+ }
95
+ }
96
+ fn create_nodes<'a, T: IntoIterator<Item = &'a crate::graph::Node>>(
97
+ &self,
98
+ transaction: &mut Self::TransactionBox,
99
+ graph_name: impl AsRef<str>,
100
+ nodes_iter: T,
101
+ ) -> Result<()>
102
+ {
103
+ for x in nodes_iter
104
+ {
105
+ self.execute(
106
+ transaction,
107
+ Self::node_create_query(&graph_name)?.as_str(),
108
+ (
109
+ &x.key(),
110
+ &serde_json::to_string(x.labels())?,
111
+ &serde_json::to_string(x.properties())?,
112
+ ),
113
+ )?;
114
+ }
115
+ Ok(())
116
+ }
117
+ fn delete_nodes(
118
+ &self,
119
+ transaction: &mut Self::TransactionBox,
120
+ graph_name: impl AsRef<str>,
121
+ query: store::SelectNodeQuery,
122
+ detach: bool,
123
+ ) -> Result<()>
124
+ {
125
+ let graph_name = graph_name.as_ref();
126
+ let nodes = self.select_nodes(transaction, graph_name, query)?;
127
+ let nodes_keys: Vec<String> = nodes.into_iter().map(|x| hex(x.key())).collect();
128
+ if detach
129
+ {
130
+ self.execute(
131
+ transaction,
132
+ Self::edge_delete_by_nodes_query(graph_name, &nodes_keys)?,
133
+ (),
134
+ )?;
135
+ }
136
+ else
137
+ {
138
+ let count = self.query_row(
139
+ transaction,
140
+ Self::edge_count_for_nodes_query(graph_name, &nodes_keys)?,
141
+ (),
142
+ |row| row.get::<usize>(0),
143
+ )?;
144
+ if count > 0
145
+ {
146
+ return Err(error::RunTimeError::DeleteConnectedNode.into());
147
+ }
148
+ }
149
+ self.execute(
150
+ transaction,
151
+ Self::node_delete_query(graph_name, nodes_keys)?,
152
+ (),
153
+ )?;
154
+ Ok(())
155
+ }
156
+ fn update_node(
157
+ &self,
158
+ transaction: &mut Self::TransactionBox,
159
+ graph_name: impl AsRef<str>,
160
+ node: &crate::graph::Node,
161
+ ) -> Result<()>
162
+ {
163
+ self.execute(
164
+ transaction,
165
+ Self::node_update_query(graph_name)?,
166
+ (
167
+ &node.key(),
168
+ &serde_json::to_string(node.labels())?,
169
+ &serde_json::to_string(node.properties())?,
170
+ ),
171
+ )?;
172
+ Ok(())
173
+ }
174
+ fn select_nodes(
175
+ &self,
176
+ transaction: &mut Self::TransactionBox,
177
+ graph_name: impl AsRef<str>,
178
+ query: store::SelectNodeQuery,
179
+ ) -> Result<Vec<crate::graph::Node>>
180
+ {
181
+ let mut query_bindings = Vec::<SqlValue>::new();
182
+ let keys_var = query
183
+ .keys
184
+ .map(|keys| {
185
+ let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
186
+ query_bindings.push(serde_json::to_string(&hex_keys)?.into());
187
+ Ok::<_, Error>(query_bindings.len())
188
+ })
189
+ .transpose()?;
190
+ let labels_var = query
191
+ .labels
192
+ .map(|labels| {
193
+ query_bindings.push(serde_json::to_string(&labels)?.into());
194
+ Ok::<_, Error>(query_bindings.len())
195
+ })
196
+ .transpose()?;
197
+ let properties_var = query
198
+ .properties
199
+ .map(|properties| {
200
+ query_bindings.push(serde_json::to_string(&properties)?.into());
201
+ Ok::<_, Error>(query_bindings.len())
202
+ })
203
+ .transpose()?;
204
+ let mut nodes: Vec<graph::Node> = Default::default();
205
+ self.query_rows(
206
+ transaction,
207
+ Self::node_select_query(graph_name, keys_var, labels_var, properties_var)?,
208
+ query_bindings,
209
+ |row| {
210
+ let key: graph::Key = row.get::<graph::Key>(0)?;
211
+ let labels = serde_json::from_str(&row.get::<String>(1)?)?;
212
+ let properties = serde_json::from_str(&row.get::<String>(2)?)?;
213
+ nodes.push(graph::Node::new(key, labels, properties));
214
+ Ok(())
215
+ },
216
+ )?;
217
+
218
+ Ok(nodes)
219
+ }
220
+ fn create_edges<'a, T: IntoIterator<Item = &'a crate::graph::SinglePath>>(
221
+ &self,
222
+ transaction: &mut Self::TransactionBox,
223
+ graph_name: impl AsRef<str>,
224
+ edges_iter: T,
225
+ ) -> Result<()>
226
+ {
227
+ for x in edges_iter
228
+ {
229
+ self.execute(
230
+ transaction,
231
+ Self::edge_create_query(graph_name.as_ref())?,
232
+ (
233
+ &x.key(),
234
+ &serde_json::to_string(x.labels())?,
235
+ &serde_json::to_string(x.properties())?,
236
+ &x.source().key(),
237
+ &x.destination().key(),
238
+ ),
239
+ )?;
240
+ }
241
+ Ok(())
242
+ }
243
+ fn delete_edges(
244
+ &self,
245
+ transaction: &mut Self::TransactionBox,
246
+ graph_name: impl AsRef<str>,
247
+ query: store::SelectEdgeQuery,
248
+ directivity: crate::graph::EdgeDirectivity,
249
+ ) -> Result<()>
250
+ {
251
+ let graph_name = graph_name.as_ref();
252
+ let edges = self.select_edges(transaction, graph_name, query, directivity)?;
253
+ let edges_keys: Vec<String> = edges.into_iter().map(|x| hex(x.path.key())).collect();
254
+ self.execute(
255
+ transaction,
256
+ Self::edge_delete_query(graph_name, &edges_keys)?,
257
+ (),
258
+ )?;
259
+ Ok(())
260
+ }
261
+ fn update_edge(
262
+ &self,
263
+ transaction: &mut Self::TransactionBox,
264
+ graph_name: impl AsRef<str>,
265
+ edge: &crate::graph::Edge,
266
+ ) -> Result<()>
267
+ {
268
+ self.execute(
269
+ transaction,
270
+ Self::edge_update_query(graph_name)?,
271
+ (
272
+ &edge.key(),
273
+ serde_json::to_string(edge.labels())?,
274
+ serde_json::to_string(edge.properties())?,
275
+ ),
276
+ )?;
277
+ Ok(())
278
+ }
279
+ fn select_edges(
280
+ &self,
281
+ transaction: &mut Self::TransactionBox,
282
+ graph_name: impl AsRef<str>,
283
+ query: store::SelectEdgeQuery,
284
+ directivity: crate::graph::EdgeDirectivity,
285
+ ) -> Result<Vec<store::EdgeResult>>
286
+ {
287
+ if query.source.is_select_none() || query.destination.is_select_none()
288
+ {
289
+ return Ok(Default::default());
290
+ }
291
+ let (is_undirected, table_suffix) = match directivity
292
+ {
293
+ graph::EdgeDirectivity::Directed => (false, ""),
294
+ graph::EdgeDirectivity::Undirected => (true, "_undirected"),
295
+ };
296
+
297
+ let mut query_bindings = Vec::<SqlValue>::new();
298
+
299
+ // Edge queries
300
+ let edge_keys_var = query
301
+ .keys
302
+ .map(|keys| {
303
+ let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
304
+ query_bindings.push(serde_json::to_string(&hex_keys)?.into());
305
+ Ok::<_, Error>(query_bindings.len())
306
+ })
307
+ .transpose()?;
308
+ let edge_labels_var = query
309
+ .labels
310
+ .map(|labels| {
311
+ query_bindings.push(serde_json::to_string(&labels)?.into());
312
+ Ok::<_, Error>(query_bindings.len())
313
+ })
314
+ .transpose()?;
315
+ let edge_properties_var = query
316
+ .properties
317
+ .map(|properties| {
318
+ query_bindings.push(serde_json::to_string(&properties)?.into());
319
+ Ok::<_, Error>(query_bindings.len())
320
+ })
321
+ .transpose()?;
322
+
323
+ // Left node queries
324
+ let left_node_keys_var = query
325
+ .source
326
+ .keys
327
+ .map(|keys| {
328
+ let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
329
+ query_bindings.push(serde_json::to_string(&hex_keys)?.into());
330
+ Ok::<_, Error>(query_bindings.len())
331
+ })
332
+ .transpose()?;
333
+ let left_node_labels_var = query
334
+ .source
335
+ .labels
336
+ .map(|labels| {
337
+ query_bindings.push(serde_json::to_string(&labels)?.into());
338
+ Ok::<_, Error>(query_bindings.len())
339
+ })
340
+ .transpose()?;
341
+ let left_node_properties_var = query
342
+ .source
343
+ .properties
344
+ .map(|properties| {
345
+ query_bindings.push(serde_json::to_string(&properties)?.into());
346
+ Ok::<_, Error>(query_bindings.len())
347
+ })
348
+ .transpose()?;
349
+
350
+ // Right node queries
351
+ let right_node_keys_var = query
352
+ .destination
353
+ .keys
354
+ .map(|keys| {
355
+ let hex_keys = keys.iter().map(|key| hex(*key)).collect::<Vec<_>>();
356
+ query_bindings.push(serde_json::to_string(&hex_keys)?.into());
357
+ Ok::<_, Error>(query_bindings.len())
358
+ })
359
+ .transpose()?;
360
+ let right_node_labels_var = query
361
+ .destination
362
+ .labels
363
+ .map(|labels| {
364
+ query_bindings.push(serde_json::to_string(&labels)?.into());
365
+ Ok::<_, Error>(query_bindings.len())
366
+ })
367
+ .transpose()?;
368
+ let right_node_properties_var = query
369
+ .destination
370
+ .properties
371
+ .map(|properties| {
372
+ query_bindings.push(serde_json::to_string(&properties)?.into());
373
+ Ok::<_, Error>(query_bindings.len())
374
+ })
375
+ .transpose()?;
376
+
377
+ let mut edges: Vec<EdgeResult> = Default::default();
378
+ let mut edges_keys: HashSet<u128> = Default::default();
379
+
380
+ // Execute query
381
+ self.query_rows(
382
+ transaction,
383
+ Self::edge_select_query(
384
+ graph_name,
385
+ is_undirected,
386
+ table_suffix,
387
+ edge_keys_var,
388
+ edge_labels_var,
389
+ edge_properties_var,
390
+ left_node_keys_var,
391
+ left_node_labels_var,
392
+ left_node_properties_var,
393
+ right_node_keys_var,
394
+ right_node_labels_var,
395
+ right_node_properties_var,
396
+ )?,
397
+ query_bindings,
398
+ |row| {
399
+ let edge_key: graph::Key = row.get(0)?;
400
+ let n_left_key: graph::Key = row.get(4)?;
401
+ let n_right_key: graph::Key = row.get(7)?;
402
+
403
+ // This ensure that if (a)-[]->(a) the edge is returned only once. But matching [a]-[]-[b] return the edge twice.
404
+ if n_left_key == n_right_key && edges_keys.contains(&edge_key.uuid())
405
+ {
406
+ return Ok(());
407
+ }
408
+ edges_keys.insert(edge_key.uuid());
409
+ let edge_labels = serde_json::from_str(&row.get::<String>(1)?)?;
410
+ let edge_properties = serde_json::from_str(&row.get::<String>(2)?)?;
411
+
412
+ let n_left_labels = serde_json::from_str(&row.get::<String>(5)?)?;
413
+ let n_left_properties = serde_json::from_str(&row.get::<String>(6)?)?;
414
+
415
+ let n_right_labels = serde_json::from_str(&row.get::<String>(8)?)?;
416
+ let n_right_properties = serde_json::from_str(&row.get::<String>(9)?)?;
417
+
418
+ let source = graph::Node::new(n_left_key, n_left_labels, n_left_properties);
419
+ let destination = graph::Node::new(n_right_key, n_right_labels, n_right_properties);
420
+ let reversed = row.get::<u32>(3)? == 1;
421
+ let (source, destination) = if reversed
422
+ {
423
+ (destination, source)
424
+ }
425
+ else
426
+ {
427
+ (source, destination)
428
+ };
429
+
430
+ edges.push(EdgeResult {
431
+ path: graph::Path::new(edge_key, source, edge_labels, edge_properties, destination),
432
+ reversed,
433
+ });
434
+ Ok(())
435
+ },
436
+ )?;
437
+
438
+ Ok(edges)
439
+ }
440
+ fn compute_statistics(&self, transaction: &mut Self::TransactionBox)
441
+ -> Result<store::Statistics>
442
+ {
443
+ let (nodes_count, edges_count, labels_nodes_count, properties_count) = self.query_row(
444
+ transaction,
445
+ Self::compute_statistics_query("default")?,
446
+ (),
447
+ |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?, row.get(3)?)),
448
+ )?;
449
+ Ok(store::Statistics {
450
+ nodes_count,
451
+ edges_count,
452
+ labels_nodes_count,
453
+ properties_count,
454
+ })
455
+ }
456
+ }