Ensure index resources are properly deleted on index deletion (#2234)

This commit is contained in:
Emmanuel Keller 2023-07-10 09:24:47 +01:00 committed by GitHub
parent bb61ee7ff9
commit 75fc006c21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 590 additions and 52 deletions

View file

@ -118,13 +118,13 @@ impl<'a> IndexOperation<'a> {
}
fn get_non_unique_index_key(&self, v: &Array) -> key::index::Index {
key::index::new(
key::index::Index::new(
self.opt.ns(),
self.opt.db(),
&self.ix.what,
&self.ix.name,
v,
Some(&self.rid.id),
v.to_owned(),
Some(self.rid.id.to_owned()),
)
}
@ -145,7 +145,14 @@ impl<'a> IndexOperation<'a> {
}
fn get_unique_index_key(&self, v: &Array) -> key::index::Index {
key::index::new(self.opt.ns(), self.opt.db(), &self.ix.what, &self.ix.name, v, None)
key::index::Index::new(
self.opt.ns(),
self.opt.db(),
&self.ix.what,
&self.ix.name,
v.to_owned(),
None,
)
}
async fn index_unique(&self, run: &mut kvs::Transaction) -> Result<(), Error> {

View file

@ -198,8 +198,8 @@ impl NonUniqueEqualThingIterator {
v: &Value,
) -> Result<NonUniqueEqualThingIterator, Error> {
let v = Array::from(v.clone());
let beg = key::index::prefix_all_ids(opt.ns(), opt.db(), &ix.what, &ix.name, &v);
let end = key::index::suffix_all_ids(opt.ns(), opt.db(), &ix.what, &ix.name, &v);
let (beg, end) =
key::index::Index::range_all_ids(opt.ns(), opt.db(), &ix.what, &ix.name, &v);
Ok(Self {
beg,
end,
@ -230,7 +230,7 @@ pub(crate) struct UniqueEqualThingIterator {
impl UniqueEqualThingIterator {
fn new(opt: &Options, ix: &DefineIndexStatement, v: &Value) -> Result<Self, Error> {
let v = Array::from(v.clone());
let key = key::index::new(opt.ns(), opt.db(), &ix.what, &ix.name, &v, None).into();
let key = key::index::Index::new(opt.ns(), opt.db(), &ix.what, &ix.name, v, None).into();
Ok(Self {
key: Some(key),
})

View file

@ -1,6 +1,7 @@
use crate::idx::ft::terms::TermId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bc<'a> {
@ -37,6 +38,49 @@ impl<'a> Bc<'a> {
term_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'c',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::btree::NodeId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bd<'a> {
@ -43,6 +44,49 @@ impl<'a> Bd<'a> {
node_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'd',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -2,6 +2,7 @@ use crate::idx::ft::docids::DocId;
use crate::idx::ft::terms::TermId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bf<'a> {
@ -47,6 +48,49 @@ impl<'a> Bf<'a> {
doc_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'f',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::btree::NodeId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bi<'a> {
@ -37,6 +38,49 @@ impl<'a> Bi<'a> {
node_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'i',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::ft::docids::DocId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bk<'a> {
@ -37,6 +38,49 @@ impl<'a> Bk<'a> {
doc_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'k',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::btree::NodeId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bl<'a> {
@ -43,6 +44,49 @@ impl<'a> Bl<'a> {
node_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'l',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -2,6 +2,7 @@ use crate::idx::ft::docids::DocId;
use crate::idx::ft::terms::TermId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bo<'a> {
@ -47,6 +48,49 @@ impl<'a> Bo<'a> {
term_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'o',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::btree::NodeId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bp<'a> {
@ -43,6 +44,49 @@ impl<'a> Bp<'a> {
node_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
pub fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'p',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::btree::NodeId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bt<'a> {
@ -43,6 +44,49 @@ impl<'a> Bt<'a> {
node_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b't',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -1,6 +1,7 @@
use crate::idx::ft::terms::TermId;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
pub struct Bu<'a> {
@ -37,6 +38,49 @@ impl<'a> Bu<'a> {
term_id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
__: u8,
_a: u8,
pub ns: &'a str,
_b: u8,
pub db: &'a str,
_c: u8,
pub tb: &'a str,
_d: u8,
_e: u8,
_f: u8,
pub ix: &'a str,
_g: u8,
}
impl<'a> Prefix<'a> {
fn new(ns: &'a str, db: &'a str, tb: &'a str, ix: &'a str) -> Self {
Self {
__: b'/',
_a: b'*',
ns,
_b: b'*',
db,
_c: b'*',
tb,
_d: b'!',
_e: b'b',
_f: b'u',
ix,
_g: b'*',
}
}
}
#[cfg(test)]

View file

@ -3,6 +3,7 @@ use crate::sql::array::Array;
use crate::sql::id::Id;
use derive::Key;
use serde::{Deserialize, Serialize};
use std::ops::Range;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Key)]
struct Prefix<'a> {
@ -79,41 +80,6 @@ pub struct Index<'a> {
pub id: Option<Id>,
}
pub fn new<'a>(
ns: &'a str,
db: &'a str,
tb: &'a str,
ix: &'a str,
fd: &Array,
id: Option<&Id>,
) -> Index<'a> {
Index::new(ns, db, tb, ix, fd.to_owned(), id.cloned())
}
pub fn prefix(ns: &str, db: &str, tb: &str, ix: &str) -> Vec<u8> {
let mut k = Prefix::new(ns, db, tb, ix).encode().unwrap();
k.extend_from_slice(&[0x00]);
k
}
pub fn suffix(ns: &str, db: &str, tb: &str, ix: &str) -> Vec<u8> {
let mut k = Prefix::new(ns, db, tb, ix).encode().unwrap();
k.extend_from_slice(&[0xff]);
k
}
pub fn prefix_all_ids(ns: &str, db: &str, tb: &str, ix: &str, fd: &Array) -> Vec<u8> {
let mut k = PrefixIds::new(ns, db, tb, ix, fd).encode().unwrap();
k.extend_from_slice(&[0x00]);
k
}
pub fn suffix_all_ids(ns: &str, db: &str, tb: &str, ix: &str, fd: &Array) -> Vec<u8> {
let mut k = PrefixIds::new(ns, db, tb, ix, fd).encode().unwrap();
k.extend_from_slice(&[0xff]);
k
}
impl<'a> Index<'a> {
pub fn new(
ns: &'a str,
@ -137,6 +103,22 @@ impl<'a> Index<'a> {
id,
}
}
pub fn range(ns: &str, db: &str, tb: &str, ix: &str) -> Range<Vec<u8>> {
let mut beg = Prefix::new(ns, db, tb, ix).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = Prefix::new(ns, db, tb, ix).encode().unwrap();
end.extend_from_slice(&[0xff]);
beg..end
}
pub fn range_all_ids(ns: &str, db: &str, tb: &str, ix: &str, fd: &Array) -> (Vec<u8>, Vec<u8>) {
let mut beg = PrefixIds::new(ns, db, tb, ix, fd).encode().unwrap();
beg.extend_from_slice(&[0x00]);
let mut end = PrefixIds::new(ns, db, tb, ix, fd).encode().unwrap();
end.extend_from_slice(&[0xff]);
(beg, end)
}
}
#[cfg(test)]

View file

@ -111,7 +111,6 @@ mod ctx;
mod doc;
mod exe;
mod fnc;
mod key;
mod vs;
pub mod sql;
@ -137,6 +136,8 @@ pub mod iam;
#[doc(hidden)]
pub mod idx;
#[doc(hidden)]
pub mod key;
#[doc(hidden)]
pub mod kvs;
#[doc(inline)]

View file

@ -21,7 +21,7 @@ use crate::sql::idiom::{Idiom, Idioms};
use crate::sql::index::Index;
use crate::sql::kind::{kind, Kind};
use crate::sql::permission::{permissions, Permissions};
use crate::sql::statements::UpdateStatement;
use crate::sql::statements::{RemoveIndexStatement, UpdateStatement};
use crate::sql::strand::strand_raw;
use crate::sql::tokenizer::{tokenizers, Tokenizer};
use crate::sql::value::{value, values, Value, Values};
@ -1310,9 +1310,7 @@ impl DefineIndexStatement {
let key = crate::key::ix::prefix(opt.ns(), opt.db(), &self.what);
run.clr(key).await?;
// Remove the index data
let beg = crate::key::index::prefix(opt.ns(), opt.db(), &self.what, &self.name);
let end = crate::key::index::suffix(opt.ns(), opt.db(), &self.what, &self.name);
run.delr(beg..end, u32::MAX).await?;
RemoveIndexStatement::delete_resources(&mut run, opt, &self.what, &self.name).await?;
// Release the transaction
drop(run);
// Force queries to run

View file

@ -3,6 +3,7 @@ use crate::dbs::Options;
use crate::dbs::{Level, Transaction};
use crate::doc::CursorDoc;
use crate::err::Error;
use crate::kvs;
use crate::sql::base::{base, base_or_scope, Base};
use crate::sql::comment::{mightbespace, shouldbespace};
use crate::sql::error::IResult;
@ -238,7 +239,7 @@ impl RemoveFunctionStatement {
}
}
impl fmt::Display for RemoveFunctionStatement {
impl Display for RemoveFunctionStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "REMOVE FUNCTION fn::{}", self.name)
}
@ -793,13 +794,45 @@ impl RemoveIndexStatement {
// Clear the cache
let key = crate::key::ix::prefix(opt.ns(), opt.db(), &self.what);
run.clr(key).await?;
// Remove the resource data
let beg = crate::key::index::prefix(opt.ns(), opt.db(), &self.what, &self.name);
let end = crate::key::index::suffix(opt.ns(), opt.db(), &self.what, &self.name);
run.delr(beg..end, u32::MAX).await?;
// Delete resource
Self::delete_resources(&mut run, opt, &self.what, &self.name).await?;
// Ok all good
Ok(Value::None)
}
// Remove the resource data (whatever the type of the index)
pub(crate) async fn delete_resources(
run: &mut kvs::Transaction,
opt: &Options,
tb: &str,
ix: &str,
) -> Result<(), Error> {
let rng = crate::key::index::Index::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bc::Bc::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bd::Bd::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bf::Bf::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bi::Bi::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bk::Bk::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bl::Bl::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bo::Bo::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bp::Bp::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let key = crate::key::bs::Bs::new(opt.ns(), opt.db(), tb, ix);
run.del(key).await?;
let rng = crate::key::bt::Bt::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
let rng = crate::key::bu::Bu::range(opt.ns(), opt.db(), tb, ix);
run.delr(rng, u32::MAX).await?;
Ok(())
}
}
impl Display for RemoveIndexStatement {

View file

@ -3,6 +3,18 @@ mod parse;
use parse::Parse;
use surrealdb::dbs::Session;
use surrealdb::err::Error;
use surrealdb::key::bc::Bc;
use surrealdb::key::bd::Bd;
use surrealdb::key::bf::Bf;
use surrealdb::key::bi::Bi;
use surrealdb::key::bk::Bk;
use surrealdb::key::bl::Bl;
use surrealdb::key::bo::Bo;
use surrealdb::key::bp::Bp;
use surrealdb::key::bs::Bs;
use surrealdb::key::bt::Bt;
use surrealdb::key::bu::Bu;
use surrealdb::key::index::Index;
use surrealdb::kvs::Datastore;
use surrealdb::sql::Value;
@ -73,3 +85,68 @@ async fn remove_statement_analyzer() -> Result<(), Error> {
assert_eq!(tmp, val);
Ok(())
}
macro_rules! check_empty_range {
($tx:expr, $rng:expr) => {{
let r = $tx.getr($rng, 1).await?;
assert!(r.is_empty());
}};
}
macro_rules! check_none_val {
($tx:expr, $key:expr) => {{
let r = $tx.get($key).await?;
assert!(r.is_none());
}};
}
#[tokio::test]
async fn remove_statement_index() -> Result<(), Error> {
let sql = "
DEFINE INDEX uniq_isbn ON book FIELDS isbn UNIQUE;
DEFINE INDEX idx_author ON book FIELDS author;
DEFINE ANALYZER simple TOKENIZERS blank,class FILTERS lowercase;
DEFINE INDEX ft_title ON book FIELDS title SEARCH ANALYZER simple BM25 HIGHLIGHTS;
CREATE book:1 SET title = 'Rust Web Programming', isbn = '978-1803234694', author = 'Maxwell Flitton';
REMOVE INDEX uniq_isbn ON book;
REMOVE INDEX idx_author ON book;
REMOVE INDEX ft_title ON book;
INFO FOR TABLE book;
";
let dbs = Datastore::new("memory").await?;
let ses = Session::for_kv().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 9);
for _ in 0..8 {
let tmp = res.remove(0).result;
assert!(tmp.is_ok());
}
// Check infos output
let tmp = res.remove(0).result?;
let val = Value::parse(
"{
events: {},
fields: {},
indexes: {},
tables: {},
}",
);
assert_eq!(tmp, val);
let mut tx = dbs.transaction(false, false).await?;
for ix in ["uniq_isbn", "idx_author", "ft_title"] {
check_empty_range!(&mut tx, Bc::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bd::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bf::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bi::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bk::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bl::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bo::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bp::range("test", "test", "book", ix));
check_none_val!(&mut tx, Bs::new("test", "test", "book", ix));
check_empty_range!(&mut tx, Bt::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Bu::range("test", "test", "book", ix));
check_empty_range!(&mut tx, Index::range("test", "test", "book", ix));
}
Ok(())
}