[Bug fix] Index creation schemafull checks (#4091)

This commit is contained in:
Emmanuel Keller 2024-05-24 19:09:10 +01:00 committed by GitHub
parent bbab9fbee4
commit 3ccadb0740
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 63 additions and 8 deletions

View file

@ -5,7 +5,7 @@ use crate::err::Error;
use crate::iam::{Action, ResourceKind};
use crate::sql::statements::info::InfoStructure;
use crate::sql::{
statements::UpdateStatement, Base, Ident, Idioms, Index, Object, Strand, Value, Values,
statements::UpdateStatement, Base, Ident, Idioms, Index, Object, Part, Strand, Value, Values,
};
use derive::Store;
use reblessive::tree::Stk;
@ -52,6 +52,29 @@ impl DefineIndexStatement {
value: self.name.to_string(),
});
}
// If we are strict, check that the table exists
run.check_ns_db_tb(opt.ns(), opt.db(), &self.what, opt.strict).await?;
// Does the table exists?
match run.get_and_cache_tb(opt.ns(), opt.db(), &self.what).await {
Ok(db) => {
// Are we SchemaFull?
if db.full {
// Check that the fields exists
for idiom in self.cols.iter() {
if let Some(Part::Field(id)) = idiom.first() {
run.get_tb_field(opt.ns(), opt.db(), &self.what, id).await?;
}
}
}
}
// If the TB was not found, we're fine
Err(Error::TbNotFound {
..
}) => {}
// Any other error should be returned
Err(e) => return Err(e),
}
// Process the statement
let key = crate::key::table::ix::new(opt.ns(), opt.db(), &self.what, &self.name);
run.add_ns(opt.ns(), opt.strict).await?;

View file

@ -854,11 +854,7 @@ async fn define_statement_index_multiple() -> Result<(), Error> {
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());
skip_ok(res, 2)?;
//
let tmp = res.remove(0).result?;
let val = Value::parse(
@ -1236,6 +1232,39 @@ async fn define_statement_index_multiple_unique_embedded_multiple() -> Result<()
Ok(())
}
#[tokio::test]
async fn define_statement_index_on_schemafull_without_permission() -> Result<(), Error> {
let sql = "
DEFINE TABLE test SCHEMAFULL PERMISSIONS NONE;
DEFINE INDEX idx ON test FIELDS foo;
";
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test").with_db("test");
let mut res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 2);
//
skip_ok(&mut res, 1)?;
//
let tmp = res.remove(0).result;
let s = format!("{:?}", tmp);
assert!(
tmp.is_err_and(|e| {
if let Error::FdNotFound {
value,
} = e
{
assert_eq!(value, "foo", "Wrong field: {value}");
true
} else {
false
}
}),
"Expected error, but got: {:?}",
s
);
Ok(())
}
#[tokio::test]
async fn define_statement_analyzer() -> Result<(), Error> {
let sql = r#"

View file

@ -197,8 +197,11 @@ pub fn with_enough_stack(
#[allow(dead_code)]
pub fn skip_ok(res: &mut Vec<Response>, skip: usize) -> Result<(), Error> {
for _ in 0..skip {
let _ = res.remove(0).result?;
for i in 0..skip {
let r = res.remove(0).result;
let _ = r.is_err_and(|e| {
panic!("Statement #{i} fails with: {e}");
});
}
Ok(())
}