Skip to content

Commit 326ae3c

Browse files
committed
feat: add ability to set or unset the CLIENT_FOUND_ROWS flag
1 parent 1d674f5 commit 326ae3c

3 files changed

Lines changed: 67 additions & 1 deletion

File tree

sqlx-mysql/src/connection/stream.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ impl<S: Socket> MySqlStream<S> {
3535
let mut capabilities = Capabilities::PROTOCOL_41
3636
| Capabilities::IGNORE_SPACE
3737
| Capabilities::DEPRECATE_EOF
38-
| Capabilities::FOUND_ROWS
3938
| Capabilities::TRANSACTIONS
4039
| Capabilities::SECURE_CONNECTION
4140
| Capabilities::PLUGIN_AUTH_LENENC_DATA
@@ -49,6 +48,10 @@ impl<S: Socket> MySqlStream<S> {
4948
capabilities |= Capabilities::CONNECT_WITH_DB;
5049
}
5150

51+
if options.found_rows {
52+
capabilities |= Capabilities::FOUND_ROWS;
53+
}
54+
5255
Self {
5356
waiting: VecDeque::new(),
5457
capabilities,

sqlx-mysql/src/options/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub struct MySqlConnectOptions {
8080
pub(crate) no_engine_substitution: bool,
8181
pub(crate) timezone: Option<String>,
8282
pub(crate) set_names: bool,
83+
pub(crate) found_rows: bool,
8384
}
8485

8586
impl Default for MySqlConnectOptions {
@@ -111,6 +112,7 @@ impl MySqlConnectOptions {
111112
no_engine_substitution: true,
112113
timezone: Some(String::from("+00:00")),
113114
set_names: true,
115+
found_rows: true,
114116
}
115117
}
116118

@@ -414,6 +416,15 @@ impl MySqlConnectOptions {
414416
self.set_names = flag_val;
415417
self
416418
}
419+
420+
/// Sets the flag that enables or disables CLIENT_FOUND_ROWS,
421+
/// to return the number of found (matched) rows, and not the number of changed rows.
422+
///
423+
/// The default value is set to true.
424+
pub fn found_rows(mut self, flag_val: bool) -> Self {
425+
self.found_rows = flag_val;
426+
self
427+
}
417428
}
418429

419430
impl MySqlConnectOptions {

tests/mysql/mysql.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,3 +727,55 @@ async fn any_blob_conversions() -> anyhow::Result<()> {
727727

728728
Ok(())
729729
}
730+
731+
#[sqlx_macros::test]
732+
async fn test_client_found_rows() -> anyhow::Result<()> {
733+
setup_if_needed();
734+
735+
let url = url::Url::parse(&env::var("DATABASE_URL")?)?;
736+
737+
// CLIENT_AFFECTED_ROWS unspecified = true by default.
738+
let mut conn = MySqlConnectOptions::from_url(&url)?.connect().await?;
739+
let mut tx = conn.begin().await?;
740+
741+
tx.execute(sqlx::query(
742+
"CREATE TEMPORARY TABLE found_rows_testing (id INT PRIMARY KEY, field INT NOT NULL)",
743+
))
744+
.await?;
745+
746+
let result = tx.execute(sqlx::query("INSERT INTO found_rows_testing VALUES (0, 10) AS new ON DUPLICATE KEY UPDATE field = new.field")).await?;
747+
assert_eq!(result.rows_affected(), 1);
748+
749+
let result = tx.execute(sqlx::query("INSERT INTO found_rows_testing VALUES (0, 10) AS new ON DUPLICATE KEY UPDATE field = new.field")).await?;
750+
assert_eq!(result.rows_affected(), 1);
751+
752+
let result = tx.execute(sqlx::query("INSERT INTO found_rows_testing VALUES (0, 20) AS new ON DUPLICATE KEY UPDATE field = new.field")).await?;
753+
assert_eq!(result.rows_affected(), 2);
754+
755+
tx.rollback().await?;
756+
757+
// Explicitly unset CLIENT_AFFECTED_ROWS.
758+
let mut conn = MySqlConnectOptions::from_url(&url)?
759+
.found_rows(false)
760+
.connect()
761+
.await?;
762+
let mut tx = conn.begin().await?;
763+
764+
tx.execute(sqlx::query(
765+
"CREATE TEMPORARY TABLE found_rows_testing (id INT PRIMARY KEY, field INT NOT NULL)",
766+
))
767+
.await?;
768+
769+
let result = tx.execute(sqlx::query("INSERT INTO found_rows_testing VALUES (0, 10) AS new ON DUPLICATE KEY UPDATE field = new.field")).await?;
770+
assert_eq!(result.rows_affected(), 1);
771+
772+
let result = tx.execute(sqlx::query("INSERT INTO found_rows_testing VALUES (0, 10) AS new ON DUPLICATE KEY UPDATE field = new.field")).await?;
773+
assert_eq!(result.rows_affected(), 0);
774+
775+
let result = tx.execute(sqlx::query("INSERT INTO found_rows_testing VALUES (0, 20) AS new ON DUPLICATE KEY UPDATE field = new.field")).await?;
776+
assert_eq!(result.rows_affected(), 2);
777+
778+
tx.rollback().await?;
779+
780+
Ok(())
781+
}

0 commit comments

Comments
 (0)