diff --git a/index-scheduler/src/batch.rs b/index-scheduler/src/batch.rs index f6b4f1ed1..c54be3338 100644 --- a/index-scheduler/src/batch.rs +++ b/index-scheduler/src/batch.rs @@ -74,6 +74,7 @@ pub(crate) enum Batch { IndexDeletion { index_uid: String, tasks: Vec, + index_has_been_created: bool, }, IndexSwap { task: Task, @@ -444,6 +445,7 @@ impl IndexScheduler { } BatchKind::IndexDeletion { ids } => Ok(Some(Batch::IndexDeletion { index_uid, + index_has_been_created: must_create_index, tasks: self.get_existing_tasks(rtxn, ids)?, })), BatchKind::IndexSwap { id } => { @@ -796,18 +798,25 @@ impl IndexScheduler { } Batch::IndexDeletion { index_uid, + index_has_been_created, mut tasks, } => { let wtxn = self.env.write_txn()?; - let number_of_documents = { + // it's possible that the index doesn't exist + let number_of_documents = || -> Result { let index = self.index_mapper.index(&wtxn, &index_uid)?; let index_rtxn = index.read_txn()?; - index.number_of_documents(&index_rtxn)? - }; + Ok(index.number_of_documents(&index_rtxn)?) + }() + .unwrap_or_default(); // The write transaction is directly owned and commited inside. - self.index_mapper.delete_index(wtxn, &index_uid)?; + match self.index_mapper.delete_index(wtxn, &index_uid) { + Ok(()) => (), + Err(Error::IndexNotFound(_)) if index_has_been_created => (), + Err(e) => return Err(e), + } // We set all the tasks details to the default value. for task in &mut tasks { diff --git a/index-scheduler/src/lib.rs b/index-scheduler/src/lib.rs index 234ff7451..5faedcb5d 100644 --- a/index-scheduler/src/lib.rs +++ b/index-scheduler/src/lib.rs @@ -1327,6 +1327,45 @@ mod tests { snapshot!(snapshot_index_scheduler(&index_scheduler), name: "second_swap_processed"); } + #[test] + fn document_addition_and_index_deletion_on_unexisting_index() { + let (index_scheduler, handle) = IndexScheduler::test(true); + + let content = r#" + { + "id": 1, + "doggo": "bob" + }"#; + + let (uuid, mut file) = index_scheduler.create_update_file_with_uuid(0).unwrap(); + let documents_count = + meilisearch_types::document_formats::read_json(content.as_bytes(), file.as_file_mut()) + .unwrap() as u64; + file.persist().unwrap(); + index_scheduler + .register(KindWithContent::DocumentImport { + index_uid: S("doggos"), + primary_key: Some(S("id")), + method: ReplaceDocuments, + content_file: uuid, + documents_count, + allow_index_creation: true, + }) + .unwrap(); + index_scheduler + .register(KindWithContent::IndexDeletion { + index_uid: S("doggos"), + }) + .unwrap(); + + snapshot!(snapshot_index_scheduler(&index_scheduler)); + + handle.wait_till(Breakpoint::Start); // before anything happens. + handle.wait_till(Breakpoint::Start); // after the execution of the two tasks in a single batch. + + snapshot!(snapshot_index_scheduler(&index_scheduler)); + } + #[macro_export] macro_rules! debug_snapshot { ($value:expr, @$snapshot:literal) => {{