1use std::sync::Arc;
10
11use parking_lot::Mutex;
12use serde::{Deserialize, Serialize};
13
14use crate::catalog::{
15 CatalogFacade, CatalogIndexRow, ColumnStatsInput, ColumnStatsRow, EdgeRow, ForeignServerRow,
16 ForeignTableRow, GraphSnapshot, RelationIdentity, RelationKind, SchemaRow, SequenceOptions,
17 SequenceReservationResult, SequenceRow, SequenceSetValueResult, TableSchema, ViewRow,
18};
19use crate::{StorageBackendError, StorageBackendResult};
20
21use super::codec::{
22 decode_stored_document_value, decode_string, decode_value, doc_length_key,
23 doc_length_key_prefix, document_key_prefix, encode_stored_document_value, encode_value,
24 field_stats_key, field_stats_key_prefix, key_with_tag, posting_cluster_positions_field_prefix,
25 posting_cluster_positions_key_prefix, posting_cluster_score_field_prefix,
26 posting_cluster_score_key_prefix, posting_document_key, posting_document_key_prefix,
27 posting_field_prefix, posting_key_prefix, push_str, push_u64, read_str, read_u64,
28 reverse_posting_key, reverse_posting_key_prefix, single_str_key, string_value,
29 vector_field_prefix, vector_key_prefix,
30};
31use super::{
32 KeyValueBatch, KeyValueStore, TAG_ANALYZER, TAG_ANALYZER_DESCRIPTOR, TAG_CATALOG_INDEX,
33 TAG_COLUMN_STATS, TAG_EDGE, TAG_FIELD_ANALYZER_BINDING, TAG_FOREIGN_SERVER, TAG_FOREIGN_TABLE,
34 TAG_GRAPH_MEMBERSHIP, TAG_METADATA, TAG_MODEL, TAG_NAMED_GRAPH, TAG_PATH_INDEX, TAG_RELATION,
35 TAG_SCHEMA, TAG_SCORING_PARAMS, TAG_SEQUENCE, TAG_SEQUENCE_VALUE, TAG_TABLE,
36 TAG_TABLE_FIELD_ANALYZER, TAG_VERTEX, TAG_VIEW,
37};
38
39mod analyzers;
40pub(super) mod diskann;
41mod foreign;
42mod graph_access;
43mod graph_guards;
44mod graph_observations;
45mod graph_view;
46mod graphs;
47mod indexes;
48pub(super) mod keys;
49mod migration;
50mod models;
51mod occurrence_lifecycle;
52mod path_index_data;
53mod physical_indexes;
54mod record_revisions;
55mod records;
56mod relation_acl;
57mod relations;
58mod schema_table;
59mod sequences;
60mod table_data;
61mod tables;
62mod views;
63
64use keys::{
65 batch_put_or_keep_existing, batch_rekey_prefix, batch_rekey_prefix_or_keep_existing,
66 catalog_index_references_column, catalog_index_rename_column, column_stats_key,
67 column_stats_prefix, decode_catalog_relation_key, decode_relation_key, edge_key,
68 ensure_prefix_absent, graph_membership_graph_prefix, graph_membership_key,
69 graph_membership_prefix, load_single_string_rows, register_migration_relation, relation_key,
70 table_field_analyzer_field_prefix, table_field_analyzer_key, table_field_analyzer_prefix,
71 vertex_key,
72};
73use migration::{
74 apply_relation_migrations, collect_relation_migrations, validate_relation_parents,
75};
76use records::{
77 StoredCatalogIndex, StoredColumnStats, StoredEdge, StoredForeignServer, StoredForeignTable,
78 StoredRelation, StoredSequence, StoredSequenceValue, StoredVertex, StoredView,
79 STORED_FOREIGN_TABLE_SECURITY_VERSION,
80};
81
82#[derive(Clone)]
83pub struct KeyValueCatalog {
84 store: Arc<dyn KeyValueStore>,
85 graph_indexes_lock: Arc<Mutex<()>>,
86}
87
88impl KeyValueCatalog {
89 pub fn new(store: Arc<dyn KeyValueStore>) -> Self {
90 Self {
91 store,
92 graph_indexes_lock: Arc::new(Mutex::new(())),
93 }
94 }
95
96 pub fn store(&self) -> Arc<dyn KeyValueStore> {
97 Arc::clone(&self.store)
98 }
99}
100
101impl CatalogFacade for KeyValueCatalog {
102 fn record_revisions(
103 &self,
104 records: &[crate::catalog::CatalogRecordRef<'_>],
105 ) -> StorageBackendResult<Option<Vec<Option<crate::catalog::CatalogRecordRevision>>>> {
106 if !self.store.transaction_model().is_versioned() {
107 return Ok(None);
108 }
109 self.record_revisions_impl(records).map(Some)
110 }
111
112 fn transaction_model(&self) -> crate::StorageTransactionModel {
113 self.store.transaction_model()
114 }
115
116 fn transaction_affinity(&self) -> Option<crate::StorageSessionAffinity> {
117 self.store.transaction_affinity()
118 }
119
120 fn clear_path_index_data(&self, index: &str) -> StorageBackendResult<()> {
121 self.clear_path_index_data_impl(index)
122 }
123
124 fn save_path_index_pairs(
125 &self,
126 index: &str,
127 sequence: &str,
128 pairs: &[(u64, u64)],
129 ) -> StorageBackendResult<()> {
130 self.save_path_index_pairs_impl(index, sequence, pairs)
131 }
132
133 fn finish_path_index_data(
134 &self,
135 index: &str,
136 graph: &str,
137 definition: &str,
138 ) -> StorageBackendResult<()> {
139 self.finish_path_index_data_impl(index, graph, definition)
140 }
141
142 fn path_index_data_is_current(
143 &self,
144 index: &str,
145 definition: &str,
146 ) -> StorageBackendResult<bool> {
147 self.path_index_data_is_current_impl(index, definition)
148 }
149
150 fn path_index_pairs(
151 &self,
152 index: &str,
153 sequence: &str,
154 after: Option<(u64, u64)>,
155 limit: usize,
156 ) -> StorageBackendResult<Vec<(u64, u64)>> {
157 self.path_index_pairs_impl(index, sequence, after, limit)
158 }
159
160 fn graph_vertex(&self, id: u64) -> StorageBackendResult<Option<crate::GraphVertexRow>> {
161 self.graph_vertex_impl(id)
162 }
163
164 fn graph_edge(&self, id: u64) -> StorageBackendResult<Option<EdgeRow>> {
165 self.graph_edge_impl(id)
166 }
167
168 fn graph_entity_ids(
169 &self,
170 filter: crate::GraphEntityFilter<'_>,
171 after: Option<u64>,
172 limit: usize,
173 ) -> StorageBackendResult<Vec<u64>> {
174 self.graph_entity_ids_impl(filter, after, limit)
175 }
176
177 fn graph_entity_count(
178 &self,
179 filter: crate::GraphEntityFilter<'_>,
180 ) -> StorageBackendResult<u64> {
181 self.with_graph_read(|read| {
182 let mut after = None;
183 let mut count = 0_u64;
184 loop {
185 let ids = read.ids(filter, after, 256)?;
186 if ids.is_empty() {
187 return Ok(count);
188 }
189 after = ids.last().copied();
190 count = count
191 .checked_add(
192 u64::try_from(ids.len())
193 .map_err(|error| StorageBackendError::Other(error.to_string()))?,
194 )
195 .ok_or_else(|| {
196 StorageBackendError::Other("graph entity count overflow".into())
197 })?;
198 }
199 })
200 }
201
202 fn graph_entity_max_id(
203 &self,
204 kind: crate::GraphEntityKind,
205 ) -> StorageBackendResult<Option<u64>> {
206 self.with_graph_read(|read| {
207 let filter = crate::GraphEntityFilter::new(kind, None);
208 let mut after = None;
209 loop {
210 let ids = read.ids(filter, after, 256)?;
211 if ids.is_empty() {
212 return Ok(after);
213 }
214 after = ids.last().copied();
215 }
216 })
217 }
218
219 fn graph_entity_memberships(
220 &self,
221 kind: crate::GraphEntityKind,
222 id: u64,
223 ) -> StorageBackendResult<Vec<String>> {
224 self.graph_entity_memberships_impl(kind, id)
225 }
226
227 fn graph_has_membership(
228 &self,
229 kind: crate::GraphEntityKind,
230 id: u64,
231 graph: &str,
232 ) -> StorageBackendResult<bool> {
233 self.store
234 .contains_key(&graph_membership_key(kind.as_str(), id, graph)?)
235 }
236
237 fn set_metadata(&self, key: &str, value: &str) -> StorageBackendResult<()> {
238 self.set_metadata_impl(key, value)
239 }
240
241 fn delete_metadata(&self, key: &str) -> StorageBackendResult<()> {
242 self.delete_metadata_impl(key)
243 }
244
245 fn get_metadata(&self, key: &str) -> StorageBackendResult<Option<String>> {
246 self.get_metadata_impl(key)
247 }
248
249 fn metadata_has_private_changes(&self, key: &str) -> StorageBackendResult<bool> {
250 self.metadata_has_private_changes_impl(key)
251 }
252 fn metadata_with_prefix(&self, prefix: &str) -> StorageBackendResult<Vec<(String, String)>> {
253 self.metadata_with_prefix_impl(prefix)
254 }
255
256 fn save_statistics_maintenance(
257 &self,
258 table: &str,
259 state: &crate::statistics_maintenance::StatisticsMaintenance,
260 ) -> StorageBackendResult<()> {
261 let key = single_str_key(
262 TAG_METADATA,
263 &crate::statistics_maintenance::StatisticsMaintenance::key(table),
264 )?;
265 self.store.with_mutation(&mut |read, batch| {
266 let value = state
267 .encode(read.control())
268 .map_err(crate::mvcc::VersionError::into_storage_error)?;
269 batch.replace_statistics_maintenance(&key, &value)
270 })
271 }
272
273 fn migrate_relation_namespace(&self) -> StorageBackendResult<()> {
274 self.migrate_relation_namespace_impl()?;
275 self.ensure_graph_lookup_indexes()
276 }
277
278 fn save_schema_row(&self, schema: &SchemaRow) -> StorageBackendResult<()> {
279 self.save_schema_row_impl(schema)
280 }
281
282 fn schema_has_private_changes(&self, name: &str) -> StorageBackendResult<bool> {
283 self.named_record_has_private_changes(TAG_SCHEMA, name)
284 }
285
286 fn drop_schema(&self, name: &str) -> StorageBackendResult<()> {
287 self.drop_schema_impl(name)
288 }
289
290 fn load_schema_rows(&self) -> StorageBackendResult<Vec<SchemaRow>> {
291 self.load_schema_rows_impl()
292 }
293
294 fn save_table(&self, schema: &TableSchema) -> StorageBackendResult<()> {
295 self.save_table_impl(schema)
296 }
297
298 fn load_tables(&self) -> StorageBackendResult<Vec<TableSchema>> {
299 self.load_tables_impl()
300 }
301
302 fn drop_table(&self, name: &str) -> StorageBackendResult<()> {
303 self.drop_table_impl(name)
304 }
305
306 fn drop_table_and_data(&self, name: &str) -> StorageBackendResult<()> {
307 self.drop_table_and_data_impl(name)
308 }
309
310 fn purge_table_data(&self, name: &str) -> StorageBackendResult<()> {
311 self.purge_table_data_impl(name)
312 }
313
314 fn rename_table_data(&self, from: &str, to: &str) -> StorageBackendResult<()> {
315 self.rename_table_data_impl(from, to)
316 }
317
318 fn drop_column_data(&self, table_name: &str, column_name: &str) -> StorageBackendResult<()> {
319 self.drop_column_data_impl(table_name, column_name)
320 }
321
322 fn rename_column_data(
323 &self,
324 table_name: &str,
325 from: &str,
326 to: &str,
327 ) -> StorageBackendResult<()> {
328 self.rename_column_data_impl(table_name, from, to)
329 }
330
331 fn save_model(&self, name: &str, json: &str) -> StorageBackendResult<()> {
332 self.save_model_impl(name, json)
333 }
334
335 fn load_models(&self) -> StorageBackendResult<Vec<(String, String)>> {
336 self.load_models_impl()
337 }
338
339 fn load_model(&self, name: &str) -> StorageBackendResult<Option<String>> {
340 self.load_model_impl(name)
341 }
342
343 fn drop_model(&self, name: &str) -> StorageBackendResult<()> {
344 self.drop_model_impl(name)
345 }
346
347 fn save_scoring_params(&self, name: &str, params_json: &str) -> StorageBackendResult<()> {
348 self.save_scoring_params_impl(name, params_json)
349 }
350
351 fn load_scoring_params(&self, name: &str) -> StorageBackendResult<Option<String>> {
352 self.load_scoring_params_impl(name)
353 }
354
355 fn load_all_scoring_params(&self) -> StorageBackendResult<Vec<(String, String)>> {
356 self.load_all_scoring_params_impl()
357 }
358
359 fn drop_scoring_params(&self, name: &str) -> StorageBackendResult<()> {
360 self.drop_scoring_params_impl(name)
361 }
362
363 fn create_sequence_row(&self, sequence: &SequenceRow) -> StorageBackendResult<bool> {
364 self.create_sequence_row_impl(sequence)
365 }
366
367 fn replace_sequence_row(&self, sequence: &SequenceRow) -> StorageBackendResult<bool> {
368 self.replace_sequence_row_impl(sequence)
369 }
370
371 fn rename_sequence_row(&self, from: &str, to: &str) -> StorageBackendResult<bool> {
372 self.rename_sequence_row_impl(from, to)
373 }
374
375 fn drop_sequence_row(&self, name: &str) -> StorageBackendResult<bool> {
376 self.drop_sequence_row_impl(name)
377 }
378
379 fn load_sequence_rows(&self) -> StorageBackendResult<Vec<SequenceRow>> {
380 self.load_sequence_rows_impl()
381 }
382
383 fn sequence_has_private_changes(
384 &self,
385 relation: &RelationIdentity,
386 _object_id: [u8; 16],
387 ) -> StorageBackendResult<bool> {
388 self.sequence_has_private_changes_impl(relation)
389 }
390
391 fn sequence_value_has_private_changes(
392 &self,
393 object_id: [u8; 16],
394 definition_generation: [u8; 16],
395 ) -> StorageBackendResult<bool> {
396 self.sequence_value_has_private_changes_impl(object_id, definition_generation)
397 }
398
399 fn migrate_sequence_values(&self) -> StorageBackendResult<()> {
400 self.migrate_sequence_values_impl()
401 }
402
403 fn reserve_sequence_values(
404 &self,
405 name: &str,
406 object_id: [u8; 16],
407 definition_generation: [u8; 16],
408 ) -> StorageBackendResult<SequenceReservationResult> {
409 self.reserve_sequence_values_impl(name, object_id, definition_generation)
410 }
411
412 fn set_sequence_value(
413 &self,
414 name: &str,
415 object_id: [u8; 16],
416 definition_generation: [u8; 16],
417 value: i64,
418 called: bool,
419 log_count: i64,
420 ) -> StorageBackendResult<SequenceSetValueResult> {
421 self.set_sequence_value_impl(
422 name,
423 object_id,
424 definition_generation,
425 value,
426 called,
427 log_count,
428 )
429 }
430
431 fn log_sequence_values(
432 &self,
433 name: &str,
434 object_id: [u8; 16],
435 definition_generation: [u8; 16],
436 expected: (i64, bool),
437 logged: crate::catalog::SequenceValuePosition,
438 ) -> StorageBackendResult<crate::catalog::SequenceLogResult> {
439 self.log_sequence_values_impl(name, object_id, definition_generation, expected, logged)
440 }
441
442 fn save_view(&self, view: &ViewRow) -> StorageBackendResult<()> {
443 self.save_view_impl(view)
444 }
445
446 fn rename_view(
447 &self,
448 from: &RelationIdentity,
449 to: &RelationIdentity,
450 ) -> StorageBackendResult<bool> {
451 self.rename_view_impl(from, to)
452 }
453
454 fn drop_view(&self, relation: &RelationIdentity) -> StorageBackendResult<bool> {
455 self.drop_view_impl(relation)
456 }
457
458 fn load_views(&self) -> StorageBackendResult<Vec<ViewRow>> {
459 self.load_views_impl()
460 }
461
462 fn save_named_graph(&self, name: &str) -> StorageBackendResult<()> {
463 self.save_named_graph_impl(name)
464 }
465 fn guard_graph_definition(&self, graph: Option<&str>) -> StorageBackendResult<()> {
466 self.guard_graph_definition_impl(graph)
467 }
468 fn load_named_graph_snapshot(&self, name: &str) -> StorageBackendResult<Option<GraphSnapshot>> {
469 let (mut result, namespace) =
470 self.with_graph_read(|read| Ok((read.snapshot(name)?, read.identifier_namespace()?)))?;
471 if let (Some(snapshot), Some(allocator)) =
472 (result.as_mut(), self.store.identifier_allocator())
473 {
474 snapshot.label_registry_json = crate::catalog::graph_identifiers::export_registry(
475 &snapshot.label_registry_json,
476 name,
477 namespace,
478 |key| allocator.identifier_watermark(key),
479 )?;
480 }
481 Ok(result)
482 }
483
484 fn drop_named_graph(&self, name: &str) -> StorageBackendResult<()> {
485 self.drop_named_graph_impl(name)
486 }
487
488 fn load_named_graphs(&self) -> StorageBackendResult<Vec<String>> {
489 self.load_named_graphs_impl()
490 }
491 fn named_graph_exists(&self, name: &str) -> StorageBackendResult<bool> {
492 self.store
493 .contains_key(&single_str_key(TAG_NAMED_GRAPH, name)?)
494 }
495
496 fn save_vertex(
497 &self,
498 vertex_id: u64,
499 label: &str,
500 properties_json: &str,
501 ) -> StorageBackendResult<()> {
502 self.save_vertex_impl(vertex_id, label, properties_json)
503 }
504
505 fn delete_vertex(&self, vertex_id: u64) -> StorageBackendResult<()> {
506 self.delete_vertex_impl(vertex_id)
507 }
508
509 fn load_vertices(&self) -> StorageBackendResult<Vec<(u64, String, String)>> {
510 self.load_vertices_impl()
511 }
512
513 fn save_edge(
514 &self,
515 edge_id: u64,
516 source_id: u64,
517 target_id: u64,
518 label: &str,
519 properties_json: &str,
520 ) -> StorageBackendResult<()> {
521 self.save_edge_impl(edge_id, source_id, target_id, label, properties_json)
522 }
523
524 fn delete_edge(&self, edge_id: u64) -> StorageBackendResult<()> {
525 self.delete_edge_impl(edge_id)
526 }
527
528 fn load_edges(&self) -> StorageBackendResult<Vec<EdgeRow>> {
529 self.load_edges_impl()
530 }
531
532 fn save_graph_membership(
533 &self,
534 entity_type: &str,
535 entity_id: u64,
536 graph_name: &str,
537 ) -> StorageBackendResult<()> {
538 self.save_graph_membership_impl(entity_type, entity_id, graph_name)
539 }
540
541 fn delete_graph_membership(
542 &self,
543 entity_type: &str,
544 entity_id: u64,
545 graph_name: &str,
546 ) -> StorageBackendResult<()> {
547 self.delete_graph_membership_impl(entity_type, entity_id, graph_name)
548 }
549
550 fn delete_graph_membership_for_graph(&self, graph_name: &str) -> StorageBackendResult<()> {
551 self.delete_graph_membership_for_graph_impl(graph_name)
552 }
553
554 fn load_graph_memberships(&self) -> StorageBackendResult<Vec<(String, u64, String)>> {
555 self.load_graph_memberships_impl()
556 }
557
558 fn purge_orphan_graph_entities(&self) -> StorageBackendResult<()> {
559 self.purge_orphan_graph_entities_impl()
560 }
561
562 fn replace_named_graph(
563 &self,
564 graph_name: &str,
565 snapshot: &GraphSnapshot,
566 ) -> StorageBackendResult<()> {
567 self.replace_named_graph_impl(graph_name, snapshot)
568 }
569
570 fn drop_named_graph_data(&self, graph_name: &str) -> StorageBackendResult<()> {
571 self.drop_named_graph_data_impl(graph_name)
572 }
573
574 fn save_analyzer(&self, name: &str, config_json: &str) -> StorageBackendResult<()> {
575 self.save_analyzer_impl(name, config_json)
576 }
577
578 fn drop_analyzer(&self, name: &str) -> StorageBackendResult<()> {
579 self.drop_analyzer_impl(name)
580 }
581
582 fn load_analyzers(&self) -> StorageBackendResult<Vec<(String, String)>> {
583 self.load_analyzers_impl()
584 }
585
586 fn save_analyzer_revision(
587 &self,
588 name: &str,
589 config_json: &str,
590 descriptor_json: &str,
591 ) -> StorageBackendResult<()> {
592 self.save_analyzer_revision_impl(name, config_json, descriptor_json)
593 }
594
595 fn load_analyzer_descriptors(&self) -> StorageBackendResult<Vec<(String, String)>> {
596 load_single_string_rows(self.store.as_ref(), TAG_ANALYZER_DESCRIPTOR)
597 }
598
599 fn replace_table_field_analyzer_binding(
600 &self,
601 table: &str,
602 field: &str,
603 phase: &str,
604 name: &str,
605 binding_json: &str,
606 ) -> StorageBackendResult<()> {
607 self.replace_table_field_analyzer_binding_impl(table, field, phase, name, binding_json)
608 }
609
610 fn load_table_field_analyzer_bindings(
611 &self,
612 ) -> StorageBackendResult<Vec<(String, String, String)>> {
613 self.load_table_field_analyzer_bindings_impl()
614 }
615
616 fn save_table_field_analyzer(
617 &self,
618 table_name: &str,
619 field: &str,
620 phase: &str,
621 analyzer_name: &str,
622 ) -> StorageBackendResult<()> {
623 self.save_table_field_analyzer_impl(table_name, field, phase, analyzer_name)
624 }
625
626 fn replace_table_field_analyzer(
627 &self,
628 table_name: &str,
629 field: &str,
630 phase: &str,
631 analyzer_name: &str,
632 ) -> StorageBackendResult<()> {
633 self.replace_table_field_analyzer_impl(table_name, field, phase, analyzer_name)
634 }
635
636 fn drop_table_field_analyzer_field(
637 &self,
638 table_name: &str,
639 field: &str,
640 ) -> StorageBackendResult<()> {
641 self.drop_table_field_analyzer_field_impl(table_name, field)
642 }
643
644 fn drop_table_field_analyzers(&self, table_name: &str) -> StorageBackendResult<()> {
645 self.drop_table_field_analyzers_impl(table_name)
646 }
647
648 fn load_table_field_analyzers(
649 &self,
650 ) -> StorageBackendResult<Vec<(String, String, String, String)>> {
651 self.load_table_field_analyzers_impl()
652 }
653
654 fn save_foreign_server(
655 &self,
656 name: &str,
657 fdw_type: &str,
658 options_json: &str,
659 ) -> StorageBackendResult<()> {
660 self.save_foreign_server_impl(name, fdw_type, options_json)
661 }
662
663 fn drop_foreign_server(&self, name: &str) -> StorageBackendResult<()> {
664 self.drop_foreign_server_impl(name)
665 }
666
667 fn load_foreign_servers(&self) -> StorageBackendResult<Vec<(String, String, String)>> {
668 self.load_foreign_servers_impl()
669 }
670
671 fn save_foreign_server_row(&self, row: &ForeignServerRow) -> StorageBackendResult<()> {
672 self.save_foreign_server_row_impl(row)
673 }
674
675 fn load_foreign_server_rows(&self) -> StorageBackendResult<Vec<ForeignServerRow>> {
676 self.load_foreign_server_rows_impl()
677 }
678
679 fn save_foreign_table(&self, row: &ForeignTableRow) -> StorageBackendResult<()> {
680 self.save_foreign_table_impl(row)
681 }
682
683 fn rename_foreign_table(
684 &self,
685 from: &RelationIdentity,
686 to: &RelationIdentity,
687 ) -> StorageBackendResult<bool> {
688 self.rename_foreign_table_impl(from, to)
689 }
690
691 fn update_foreign_table_security(
692 &self,
693 relation: &RelationIdentity,
694 security: &crate::RelationSecurityRow,
695 ) -> StorageBackendResult<bool> {
696 self.update_foreign_table_security_impl(relation, security)
697 }
698
699 fn drop_foreign_table(&self, relation: &RelationIdentity) -> StorageBackendResult<()> {
700 self.drop_foreign_table_impl(relation)
701 }
702
703 fn load_foreign_tables(&self) -> StorageBackendResult<Vec<ForeignTableRow>> {
704 self.load_foreign_tables_impl()
705 }
706
707 fn save_catalog_index_row(&self, index: &CatalogIndexRow) -> StorageBackendResult<()> {
708 self.save_catalog_index_impl(index)
709 }
710
711 fn drop_catalog_index(&self, relation: &RelationIdentity) -> StorageBackendResult<()> {
712 self.drop_catalog_index_impl(relation)
713 }
714
715 fn drop_catalog_indexes_for_table(&self, table_name: &str) -> StorageBackendResult<()> {
716 self.drop_catalog_indexes_for_table_impl(table_name)
717 }
718
719 fn load_catalog_indexes(&self) -> StorageBackendResult<Vec<CatalogIndexRow>> {
720 self.load_catalog_indexes_impl()
721 }
722
723 fn save_path_index(
724 &self,
725 graph_name: &str,
726 label_sequences_json: &str,
727 ) -> StorageBackendResult<()> {
728 self.save_path_index_impl(graph_name, label_sequences_json)
729 }
730
731 fn drop_path_index(&self, graph_name: &str) -> StorageBackendResult<()> {
732 self.drop_path_index_impl(graph_name)
733 }
734
735 fn load_path_indexes(&self) -> StorageBackendResult<Vec<(String, String)>> {
736 self.load_path_indexes_impl()
737 }
738
739 fn save_column_stats(&self, stats: ColumnStatsInput<'_>) -> StorageBackendResult<()> {
740 self.save_column_stats_impl(stats)
741 }
742
743 fn replace_column_stats(
744 &self,
745 table_name: &str,
746 stats: &[ColumnStatsInput<'_>],
747 ) -> StorageBackendResult<()> {
748 self.replace_column_stats_impl(table_name, stats)
749 }
750
751 fn load_column_stats(&self, table_name: &str) -> StorageBackendResult<Vec<ColumnStatsRow>> {
752 self.load_column_stats_impl(table_name)
753 }
754
755 fn delete_column_stats(&self, table_name: &str) -> StorageBackendResult<()> {
756 self.delete_column_stats_impl(table_name)
757 }
758}
759
760#[cfg(test)]
761mod tests;