(
framed: &mut Framed<T, crate::protocol::PostgresCodec>,
db: &Arc<DbHandler>,
session: &Arc<SessionState>,
query: &str,
query_router: Option<&Arc<QueryRouter>>
| 256 | } |
| 257 | |
| 258 | async fn execute_single_statement<T>( |
| 259 | framed: &mut Framed<T, crate::protocol::PostgresCodec>, |
| 260 | db: &Arc<DbHandler>, |
| 261 | session: &Arc<SessionState>, |
| 262 | query: &str, |
| 263 | query_router: Option<&Arc<QueryRouter>>, |
| 264 | ) -> Result<(), PgSqliteError> |
| 265 | where |
| 266 | T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, |
| 267 | { |
| 268 | use crate::protocol::TransactionStatus; |
| 269 | |
| 270 | // Check if we're in a failed transaction |
| 271 | if session.get_transaction_status().await == TransactionStatus::InFailedTransaction { |
| 272 | // Only ROLLBACK is allowed in a failed transaction |
| 273 | use crate::query::{QueryTypeDetector, QueryType}; |
| 274 | if !matches!(QueryTypeDetector::detect_query_type(query), QueryType::Rollback) { |
| 275 | return Err(PgSqliteError::Protocol( |
| 276 | "current transaction is aborted, commands ignored until end of transaction block".to_string() |
| 277 | )); |
| 278 | } |
| 279 | } |
| 280 | // Preprocess query: rewrite pg_show_all_settings() → pg_settings |
| 281 | let query = preprocess_query(query); |
| 282 | let query: &str = query.as_str(); |
| 283 | |
| 284 | // Handle set_config() function calls |
| 285 | if let Some(caps) = SET_CONFIG_PATTERN.captures(query) { |
| 286 | let param_name = caps[1].to_string(); |
| 287 | let param_value = caps[2].to_string(); |
| 288 | // is_local (caps[3]) is ignored — pgsqlite doesn't support transaction-scoped settings |
| 289 | |
| 290 | debug!("Handling set_config('{}', '{}', ...)", param_name, param_value); |
| 291 | |
| 292 | // Set the parameter in the session |
| 293 | let mut params = session.parameters.write().await; |
| 294 | params.insert(param_name.to_uppercase(), param_value.clone()); |
| 295 | drop(params); |
| 296 | |
| 297 | // Send synthetic response: RowDescription + DataRow + CommandComplete |
| 298 | let field = FieldDescription { |
| 299 | name: "set_config".to_string(), |
| 300 | table_oid: 0, |
| 301 | column_id: 1, |
| 302 | type_oid: PgType::Text.to_oid(), |
| 303 | type_size: -1, |
| 304 | type_modifier: -1, |
| 305 | format: 0, |
| 306 | }; |
| 307 | framed.send(BackendMessage::RowDescription(vec![field])).await |
| 308 | .map_err(PgSqliteError::Io)?; |
| 309 | |
| 310 | let row = vec![Some(param_value.as_bytes().to_vec())]; |
| 311 | framed.send(BackendMessage::DataRow(row)).await |
| 312 | .map_err(PgSqliteError::Io)?; |
| 313 | |
| 314 | framed.send(BackendMessage::CommandComplete { |
| 315 | tag: "SELECT 1".to_string() |
nothing calls this directly
no test coverage detected