Skip to content

Commit b97e1c0

Browse files
authored
Merge pull request #123 from blackbeam/skipped-empty-result-set
Do not skip empty result sets (fix #121)
2 parents 4602469 + 7bd4616 commit b97e1c0

File tree

4 files changed

+46
-9
lines changed

4 files changed

+46
-9
lines changed

src/conn/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,6 +1529,30 @@ mod test {
15291529
Ok(())
15301530
}
15311531

1532+
#[tokio::test]
1533+
async fn should_provide_multiresult_set_metadata() -> super::Result<()> {
1534+
let mut c = Conn::new(get_opts()).await?;
1535+
c.query_drop("CREATE TEMPORARY TABLE tmp (id INT, foo TEXT)")
1536+
.await?;
1537+
1538+
let mut result = c
1539+
.query_iter("SELECT 1; SELECT id, foo FROM tmp WHERE 1 = 2; DO 42; SELECT 2;")
1540+
.await?;
1541+
assert_eq!(result.columns().map(|x| x.len()).unwrap_or_default(), 1);
1542+
1543+
result.for_each(drop).await?;
1544+
assert_eq!(result.columns().map(|x| x.len()).unwrap_or_default(), 2);
1545+
1546+
result.for_each(drop).await?;
1547+
assert_eq!(result.columns().map(|x| x.len()).unwrap_or_default(), 0);
1548+
1549+
result.for_each(drop).await?;
1550+
assert_eq!(result.columns().map(|x| x.len()).unwrap_or_default(), 1);
1551+
1552+
c.disconnect().await?;
1553+
Ok(())
1554+
}
1555+
15321556
#[tokio::test]
15331557
async fn should_handle_local_infile() -> super::Result<()> {
15341558
use std::fs::write;

src/queryable/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl Conn {
9696
{
9797
self.write_command_data(Command::COM_QUERY, query.as_ref().as_bytes())
9898
.await?;
99-
self.read_result_set::<TextProtocol>().await?;
99+
self.read_result_set::<TextProtocol>(true).await?;
100100
Ok(())
101101
}
102102
}

src/queryable/query_result.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ where
9191
if columns.is_empty() {
9292
// Empty, but not yet consumed result set.
9393
self.conn.set_pending_result(None);
94-
return Ok(None);
9594
} else {
9695
// Not yet consumed non-empty result set.
9796
let packet = match self.conn.read_packet().await {
@@ -106,7 +105,6 @@ where
106105
if P::is_last_result_set_packet(self.conn.capabilities(), &packet) {
107106
// `packet` is a result set terminator.
108107
self.conn.set_pending_result(None);
109-
return Ok(None);
110108
} else {
111109
// `packet` is a result set row.
112110
return Ok(Some(P::read_result_set_row(&packet, columns)?));
@@ -118,8 +116,8 @@ where
118116
if self.conn.more_results_exists() {
119117
// More data will follow.
120118
self.conn.sync_seq_id();
121-
self.conn.read_result_set::<P>().await?;
122-
continue;
119+
self.conn.read_result_set::<P>(false).await?;
120+
return Ok(None);
123121
} else {
124122
// The end of a query result.
125123
return Ok(None);
@@ -329,11 +327,26 @@ where
329327

330328
impl crate::Conn {
331329
/// Will read result set and write pending result into `self` (if any).
332-
pub(crate) async fn read_result_set<P>(&mut self) -> Result<()>
330+
pub(crate) async fn read_result_set<P>(&mut self, is_first_result_set: bool) -> Result<()>
333331
where
334332
P: Protocol,
335333
{
336-
let packet = self.read_packet().await?;
334+
let packet = match self.read_packet().await {
335+
Ok(packet) => packet,
336+
Err(err @ Error::Server(_)) if is_first_result_set => {
337+
// shortcut to emit an error right to the caller of a query/execute
338+
return Err(err);
339+
}
340+
Err(Error::Server(error)) => {
341+
// error will be consumed as a part of a multi-result set
342+
self.set_pending_result(Some(ResultSetMeta::Error(error)));
343+
return Ok(());
344+
}
345+
Err(err) => {
346+
// non-server errors are fatal
347+
return Err(err);
348+
}
349+
};
337350

338351
match packet.get(0) {
339352
Some(0x00) => self.set_pending_result(Some(P::result_set_meta(Arc::from(

src/queryable/stmt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl crate::Conn {
274274
}
275275

276276
self.write_command_raw(body).await?;
277-
self.read_result_set::<BinaryProtocol>().await?;
277+
self.read_result_set::<BinaryProtocol>(true).await?;
278278
break;
279279
}
280280
Params::Named(_) => {
@@ -303,7 +303,7 @@ impl crate::Conn {
303303

304304
let (body, _) = ComStmtExecuteRequestBuilder::new(statement.id()).build(&[]);
305305
self.write_command_raw(body).await?;
306-
self.read_result_set::<BinaryProtocol>().await?;
306+
self.read_result_set::<BinaryProtocol>(true).await?;
307307
break;
308308
}
309309
}

0 commit comments

Comments
 (0)