Returns Ok(Err) if any statement error'd during execution.
(
client: &mut SessionClient,
sender: &mut S,
stmt_group: Vec<(Statement<Raw>, String, Vec<Option<String>>)>,
)
| 1171 | |
| 1172 | /// Returns Ok(Err) if any statement error'd during execution. |
| 1173 | async fn execute_stmt_group<S: ResultSender>( |
| 1174 | client: &mut SessionClient, |
| 1175 | sender: &mut S, |
| 1176 | stmt_group: Vec<(Statement<Raw>, String, Vec<Option<String>>)>, |
| 1177 | ) -> Result<Result<(), ()>, Error> { |
| 1178 | let num_stmts = stmt_group.len(); |
| 1179 | for (stmt, sql, params) in stmt_group { |
| 1180 | assert!( |
| 1181 | num_stmts <= 1 || params.is_empty(), |
| 1182 | "statement groups contain more than 1 statement iff Simple request, which does not support parameters" |
| 1183 | ); |
| 1184 | |
| 1185 | let is_aborted_txn = matches!(client.session().transaction(), TransactionStatus::Failed(_)); |
| 1186 | if is_aborted_txn && !is_txn_exit_stmt(&stmt) { |
| 1187 | let err = SqlResult::err(client, Error::AbortedTransaction); |
| 1188 | let _ = send_and_retire(err.into(), client, sender).await?; |
| 1189 | return Ok(Err(())); |
| 1190 | } |
| 1191 | |
| 1192 | // Mirror the behavior of the PostgreSQL simple query protocol. |
| 1193 | // See the pgwire::protocol::StateMachine::query method for details. |
| 1194 | if let Err(e) = client.start_transaction(Some(num_stmts)) { |
| 1195 | let err = SqlResult::err(client, e); |
| 1196 | let _ = send_and_retire(err.into(), client, sender).await?; |
| 1197 | return Ok(Err(())); |
| 1198 | } |
| 1199 | let res = execute_stmt(client, sender, stmt, sql, params).await?; |
| 1200 | let is_err = send_and_retire(res, client, sender).await?; |
| 1201 | |
| 1202 | if is_err.is_err() { |
| 1203 | // Mirror StateMachine::error, which sometimes will clean up the |
| 1204 | // transaction state instead of always leaving it in Failed. |
| 1205 | let txn = client.session().transaction(); |
| 1206 | match txn { |
| 1207 | // Error can be called from describe and parse and so might not be in an active |
| 1208 | // transaction. |
| 1209 | TransactionStatus::Default | TransactionStatus::Failed(_) => {} |
| 1210 | // In Started (i.e., a single statement) and implicit transactions cleanup themselves. |
| 1211 | TransactionStatus::Started(_) | TransactionStatus::InTransactionImplicit(_) => { |
| 1212 | if let Err(err) = client.end_transaction(EndTransactionAction::Rollback).await { |
| 1213 | let err = SqlResult::err(client, err); |
| 1214 | let _ = send_and_retire(err.into(), client, sender).await?; |
| 1215 | } |
| 1216 | } |
| 1217 | // Explicit transactions move to failed. |
| 1218 | TransactionStatus::InTransaction(_) => { |
| 1219 | client.fail_transaction(); |
| 1220 | } |
| 1221 | } |
| 1222 | return Ok(Err(())); |
| 1223 | } |
| 1224 | } |
| 1225 | Ok(Ok(())) |
| 1226 | } |
| 1227 | |
| 1228 | /// Executes an entire [`SqlRequest`]. |
| 1229 | /// |
no test coverage detected