GeezerVison is showing github.com — Use unnamed statement in pg when not persistent (#3863) · tensorzero/sqlx@d335f78
This repository was archived by the owner on Jun 12, 2026. It is now read-only.
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: sqlx-postgres/src/connection/executor.rs +11-6Lines changed: 11 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -25,9 +25,15 @@ async fn prepare( | 25 | 25 | sql: &str, | 26 | 26 | parameters: &[PgTypeInfo], | 27 | 27 | metadata: Option<Arc<PgStatementMetadata>>, | | 28 | + persistent: bool, | 28 | 29 | ) -> Result<(StatementId, Arc<PgStatementMetadata>), Error> { | 29 | | - let id = conn.inner.next_statement_id; | 30 | | - conn.inner.next_statement_id = id.next(); | | 30 | + let id = if persistent { | | 31 | + let id = conn.inner.next_statement_id; | | 32 | + conn.inner.next_statement_id = id.next(); | | 33 | + id | | 34 | + } else { | | 35 | + StatementId::UNNAMED | | 36 | + }; | 31 | 37 |
| 32 | 38 | // build a list of type OIDs to send to the database in the PARSE command | 33 | 39 | // we have not yet started the query sequence, so we are *safe* to cleanly make | @@ -163,8 +169,7 @@ impl PgConnection { | 163 | 169 | &mut self, | 164 | 170 | sql: &str, | 165 | 171 | parameters: &[PgTypeInfo], | 166 | | - // should we store the result of this prepare to the cache | 167 | | - store_to_cache: bool, | | 172 | + persistent: bool, | 168 | 173 | // optional metadata that was provided by the user, this means they are reusing | 169 | 174 | // a statement object | 170 | 175 | metadata: Option<Arc<PgStatementMetadata>>, | @@ -173,9 +178,9 @@ impl PgConnection { | 173 | 178 | return Ok((*statement).clone()); | 174 | 179 | } | 175 | 180 |
| 176 | | - let statement = prepare(self, sql, parameters, metadata).await?; | | 181 | + let statement = prepare(self, sql, parameters, metadata, persistent).await?; | 177 | 182 |
| 178 | | - if store_to_cache && self.inner.cache_statement.is_enabled() { | | 183 | + if persistent && self.inner.cache_statement.is_enabled() { | 179 | 184 | if let Some((id, _)) = self.inner.cache_statement.insert(sql, statement.clone()) { | 180 | 185 | self.inner.stream.write_msg(Close::Statement(id))?; | 181 | 186 | self.write_sync(); | |
Collapse file Copy file name to clipboardExpand all lines: sqlx-postgres/src/message/parse.rs +16Lines changed: 16 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -77,3 +77,19 @@ fn test_encode_parse() { | 77 | 77 |
| 78 | 78 | assert_eq!(buf, EXPECTED); | 79 | 79 | } | | 80 | + | | 81 | +#[test] | | 82 | +fn test_encode_parse_unnamed_statement() { | | 83 | + const EXPECTED: &[u8] = b"P\0\0\0\x15\0SELECT $1\0\0\x01\0\0\0\x19"; | | 84 | + | | 85 | + let mut buf = Vec::new(); | | 86 | + let m = Parse { | | 87 | + statement: StatementId::UNNAMED, | | 88 | + query: "SELECT $1", | | 89 | + param_types: &[Oid(25)], | | 90 | + }; | | 91 | + | | 92 | + m.encode_msg(&mut buf).unwrap(); | | 93 | + | | 94 | + assert_eq!(buf, EXPECTED); | | 95 | +} |
Collapse file Copy file name to clipboardExpand all lines: tests/postgres/postgres.rs +21Lines changed: 21 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -817,6 +817,27 @@ async fn it_closes_statement_from_cache_issue_470() -> anyhow::Result<()> { | 817 | 817 | Ok(()) | 818 | 818 | } | 819 | 819 |
| | 820 | +#[sqlx_macros::test] | | 821 | +async fn it_closes_statements_when_not_persistent_issue_3850() -> anyhow::Result<()> { | | 822 | + let mut conn = new::<Postgres>().await?; | | 823 | + | | 824 | + let _row = sqlx::query("SELECT $1 AS val") | | 825 | + .bind(Oid(1)) | | 826 | + .persistent(false) | | 827 | + .fetch_one(&mut conn) | | 828 | + .await?; | | 829 | + | | 830 | + let row = sqlx::query("SELECT count(*) AS num_prepared_statements FROM pg_prepared_statements") | | 831 | + .persistent(false) | | 832 | + .fetch_one(&mut conn) | | 833 | + .await?; | | 834 | + | | 835 | + let n: i64 = row.get("num_prepared_statements"); | | 836 | + assert_eq!(0, n, "no prepared statements should be open"); | | 837 | + | | 838 | + Ok(()) | | 839 | +} | | 840 | + | 820 | 841 | #[sqlx_macros::test] | 821 | 842 | async fn it_sets_application_name() -> anyhow::Result<()> { | 822 | 843 | sqlx_test::setup_if_needed(); | |
|