Skip to content

Commit f6ec31d

Browse files
committed
Allow passing null params in query_raw_txt()
Previous coding only allowed passing vector of text values as params, but that does not allow to distinguish between nulls and 4-byte strings with "null" written in them. Change query_raw_txt params argument to accept Vec<Option<String>> instead.
1 parent 2e9b5f1 commit f6ec31d

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

tokio-postgres/src/client.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ impl Client {
381381
pub async fn query_raw_txt<'a, S, I>(&self, query: S, params: I) -> Result<RowStream, Error>
382382
where
383383
S: AsRef<str>,
384-
I: IntoIterator<Item = S>,
384+
I: IntoIterator<Item = Option<S>>,
385385
I::IntoIter: ExactSizeIterator,
386386
{
387387
let params = params.into_iter();
@@ -396,9 +396,12 @@ impl Client {
396396
"", // empty string selects the unnamed prepared statement
397397
std::iter::empty(), // all parameters use the default format (text)
398398
params,
399-
|param, buf| {
400-
buf.put_slice(param.as_ref().as_bytes());
401-
Ok(postgres_protocol::IsNull::No)
399+
|param, buf| match param {
400+
Some(param) => {
401+
buf.put_slice(param.as_ref().as_bytes());
402+
Ok(postgres_protocol::IsNull::No)
403+
}
404+
None => Ok(postgres_protocol::IsNull::Yes),
402405
},
403406
Some(0), // all text
404407
buf,

tokio-postgres/tests/test/main.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ async fn query_raw_txt() {
256256
let client = connect("user=postgres").await;
257257

258258
let rows: Vec<tokio_postgres::Row> = client
259-
.query_raw_txt("SELECT 55 * $1", ["42"])
259+
.query_raw_txt("SELECT 55 * $1", [Some("42")])
260260
.await
261261
.unwrap()
262262
.try_collect()
@@ -268,7 +268,7 @@ async fn query_raw_txt() {
268268
assert_eq!(res, 55 * 42);
269269

270270
let rows: Vec<tokio_postgres::Row> = client
271-
.query_raw_txt("SELECT $1", ["42"])
271+
.query_raw_txt("SELECT $1", [Some("42")])
272272
.await
273273
.unwrap()
274274
.try_collect()
@@ -280,6 +280,36 @@ async fn query_raw_txt() {
280280
assert!(rows[0].body_len() > 0);
281281
}
282282

283+
#[tokio::test]
284+
async fn query_raw_txt_nulls() {
285+
let client = connect("user=postgres").await;
286+
287+
let rows: Vec<tokio_postgres::Row> = client
288+
.query_raw_txt(
289+
"SELECT $1 as str, $2 as n, 'null' as str2, null as n2",
290+
[Some("null"), None],
291+
)
292+
.await
293+
.unwrap()
294+
.try_collect()
295+
.await
296+
.unwrap();
297+
298+
assert_eq!(rows.len(), 1);
299+
300+
let res = rows[0].as_text(0).unwrap();
301+
assert_eq!(res, Some("null"));
302+
303+
let res = rows[0].as_text(1).unwrap();
304+
assert_eq!(res, None);
305+
306+
let res = rows[0].as_text(2).unwrap();
307+
assert_eq!(res, Some("null"));
308+
309+
let res = rows[0].as_text(3).unwrap();
310+
assert_eq!(res, None);
311+
}
312+
283313
#[tokio::test]
284314
async fn limit_max_backend_message_size() {
285315
let client = connect("user=postgres max_backend_message_size=10000").await;

0 commit comments

Comments
 (0)