Update doesnt work with sqlx / postgres / varchar

Hello. Did anyone get this error before?

mismatched types
expected enum `std::option::Option<&[std::string::String]>`
   found enum `std::option::Option<std::string::String>`

I'm just trying to update varchar field which is nullable:

        sqlx::query!(
            r#"
            UPDATE users SET name = $1 WHERE id = $2
            "#,
            self.name, self.id
        )
        .execute(pool)
        .await?;

I am not even passing any string, just None value. To the nullable character varying field.

pub struct User {
    pub id: Option<i32>,
    pub name: Option<String>,
}

And I get this error.

If I do ARRAY[$1]::varchar[] as GPT suggests I got a funny string "{NULL}" inside the field instead of [null].

So sqlx cant convert text to varchat by itself?

It sounds like you need to convert self.name into an array (of length 1). You can do that with from_ref. To do that on a value in an Option, you can map it:

self.name.map(|name| array::from_ref(name))

Then I get

165 |             self.name.as_ref().map(|name| array::from_ref(name)),
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |             |
    |             expected `Option<&[String]>`, found `Option<&[String; 1]>`
    |             expected due to the type of this binding

It looks like the compiler wasn't able to automatically insert the conversion from array (&[String; 1]) to slice (&[String]), so you should do it manually:

self.name.map(|name| array::from_ref(name).as_slice())
1 Like

Ah I found the problem, type of the field was mistakenly character varying[] instead of character varying.

But it worked btw:

self.name.map(|name| array::from_ref(name).as_slice())

Thank you @alice