(
&mut self,
task: &ExecutionTask,
tid: u64,
collection: &str,
document_id: &str,
surrogate: Surrogate,
returning: Option<&ReturningSpec>,
)
| 16 | |
| 17 | impl CoreLoop { |
| 18 | pub(in crate::data::executor) fn execute_point_delete( |
| 19 | &mut self, |
| 20 | task: &ExecutionTask, |
| 21 | tid: u64, |
| 22 | collection: &str, |
| 23 | document_id: &str, |
| 24 | surrogate: Surrogate, |
| 25 | returning: Option<&ReturningSpec>, |
| 26 | ) -> Response { |
| 27 | let row_key = surrogate_to_doc_id(surrogate); |
| 28 | let row_key = row_key.as_str(); |
| 29 | debug!(core = self.core_id, %collection, %document_id, "point delete"); |
| 30 | |
| 31 | // On bitemporal collections: append a doc tombstone + versioned |
| 32 | // index tombstones for every current field value. `prior` is the |
| 33 | // pre-delete body so the Event Plane sees `old_value` correctly. |
| 34 | // Current-state-only indexes (text, graph, spatial, vector) are |
| 35 | // still cascaded below — they track "what exists now" regardless |
| 36 | // of bitemporal history. |
| 37 | let bitemporal = self.is_bitemporal(tid, collection); |
| 38 | let delete_result: crate::Result<Option<Vec<u8>>> = if bitemporal { |
| 39 | let prior = self.sparse.versioned_get_current(tid, collection, row_key); |
| 40 | match prior { |
| 41 | Ok(Some(body)) => { |
| 42 | let sys_from = self.bitemporal_now_ms(); |
| 43 | let res: crate::Result<()> = (|| { |
| 44 | let txn = self.sparse.begin_write()?; |
| 45 | self.sparse |
| 46 | .versioned_tombstone_in_txn(&txn, tid, collection, row_key, sys_from)?; |
| 47 | // Index tombstones: reflect every current value so |
| 48 | // `index_lookup_as_of` at or after `sys_from` skips |
| 49 | // this doc_id. |
| 50 | let config_key = (crate::types::TenantId::new(tid), collection.to_string()); |
| 51 | if let Some(config) = self.doc_configs.get(&config_key) |
| 52 | && let Some(doc) = doc_format::decode_document(&body) |
| 53 | { |
| 54 | for path in config.index_paths.clone() { |
| 55 | for v in crate::engine::document::store::extract_index_values( |
| 56 | &doc, |
| 57 | &path.path, |
| 58 | path.is_array, |
| 59 | ) { |
| 60 | let value = if path.case_insensitive { |
| 61 | v.to_lowercase() |
| 62 | } else { |
| 63 | v |
| 64 | }; |
| 65 | self.sparse.versioned_index_tombstone_in_txn( |
| 66 | &txn, tid, collection, &path.path, &value, row_key, |
| 67 | sys_from, |
| 68 | )?; |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | txn.commit().map_err(|e| crate::Error::Storage { |
| 73 | engine: "sparse".into(), |
| 74 | detail: format!("commit: {e}"), |
| 75 | })?; |
no test coverage detected