Skip to content

Commit 1235ee7

Browse files
committed
make raw_txt not prepare statements
1 parent 7434d93 commit 1235ee7

File tree

5 files changed

+69
-22
lines changed

5 files changed

+69
-22
lines changed

tokio-postgres/src/client.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -376,18 +376,16 @@ impl Client {
376376

377377
/// Pass text directly to the Postgres backend to allow it to sort out typing itself and
378378
/// to save a roundtrip
379-
pub async fn query_raw_txt<'a, T, S, I>(
379+
pub async fn query_raw_txt<S, I>(
380380
&self,
381-
statement: &T,
381+
statement: &str,
382382
params: I,
383383
) -> Result<RowStream, Error>
384384
where
385-
T: ?Sized + ToStatement,
386385
S: AsRef<str>,
387386
I: IntoIterator<Item = Option<S>>,
388387
I::IntoIter: ExactSizeIterator,
389388
{
390-
let statement = statement.__convert().into_statement(self).await?;
391389
query::query_txt(&self.inner, statement, params).await
392390
}
393391

tokio-postgres/src/generic_client.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,8 @@ pub trait GenericClient: private::Sealed {
5757
I::IntoIter: ExactSizeIterator;
5858

5959
/// Like `Client::query_raw_txt`.
60-
async fn query_raw_txt<'a, T, S, I>(
61-
&self,
62-
statement: &T,
63-
params: I,
64-
) -> Result<RowStream, Error>
60+
async fn query_raw_txt<S, I>(&self, statement: &str, params: I) -> Result<RowStream, Error>
6561
where
66-
T: ?Sized + ToStatement + Sync + Send,
6762
S: AsRef<str> + Sync + Send,
6863
I: IntoIterator<Item = Option<S>> + Sync + Send,
6964
I::IntoIter: ExactSizeIterator + Sync + Send;
@@ -145,9 +140,8 @@ impl GenericClient for Client {
145140
self.query_raw(statement, params).await
146141
}
147142

148-
async fn query_raw_txt<'a, T, S, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
143+
async fn query_raw_txt<S, I>(&self, statement: &str, params: I) -> Result<RowStream, Error>
149144
where
150-
T: ?Sized + ToStatement + Sync + Send,
151145
S: AsRef<str> + Sync + Send,
152146
I: IntoIterator<Item = Option<S>> + Sync + Send,
153147
I::IntoIter: ExactSizeIterator + Sync + Send,
@@ -237,9 +231,8 @@ impl GenericClient for Transaction<'_> {
237231
self.query_raw(statement, params).await
238232
}
239233

240-
async fn query_raw_txt<'a, T, S, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
234+
async fn query_raw_txt<S, I>(&self, statement: &str, params: I) -> Result<RowStream, Error>
241235
where
242-
T: ?Sized + ToStatement + Sync + Send,
243236
S: AsRef<str> + Sync + Send,
244237
I: IntoIterator<Item = Option<S>> + Sync + Send,
245238
I::IntoIter: ExactSizeIterator + Sync + Send,

tokio-postgres/src/query.rs

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use crate::client::{InnerClient, Responses};
22
use crate::codec::FrontendMessage;
33
use crate::connection::RequestMessages;
44
use crate::types::{BorrowToSql, IsNull};
5-
use crate::{Error, Portal, ReadyForQueryStatus, Row, Statement};
5+
use crate::{Column, Error, Portal, ReadyForQueryStatus, Row, Statement};
66
use bytes::{BufMut, Bytes, BytesMut};
7+
use fallible_iterator::FallibleIterator;
78
use futures_util::{ready, Stream};
89
use log::{debug, log_enabled, Level};
910
use pin_project_lite::pin_project;
1011
use postgres_protocol::message::backend::Message;
1112
use postgres_protocol::message::frontend;
12-
use postgres_types::Format;
13+
use postgres_types::{Format, Type};
1314
use std::fmt;
1415
use std::marker::PhantomPinned;
1516
use std::pin::Pin;
@@ -63,7 +64,7 @@ where
6364

6465
pub async fn query_txt<S, I>(
6566
client: &Arc<InnerClient>,
66-
statement: Statement,
67+
query: &str,
6768
params: I,
6869
) -> Result<RowStream, Error>
6970
where
@@ -74,10 +75,18 @@ where
7475
let params = params.into_iter();
7576

7677
let buf = client.with_buf(|buf| {
78+
frontend::parse(
79+
"", // unnamed prepared statement
80+
query, // query to parse
81+
std::iter::empty(), // give no type info
82+
buf,
83+
)
84+
.map_err(Error::encode)?;
85+
frontend::describe(b'S', "", buf).map_err(Error::encode)?;
7786
// Bind, pass params as text, retrieve as binary
7887
match frontend::bind(
7988
"", // empty string selects the unnamed portal
80-
statement.name(), // named prepared statement
89+
"", // unnamed prepared statement
8190
std::iter::empty(), // all parameters use the default format (text)
8291
params,
8392
|param, buf| match param {
@@ -104,9 +113,48 @@ where
104113
})?;
105114

106115
// now read the responses
107-
let responses = start(client, buf).await?;
116+
let mut responses = client.send(RequestMessages::Single(FrontendMessage::Raw(buf)))?;
117+
118+
match responses.next().await? {
119+
Message::ParseComplete => {}
120+
_ => return Err(Error::unexpected_message()),
121+
}
122+
123+
let parameter_description = match responses.next().await? {
124+
Message::ParameterDescription(body) => body,
125+
_ => return Err(Error::unexpected_message()),
126+
};
127+
128+
let row_description = match responses.next().await? {
129+
Message::RowDescription(body) => Some(body),
130+
Message::NoData => None,
131+
_ => return Err(Error::unexpected_message()),
132+
};
133+
134+
match responses.next().await? {
135+
Message::BindComplete => {}
136+
_ => return Err(Error::unexpected_message()),
137+
}
138+
139+
let mut parameters = vec![];
140+
let mut it = parameter_description.parameters();
141+
while let Some(oid) = it.next().map_err(Error::parse)? {
142+
let type_ = Type::from_oid(oid).unwrap_or(Type::UNKNOWN);
143+
parameters.push(type_);
144+
}
145+
146+
let mut columns = vec![];
147+
if let Some(row_description) = row_description {
148+
let mut it = row_description.fields();
149+
while let Some(field) = it.next().map_err(Error::parse)? {
150+
let type_ = Type::from_oid(field.type_oid()).unwrap_or(Type::UNKNOWN);
151+
let column = Column::new(field.name().to_string(), type_, field);
152+
columns.push(column);
153+
}
154+
}
155+
108156
Ok(RowStream {
109-
statement,
157+
statement: Statement::new_anonymous(parameters, columns),
110158
responses,
111159
command_tag: None,
112160
status: ReadyForQueryStatus::Unknown,

tokio-postgres/src/statement.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ impl Statement {
5252
}))
5353
}
5454

55+
pub(crate) fn new_anonymous(params: Vec<Type>, columns: Vec<Column>) -> Statement {
56+
Statement(Arc::new(StatementInner {
57+
client: Weak::new(),
58+
name: String::new(),
59+
params,
60+
columns,
61+
}))
62+
}
63+
5564
pub(crate) fn name(&self) -> &str {
5665
&self.0.name
5766
}

tokio-postgres/src/transaction.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,8 @@ impl<'a> Transaction<'a> {
150150
}
151151

152152
/// Like `Client::query_raw_txt`.
153-
pub async fn query_raw_txt<T, S, I>(&self, statement: &T, params: I) -> Result<RowStream, Error>
153+
pub async fn query_raw_txt<S, I>(&self, statement: &str, params: I) -> Result<RowStream, Error>
154154
where
155-
T: ?Sized + ToStatement,
156155
S: AsRef<str>,
157156
I: IntoIterator<Item = Option<S>>,
158157
I::IntoIter: ExactSizeIterator,

0 commit comments

Comments
 (0)