Skip to content

Commit 8f39137

Browse files
committed
chore: disallow DDL in multi-statement run
1 parent 071732e commit 8f39137

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/db.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,13 +374,21 @@ impl<S: Storage> Database<S> {
374374
.state
375375
.prepare_all(sql)
376376
.map_err(|err| err.with_sql_context(sql))?;
377-
let is_write = statements
377+
let has_ddl = statements
378378
.iter()
379-
.try_fold(false, |is_write, stmt| {
380-
Ok::<_, DatabaseError>(is_write || matches!(command_type(stmt)?, CommandType::DDL))
379+
.try_fold(false, |has_ddl, stmt| {
380+
Ok::<_, DatabaseError>(has_ddl || matches!(command_type(stmt)?, CommandType::DDL))
381381
})
382382
.map_err(|err| err.with_sql_context(sql))?;
383-
let _guard = if is_write {
383+
384+
if statements.len() > 1 && has_ddl {
385+
return Err(DatabaseError::UnsupportedStmt(
386+
"DDL is not allowed in multi-statement execution".to_string(),
387+
)
388+
.with_sql_context(sql));
389+
}
390+
391+
let _guard = if has_ddl {
384392
MetaDataLock::Write(self.mdl.write_arc())
385393
} else {
386394
MetaDataLock::Read(self.mdl.read_arc())
@@ -802,6 +810,25 @@ pub(crate) mod test {
802810
Ok(())
803811
}
804812

813+
#[test]
814+
fn test_run_multi_statement_disallow_ddl() -> Result<(), DatabaseError> {
815+
let temp_dir = TempDir::new().expect("unable to create temporary working directory");
816+
let kite_sql = DataBaseBuilder::path(temp_dir.path()).build()?;
817+
818+
let err = match kite_sql.run("create table t_multi_ddl (a int primary key); select 1") {
819+
Ok(_) => panic!("multi-statement execution with DDL should be rejected"),
820+
Err(err) => err,
821+
};
822+
match err {
823+
DatabaseError::UnsupportedStmt(msg) => {
824+
assert!(msg.contains("multi-statement execution"));
825+
}
826+
other => panic!("unexpected error type: {other:?}"),
827+
}
828+
829+
Ok(())
830+
}
831+
805832
#[test]
806833
fn test_bind_error_with_span() -> Result<(), DatabaseError> {
807834
let temp_dir = TempDir::new().expect("unable to create temporary working directory");

0 commit comments

Comments
 (0)