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

Method execute_dml

src/query/executor.rs:1523–1676  ·  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

1521 }
1522
1523 async fn execute_dml<T>(
1524 framed: &mut Framed<T, crate::protocol::PostgresCodec>,
1525 db: &Arc<DbHandler>,
1526 session: &Arc<SessionState>,
1527 query: &str,
1528 query_router: Option<&Arc<QueryRouter>>,
1529 ) -> Result<(), PgSqliteError>
1530 where
1531 T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send,
1532 {
1533 // SQLAlchemy manages transactions explicitly - don't start implicit transactions
1534 // This was interfering with SQLAlchemy's unit-of-work dirty detection
1535
1536 debug!("execute_dml called with query: {}", query);
1537
1538 // Check for RETURNING clause
1539 if ReturningTranslator::has_returning_clause(query) {
1540 debug!("Query has RETURNING clause, using execute_dml_with_returning: {}", query);
1541 return Self::execute_dml_with_returning(framed, db, session, query, query_router).await;
1542 } else {
1543 debug!("Query does NOT have RETURNING clause: {}", query);
1544 }
1545
1546 // Validate numeric constraints for INSERT/UPDATE before execution
1547 use crate::query::{QueryTypeDetector, QueryType};
1548 use crate::validator::NumericValidator;
1549
1550 // Validate before executing - do all database work before any await
1551 let validation_error = match QueryTypeDetector::detect_query_type(query) {
1552 QueryType::Insert => {
1553 if let Some(table_name) = extract_table_name_from_insert(query) {
1554 // Validate numeric constraints using session connection
1555 match db.with_session_connection(&session.id, |conn| {
1556 match NumericValidator::validate_insert(conn, query, &table_name) {
1557 Ok(()) => Ok(()),
1558 Err(crate::error::PgError::NumericValueOutOfRange { .. }) => {
1559 Err(rusqlite::Error::SqliteFailure(
1560 rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_ERROR),
1561 Some("NUMERIC_VALUE_OUT_OF_RANGE".to_string())
1562 ))
1563 },
1564 Err(e) => Err(rusqlite::Error::SqliteFailure(
1565 rusqlite::ffi::Error::new(rusqlite::ffi::SQLITE_ERROR),
1566 Some(format!("Numeric validation failed: {e}"))
1567 ))
1568 }
1569 }).await {
1570 Ok(()) => None,
1571 Err(PgSqliteError::Sqlite(rusqlite::Error::SqliteFailure(_, Some(msg)))) if msg == "NUMERIC_VALUE_OUT_OF_RANGE" => {
1572 // Create a numeric value out of range error
1573 Some(PgSqliteError::Validation(crate::error::PgError::NumericValueOutOfRange {
1574 type_name: "numeric".to_string(),
1575 column_name: String::new(),
1576 value: String::new(),
1577 }))
1578 },
1579 Err(e) => Some(e),
1580 }

Callers

nothing calls this directly

Calls 8

ErrorResponseClass · 0.85
create_command_tagFunction · 0.85
to_error_responseMethod · 0.80
execute_queryMethod · 0.45

Tested by

no test coverage detected