Skip to content

Commit b7277b0

Browse files
committed
fix(odbc): reuse prepared statements across queries
1 parent 0e78092 commit b7277b0

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

sqlx-core/src/odbc/connection/mod.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ use crate::odbc::{OdbcStatement, OdbcStatementMetadata};
1616
use odbc_api::{handles::StatementConnection, Prepared, ResultSetMetadata, SharedConnection};
1717
use std::borrow::Cow;
1818
use std::collections::HashMap;
19-
use std::sync::Arc;
19+
use std::sync::{Arc, Mutex};
2020

2121
mod executor;
2222

2323
type PreparedStatement = Prepared<StatementConnection<SharedConnection<'static>>>;
24+
type SharedPreparedStatement = Arc<Mutex<PreparedStatement>>;
2425

2526
fn collect_columns(prepared: &mut PreparedStatement) -> Vec<OdbcColumn> {
2627
let count = prepared.num_result_cols().unwrap_or(0);
@@ -50,7 +51,7 @@ fn decode_column_name(name_bytes: Vec<u8>, index: u16) -> String {
5051
/// thread-pool via `spawn_blocking` and synchronize access with a mutex.
5152
pub struct OdbcConnection {
5253
pub(crate) conn: SharedConnection<'static>,
53-
pub(crate) stmt_cache: HashMap<Arc<str>, PreparedStatement>,
54+
pub(crate) stmt_cache: HashMap<Arc<str>, SharedPreparedStatement>,
5455
}
5556

5657
impl std::fmt::Debug for OdbcConnection {
@@ -146,8 +147,8 @@ impl OdbcConnection {
146147
let (tx, rx) = flume::bounded(64);
147148

148149
// !!TODO!!!: Put back the prepared statement after usage
149-
let maybe_prepared = if let Some(prepared) = self.stmt_cache.remove(sql) {
150-
MaybePrepared::Prepared(prepared)
150+
let maybe_prepared = if let Some(prepared) = self.stmt_cache.get(sql) {
151+
MaybePrepared::Prepared(Arc::clone(prepared))
151152
} else {
152153
MaybePrepared::NotPrepared(sql.to_string())
153154
};
@@ -182,7 +183,8 @@ impl OdbcConnection {
182183
Ok((prepared, metadata))
183184
})
184185
.await?;
185-
self.stmt_cache.insert(Arc::clone(&sql_arc), prepared);
186+
self.stmt_cache
187+
.insert(Arc::clone(&sql_arc), Arc::new(Mutex::new(prepared)));
186188
Ok(OdbcStatement {
187189
sql: Cow::Borrowed(sql),
188190
metadata,
@@ -191,7 +193,7 @@ impl OdbcConnection {
191193
}
192194

193195
pub(crate) enum MaybePrepared {
194-
Prepared(PreparedStatement),
196+
Prepared(SharedPreparedStatement),
195197
NotPrepared(String),
196198
}
197199

sqlx-core/src/odbc/connection/odbc_bridge.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@ pub fn execute_sql(
3030
let params = prepare_parameters(args);
3131

3232
let affected = match maybe_prepared {
33-
MaybePrepared::Prepared(mut prepared) => {
33+
MaybePrepared::Prepared(prepared) => {
34+
let mut prepared = prepared.lock().expect("prepared statement lock");
3435
if let Some(mut cursor) = prepared.execute(&params[..])? {
3536
handle_cursor(&mut cursor, tx);
3637
}
37-
extract_rows_affected(&mut prepared)
38+
extract_rows_affected(&mut *prepared)
3839
}
3940
MaybePrepared::NotPrepared(sql) => {
4041
let mut preallocated = conn.preallocate().map_err(Error::from)?;

0 commit comments

Comments
 (0)