From ee17d7a4aff044d39dad3f6e6a931fe68ae6050f Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Fri, 24 Jul 2026 13:22:39 -0700 Subject: [PATCH 1/5] fix: dont reset/set parameters unnecessarily --- pgdog/src/backend/server.rs | 4 ++-- pgdog/src/net/parameter.rs | 28 ++++++++++++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/pgdog/src/backend/server.rs b/pgdog/src/backend/server.rs index 3bf9d603f..6df646c05 100644 --- a/pgdog/src/backend/server.rs +++ b/pgdog/src/backend/server.rs @@ -605,10 +605,10 @@ impl Server { // Compare client and server params. let mut executed = if !params.identical(&self.client_params) { // Construct client parameter SET queries. - let tracked = params.tracked(); + let tracked = params.tracked(&self.client_params); // Construct RESET queries to reset any current params // to their default values. - let mut queries = self.client_params.reset_queries(); + let mut queries = self.client_params.reset_queries(¶ms); // Combine both to create a new, fresh session state // on this connection. diff --git a/pgdog/src/net/parameter.rs b/pgdog/src/net/parameter.rs index 88bcc76af..9bf0aab3c 100644 --- a/pgdog/src/net/parameter.rs +++ b/pgdog/src/net/parameter.rs @@ -349,11 +349,22 @@ impl Parameters { if entries > 0 { hasher.finish() } else { 0 } } - pub fn tracked(&self) -> Parameters { + /// Calculate the parameters we need to update on the server, + /// excluding the parameters we do not track because they have no effect, e.g., "pgdog"."role", + /// or which cannot be changed, e.g., "user". + /// + /// # Arguments + /// + /// - `other`: Parameters stored on the server. + /// + pub(crate) fn tracked(&self, other: &Self) -> Parameters { let params = self .params .iter() + // Ignore untracked parameters. .filter(|(k, _)| !UNTRACKED_PARAMS.contains(k)) + // Ignore parameters that have identical values, they don't need to be updated. + .filter(|(k, v)| other.get(k).map(|other| other == *v).unwrap_or(true)) .map(|(k, v)| (k.clone(), v.clone())) .collect::>(); @@ -406,9 +417,18 @@ impl Parameters { } } - pub fn reset_queries(&self) -> Vec { + /// Create a list of `RESET` queries that will reset parameters + /// back to their default value. + /// + /// This will ignore all parameters that are about to be SET + /// by incoming parameters. It will only reset parameters + /// that are currently set on the server and which do not + /// have a value on the incoming client. + /// + pub(crate) fn reset_queries(&self, other: &Self) -> Vec { self.params .keys() + .filter(|name| !other.contains_key(*name)) .map(|name| Query::new(format!(r#"RESET "{}""#, name))) .collect() } @@ -819,7 +839,7 @@ mod test { assert_eq!(timeout.first().unwrap(), "5s"); // Get reset queries before resetting (reset_queries uses current params) - let reset_queries = params.reset_queries(); + let reset_queries = params.reset_queries(&Parameters::default()); assert_eq!(reset_queries.len(), 2); // Execute reset queries on server @@ -859,7 +879,7 @@ mod test { assert_eq!(timeout.first().unwrap(), "5s"); // Get reset queries and execute on server - let reset_queries = params.reset_queries(); + let reset_queries = params.reset_queries(&Parameters::default()); for query in reset_queries { server.execute(query).await.unwrap(); } From 49d7a12709cf5d18dfd61d9aa3dc91cc557e47c1 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Fri, 24 Jul 2026 14:15:14 -0700 Subject: [PATCH 2/5] woops --- pgdog/src/backend/server.rs | 4 ++-- pgdog/src/net/parameter.rs | 21 ++++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pgdog/src/backend/server.rs b/pgdog/src/backend/server.rs index 6df646c05..c453dc68f 100644 --- a/pgdog/src/backend/server.rs +++ b/pgdog/src/backend/server.rs @@ -605,7 +605,7 @@ impl Server { // Compare client and server params. let mut executed = if !params.identical(&self.client_params) { // Construct client parameter SET queries. - let tracked = params.tracked(&self.client_params); + let tracked = params.tracked_and_different(&self.client_params); // Construct RESET queries to reset any current params // to their default values. let mut queries = self.client_params.reset_queries(¶ms); @@ -624,7 +624,7 @@ impl Server { } // Update params on this connection. - self.client_params = tracked; + self.client_params = params.tracked(); queries.len() } else { diff --git a/pgdog/src/net/parameter.rs b/pgdog/src/net/parameter.rs index 9bf0aab3c..1ff29e994 100644 --- a/pgdog/src/net/parameter.rs +++ b/pgdog/src/net/parameter.rs @@ -349,6 +349,25 @@ impl Parameters { if entries > 0 { hasher.finish() } else { 0 } } + /// Filter our parameters that we would track with SET queries. + pub(crate) fn tracked(&self) -> Parameters { + let params = self + .params + .iter() + // Ignore untracked parameters. + .filter(|(k, _)| !UNTRACKED_PARAMS.contains(k)) + .map(|(k, v)| (k.clone(), v.clone())) + .collect::>(); + + let hash = Self::compute_hash(¶ms); + + Self { + params, + hash, + ..Default::default() + } + } + /// Calculate the parameters we need to update on the server, /// excluding the parameters we do not track because they have no effect, e.g., "pgdog"."role", /// or which cannot be changed, e.g., "user". @@ -357,7 +376,7 @@ impl Parameters { /// /// - `other`: Parameters stored on the server. /// - pub(crate) fn tracked(&self, other: &Self) -> Parameters { + pub(crate) fn tracked_and_different(&self, other: &Self) -> Parameters { let params = self .params .iter() From c522712b4164f0dc9ce3e93cb2dfb803d8e88156 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Fri, 24 Jul 2026 14:26:41 -0700 Subject: [PATCH 3/5] woops --- pgdog/src/net/parameter.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pgdog/src/net/parameter.rs b/pgdog/src/net/parameter.rs index 1ff29e994..76aa8b577 100644 --- a/pgdog/src/net/parameter.rs +++ b/pgdog/src/net/parameter.rs @@ -383,7 +383,7 @@ impl Parameters { // Ignore untracked parameters. .filter(|(k, _)| !UNTRACKED_PARAMS.contains(k)) // Ignore parameters that have identical values, they don't need to be updated. - .filter(|(k, v)| other.get(k).map(|other| other == *v).unwrap_or(true)) + .filter(|(k, v)| other.get(k).map(|other| other != *v).unwrap_or(true)) .map(|(k, v)| (k.clone(), v.clone())) .collect::>(); @@ -568,6 +568,30 @@ mod test { assert!(Parameters::default().identical(&Parameters::default())); } + #[test] + fn test_tracked_and_different() { + let mut client = Parameters::default(); + client.insert("application_name", "client"); + client.insert("statement_timeout", "1001ms"); + client.insert("search_path", "public"); + + let mut server = Parameters::default(); + server.insert("application_name", "server"); + server.insert("statement_timeout", "1001ms"); + + let different = client.tracked_and_different(&server); + + assert_eq!( + different.get("application_name"), + Some(&ParameterValue::String("client".into())) + ); + assert_eq!( + different.get("search_path"), + Some(&ParameterValue::String("public".into())) + ); + assert!(!different.contains_key("statement_timeout")); + } + #[test] fn test_insert_transaction_non_local() { let mut params = Parameters::default(); From 06403633ddbfce4b870addad47a5d25e4bca6166 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Fri, 24 Jul 2026 15:03:50 -0700 Subject: [PATCH 4/5] fmt --- pgdog/src/net/parameter.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pgdog/src/net/parameter.rs b/pgdog/src/net/parameter.rs index 76aa8b577..a105b181c 100644 --- a/pgdog/src/net/parameter.rs +++ b/pgdog/src/net/parameter.rs @@ -349,13 +349,17 @@ impl Parameters { if entries > 0 { hasher.finish() } else { 0 } } + /// Iterate over parameters that we track with SET queries. + pub(crate) fn tracked_iter(&self) -> impl Iterator { + self.params + .iter() + .filter(|(k, _)| !UNTRACKED_PARAMS.contains(k)) + } + /// Filter our parameters that we would track with SET queries. pub(crate) fn tracked(&self) -> Parameters { let params = self - .params - .iter() - // Ignore untracked parameters. - .filter(|(k, _)| !UNTRACKED_PARAMS.contains(k)) + .tracked_iter() .map(|(k, v)| (k.clone(), v.clone())) .collect::>(); @@ -378,10 +382,7 @@ impl Parameters { /// pub(crate) fn tracked_and_different(&self, other: &Self) -> Parameters { let params = self - .params - .iter() - // Ignore untracked parameters. - .filter(|(k, _)| !UNTRACKED_PARAMS.contains(k)) + .tracked_iter() // Ignore parameters that have identical values, they don't need to be updated. .filter(|(k, v)| other.get(k).map(|other| other != *v).unwrap_or(true)) .map(|(k, v)| (k.clone(), v.clone())) From 1a54de3b1702b0b53f189fe73855d6eda72030e8 Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Fri, 24 Jul 2026 15:21:20 -0700 Subject: [PATCH 5/5] fix test --- pgdog/src/backend/server.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pgdog/src/backend/server.rs b/pgdog/src/backend/server.rs index c453dc68f..4f44f998d 100644 --- a/pgdog/src/backend/server.rs +++ b/pgdog/src/backend/server.rs @@ -608,7 +608,7 @@ impl Server { let tracked = params.tracked_and_different(&self.client_params); // Construct RESET queries to reset any current params // to their default values. - let mut queries = self.client_params.reset_queries(¶ms); + let mut queries = self.client_params.reset_queries(params); // Combine both to create a new, fresh session state // on this connection. @@ -2313,7 +2313,7 @@ pub mod test { let changed = server .link_client(FrontendPid::new(), ¶ms, None) .await?; - assert_eq!(changed, 2); // RESET, SET. + assert_eq!(changed, 1); // SET only; the parameter already exists. let changed = server .link_client(FrontendPid::new(), ¶ms, None)