Execute a single (already-split) SQL statement.
(
&self,
identity: &AuthenticatedIdentity,
addr: &std::net::SocketAddr,
sql: &str,
)
| 51 | |
| 52 | /// Execute a single (already-split) SQL statement. |
| 53 | async fn execute_single_sql( |
| 54 | &self, |
| 55 | identity: &AuthenticatedIdentity, |
| 56 | addr: &std::net::SocketAddr, |
| 57 | sql: &str, |
| 58 | ) -> PgWireResult<Vec<Response>> { |
| 59 | use super::super::types::error_to_sqlstate; |
| 60 | |
| 61 | let sql_trimmed = sql.trim(); |
| 62 | let upper = sql_trimmed.to_uppercase(); |
| 63 | |
| 64 | self.sessions.ensure_session(*addr); |
| 65 | |
| 66 | if sql_trimmed.is_empty() || sql_trimmed == ";" { |
| 67 | return Ok(vec![Response::EmptyQuery]); |
| 68 | } |
| 69 | |
| 70 | // ── Transaction commands ────────────────────────────────────── |
| 71 | |
| 72 | if upper == "BEGIN" || upper == "BEGIN TRANSACTION" || upper == "START TRANSACTION" { |
| 73 | return self.handle_begin(addr); |
| 74 | } |
| 75 | |
| 76 | if upper == "COMMIT" || upper == "END" || upper == "END TRANSACTION" { |
| 77 | return self.handle_commit(identity, addr).await; |
| 78 | } |
| 79 | |
| 80 | if upper == "ROLLBACK" || upper == "ABORT" { |
| 81 | return self.handle_rollback(identity, addr); |
| 82 | } |
| 83 | |
| 84 | if let Some(result) = self.try_handle_deferred_offset(identity, addr, sql_trimmed, &upper) { |
| 85 | return result; |
| 86 | } |
| 87 | |
| 88 | // ── Wire-streaming COPY shapes for backup/restore ───────────── |
| 89 | if let Some(intent) = crate::control::backup::detect(sql_trimmed) { |
| 90 | return self |
| 91 | .intent_to_response(identity, *addr, intent) |
| 92 | .await |
| 93 | .map(|r| vec![r]); |
| 94 | } |
| 95 | |
| 96 | if upper.starts_with("SAVEPOINT ") { |
| 97 | return self.handle_savepoint(addr, sql_trimmed); |
| 98 | } |
| 99 | |
| 100 | if upper.starts_with("RELEASE SAVEPOINT ") || upper.starts_with("RELEASE ") { |
| 101 | return self.handle_release_savepoint(addr, sql_trimmed); |
| 102 | } |
| 103 | |
| 104 | if upper.starts_with("ROLLBACK TO ") { |
| 105 | return self.handle_rollback_to_savepoint(addr, sql_trimmed); |
| 106 | } |
| 107 | |
| 108 | // ── Cursor commands ─────────────────────────────────────────── |
| 109 | |
| 110 | if upper.starts_with("DECLARE ") && upper.contains(" CURSOR ") { |
no test coverage detected