Issue using f32/f64 parameters in db.execute() inserts (Rust + PostgreSQL)

Hi everyone,

I’m running into a strange issue when trying to insert floating-point parameters f32 f64 using db.execute() in Rust (with the postgres crate).

Here’s a simplified example for testing

fn doIncluirTeste(db: &mut Client) {
/*
select * from teste2
delete from teste2

create table teste2
  (codigo int,
   cst varchar(20),
   RedutorIBS numeric(18,2))
*/

let codigo: i32 = 15;
let cst: &str = "000";
let valor: f32 = 0.34;

// This works:
// db.execute("Insert Into teste2 (Codigo, CST) VALUES ($1, $2)", &[&codigo, &cst])

// This also works:
// db.execute("Insert Into teste2 (Codigo, CST, RedutorIBS) VALUES ($1, $2, 0.43)", &[&codigo, &cst])

// But this does NOT work:
match db.execute(
    "Insert Into teste2 (Codigo, CST, RedutorIBS) VALUES ($1, $2, $3)",
    &[&codigo, &cst, &valor],
) {
    Ok(res) => println!("{}", res),
    Err(err) => println!("{}", err),
}

}

I'm receiving 'error serializing parameter 2

Just a guess, but maybe there is a type mismatch that the postgres crate can't handle? Have you tried using real or double precision for the ReditorIBS column instead of numeric?

2 Likes

Please use markdown syntax to make the code you post readable. This is done using three back ticks before and after the code:

```
code here
```

By default on this forum it will even get rust syntax highlighting (though this can be adjusted).

2 Likes

I tried with double precision and it works, but some rework on existing databases will be needed

let codigo : i32 = 15;
let cst :&str  = "000";
let valor : f64 = 0.31;
let valorlive : String = format!("{:.2}", valor);
let valorstr : &str = &valorlive;

//match db.execute( "Insert Into teste2 (Codigo, CST) VALUES ($1, $2, 0.43)", &[&codigo,&cst]                                         //works
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorIBS) VALUES ($1, $2, $3::numeric)", &[&codigo,&cst,&valor]               //fail

//works
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorStr) VALUES ($1, $2, $3)", &[&codigo, &cst, &valorlive]                
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorStr) VALUES ($1, $2, $3)", &[&codigo, &cst, &valorstr]                   
match db.execute( "Insert Into teste2 (Codigo, CST, RedutorDP) VALUES ($1, $2, $3)", &[&codigo, &cst, &valor]                      

//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorDP) VALUES ($1, $2, $3::numeric)", &[&codigo, &cst, &valorlive]          //fail -> error serializing parameter 2    
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorDP) VALUES ($1, $2, $3::numeric(18,2))", &[&codigo, &cst, &valorlive]    //fail -> error serializing parameter 2    
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorDP) VALUES ($1, $2, $3::numeric)", &[&codigo, &cst, &valorstr]           //fail -> error serializing parameter 2
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorDP) VALUES ($1, $2, $3::numeric(18,2))", &[&codigo, &cst, &valorstr]     //fail -> error serializing parameter 2

//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorR) VALUES ($1, $2, $3)", &[&codigo, &cst, &valor]                       //fail -> db error
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorR) VALUES ($1, $2, $3)", &[&codigo, &cst, &valorlive]                   //fail -> db error
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorR) VALUES ($1, $2, $3)", &[&codigo, &cst, &valorstr]                    //fail -> db error
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorR) VALUES ($1, $2, $3::real)", &[&codigo, &cst, &valor]                 //fail -> db error
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorR) VALUES ($1, $2, $3::real)", &[&codigo, &cst, &valorlive]             //fail -> db error
//match db.execute( "Insert Into teste2 (Codigo, CST, RedutorR) VALUES ($1, $2, $3::real)", &[&codigo, &cst, &valorstr]              //fail -> db error
){
    Ok(res) => println!("{}", res),
    Err(err) => println!("{}", err),

}   

}

//create table teste2
// (codigo int,
// cst varchar(20),
// RedutorStr varchar(20),
// RedutorIBS numeric(18,2),
// RedutorDP double precision,
// RetudorR real)

Despite some assumptions, I think it should work with other types as well... :sweat_smile:

Thank you for the previous tips