diff --git a/src/raw_statement.rs b/src/raw_statement.rs index 58e9d0d..9e1d74e 100644 --- a/src/raw_statement.rs +++ b/src/raw_statement.rs @@ -114,15 +114,14 @@ impl RawStatement { unsafe { ffi::sqlite3_stmt_readonly(self.0) != 0 } } + /// `CStr` must be freed #[cfg(feature = "bundled")] - pub fn expanded_sql(&self) -> Option<&CStr> { - unsafe { - let ptr = ffi::sqlite3_expanded_sql(self.0); - if ptr.is_null() { - None - } else { - Some(CStr::from_ptr(ptr)) - } + pub unsafe fn expanded_sql(&self) -> Option<&CStr> { + let ptr = ffi::sqlite3_expanded_sql(self.0); + if ptr.is_null() { + None + } else { + Some(CStr::from_ptr(ptr)) } } diff --git a/src/statement.rs b/src/statement.rs index 1000dc0..e8d3fb4 100644 --- a/src/statement.rs +++ b/src/statement.rs @@ -550,11 +550,16 @@ impl Statement<'_> { /// Returns a string containing the SQL text of prepared statement with /// bound parameters expanded. #[cfg(feature = "bundled")] - pub fn expanded_sql(&self) -> Option<&str> { + pub fn expanded_sql(&self) -> Option { unsafe { - self.stmt - .expanded_sql() - .map(|s| str::from_utf8_unchecked(s.to_bytes())) + match self.stmt.expanded_sql() { + Some(s) => { + let sql = str::from_utf8_unchecked(s.to_bytes()).to_owned(); + ffi::sqlite3_free(s.as_ptr() as *mut _); + Some(sql) + } + _ => None, + } } } @@ -975,7 +980,7 @@ mod test { let db = Connection::open_in_memory().unwrap(); let stmt = db.prepare("SELECT ?").unwrap(); stmt.bind_parameter(&1, 1).unwrap(); - assert_eq!(Some("SELECT 1"), stmt.expanded_sql()); + assert_eq!(Some("SELECT 1".to_owned()), stmt.expanded_sql()); } #[test]