MCPcopy Create free account
hub / github.com/erans/pgsqlite / execute_transaction

Method execute_transaction

src/query/executor.rs:2219–2304  ·  view source on GitHub ↗
(
        framed: &mut Framed<T, crate::protocol::PostgresCodec>,
        db: &Arc<DbHandler>,
        session: &Arc<SessionState>,
        query: &str,
        _query_router: Option<&Arc<QueryRouter>

Source from the content-addressed store, hash-verified

2217 }
2218
2219 async fn execute_transaction<T>(
2220 framed: &mut Framed<T, crate::protocol::PostgresCodec>,
2221 db: &Arc<DbHandler>,
2222 session: &Arc<SessionState>,
2223 query: &str,
2224 _query_router: Option<&Arc<QueryRouter>>,
2225 ) -> Result<(), PgSqliteError>
2226 where
2227 T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send,
2228 {
2229 use crate::query::{QueryTypeDetector, QueryType};
2230 use crate::protocol::TransactionStatus;
2231
2232 // Check if we're in a failed transaction
2233 let current_status = session.get_transaction_status().await;
2234 if current_status == TransactionStatus::InFailedTransaction {
2235 // Only ROLLBACK is allowed in a failed transaction
2236 if !matches!(QueryTypeDetector::detect_query_type(query), QueryType::Rollback) {
2237 return Err(PgSqliteError::Protocol(
2238 "current transaction is aborted, commands ignored until end of transaction block".to_string()
2239 ));
2240 }
2241 }
2242
2243 match QueryTypeDetector::detect_query_type(query) {
2244 QueryType::Begin => {
2245 // Check if we're already in a transaction
2246 if current_status == TransactionStatus::InTransaction {
2247 // PostgreSQL behavior: warn but don't fail
2248 tracing::warn!("BEGIN command received while already in transaction");
2249 // Send a warning notice
2250 use crate::protocol::messages::NoticeResponse;
2251 framed.send(BackendMessage::NoticeResponse(NoticeResponse {
2252 severity: "WARNING".to_string(),
2253 code: "25001".to_string(), // active_sql_transaction
2254 message: "there is already a transaction in progress".to_string(),
2255 detail: None,
2256 hint: None,
2257 position: None,
2258 where_: None,
2259 })).await.map_err(PgSqliteError::Io)?;
2260 // Still send CommandComplete, but don't actually execute BEGIN
2261 framed.send(BackendMessage::CommandComplete { tag: "BEGIN".to_string() }).await
2262 .map_err(PgSqliteError::Io)?;
2263 } else {
2264 tracing::debug!("Executing BEGIN command");
2265 db.begin_with_session(&session.id).await?;
2266 tracing::debug!("BEGIN executed successfully");
2267 // Update transaction status to InTransaction
2268 *session.transaction_status.write().await = TransactionStatus::InTransaction;
2269 tracing::debug!("Transaction status updated to InTransaction");
2270 framed.send(BackendMessage::CommandComplete { tag: "BEGIN".to_string() }).await
2271 .map_err(PgSqliteError::Io)?;
2272 }
2273 }
2274 QueryType::Commit => {
2275 // Can't commit a failed transaction
2276 if current_status == TransactionStatus::InFailedTransaction {

Callers

nothing calls this directly

Calls 5

NoticeResponseClass · 0.85
begin_with_sessionMethod · 0.80
commit_with_sessionMethod · 0.80
rollback_with_sessionMethod · 0.80

Tested by

no test coverage detected