From 71adbe6f5a19fbc1931d6ed7471350889fc199e6 Mon Sep 17 00:00:00 2001 From: Tobie Morgan Hitchcock Date: Sun, 20 Aug 2023 02:07:15 +0100 Subject: [PATCH] Ensure foreign tables are deleted fully when removed (#2467) --- lib/src/sql/statements/remove/table.rs | 11 ++++ lib/tests/define.rs | 83 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/lib/src/sql/statements/remove/table.rs b/lib/src/sql/statements/remove/table.rs index 7c993e91..222b7aea 100644 --- a/lib/src/sql/statements/remove/table.rs +++ b/lib/src/sql/statements/remove/table.rs @@ -34,12 +34,23 @@ impl RemoveTableStatement { let mut run = txn.lock().await; // Clear the cache run.clear_cache(); + // Get the defined table + let tb = run.get_tb(opt.ns(), opt.db(), &self.name).await?; // Delete the definition let key = crate::key::database::tb::new(opt.ns(), opt.db(), &self.name); run.del(key).await?; // Remove the resource data let key = crate::key::table::all::new(opt.ns(), opt.db(), &self.name); run.delp(key, u32::MAX).await?; + // Check if this is a foreign table + if let Some(view) = &tb.view { + // Process each foreign table + for v in view.what.0.iter() { + // Save the view config + let key = crate::key::table::ft::new(opt.ns(), opt.db(), v, &self.name); + run.del(key).await?; + } + } // Ok all good Ok(Value::None) } diff --git a/lib/tests/define.rs b/lib/tests/define.rs index 50ffd3fd..336866cd 100644 --- a/lib/tests/define.rs +++ b/lib/tests/define.rs @@ -229,6 +229,89 @@ async fn define_statement_table_schemaful() -> Result<(), Error> { Ok(()) } +#[tokio::test] +async fn define_statement_table_foreigntable() -> Result<(), Error> { + let sql = " + DEFINE TABLE test SCHEMAFUL; + DEFINE TABLE view AS SELECT count() FROM test GROUP ALL; + INFO FOR DB; + INFO FOR TB test; + REMOVE TABLE view; + INFO FOR DB; + INFO FOR TB test; + "; + let dbs = Datastore::new("memory").await?; + let ses = Session::owner().with_ns("test").with_db("test"); + let res = &mut dbs.execute(sql, &ses, None).await?; + assert_eq!(res.len(), 7); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "{ + analyzers: {}, + tokens: {}, + functions: {}, + params: {}, + scopes: {}, + tables: { + test: 'DEFINE TABLE test SCHEMAFULL', + view: 'DEFINE TABLE view SCHEMALESS AS SELECT count() FROM test GROUP ALL', + }, + users: {}, + }", + ); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "{ + events: {}, + fields: {}, + tables: { view: 'DEFINE TABLE view SCHEMALESS AS SELECT count() FROM test GROUP ALL' }, + indexes: {}, + }", + ); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "{ + analyzers: {}, + tokens: {}, + functions: {}, + params: {}, + scopes: {}, + tables: { + test: 'DEFINE TABLE test SCHEMAFULL', + }, + users: {}, + }", + ); + assert_eq!(tmp, val); + // + let tmp = res.remove(0).result?; + let val = Value::parse( + "{ + events: {}, + fields: {}, + tables: {}, + indexes: {}, + }", + ); + assert_eq!(tmp, val); + // + Ok(()) +} + #[tokio::test] async fn define_statement_event() -> Result<(), Error> { let sql = "