Brendonovich / prisma-client-rust

Type-safe database access for Rust
https://prisma.brendonovich.dev
Apache License 2.0
1.76k stars 104 forks source link

JsonNullableFilter type is wrong #297

Open mirror-kt opened 1 year ago

mirror-kt commented 1 year ago

I wrote a model using the Json? type in schema.prisma and did a cargo prisma generate.

The generated code looks like the following, which is a compile error because it cannot accept Option.

model some_model {
    id                     String               @id @unique @db.Uuid
    some_column            Json?
}
pub enum JsonNullableFilter {
    Equals(::prisma_client_rust::serde_json::Value),
    Path(Vec<String>),
    StringContains(String),
    StringStartsWith(String),
    StringEndsWith(String),
    ArrayContains(Option<::prisma_client_rust::serde_json::Value>),
    ArrayStartsWith(Option<::prisma_client_rust::serde_json::Value>),
    ArrayEndsWith(Option<::prisma_client_rust::serde_json::Value>),
    Lt(::prisma_client_rust::serde_json::Value),
    Lte(::prisma_client_rust::serde_json::Value),
    Gt(::prisma_client_rust::serde_json::Value),
    Gte(::prisma_client_rust::serde_json::Value),
    Not(::prisma_client_rust::serde_json::Value),
}
pub mod some_model {
    pub fn equals(value: Option<::prisma_client_rust::serde_json::Value>) -> WhereParam {
        WhereParam::SomeColumn(_prisma::read_filters::JsonNullableFilter::Equals(value))
    }
}
Brendonovich commented 1 year ago

This is an interesting one... Turns out Prisma's null handling is way more complex than I expected. Making Equals contain an Option should do the trick for now but I feel like more will need to be done eventually.

Brendonovich commented 1 year ago

🙃

image
Brendonovich commented 1 year ago

Ok, so Prisma Client JS deals with nulls by exposing an enum like this, since it only has one null type:

pub enum JsonNullValueFilter {
    DbNull,
    JsonNull,
    AnyNull,
}

But Rust has both Option::None and serde_json::Value::Null, which I feel would be more ergonomic - though it doesn't account for AnyNull, which allows checking for both at once. I'm tossing up adding an is_null function or doing some trait stuff to allow passing both serde_json::Value and JsonNullValueFilter to equals. I'm not sure I want Option<serde_json::Value> since it's 2/3 of JsonNullValueFilter but not as clear what's going on.

Brendonovich commented 1 year ago

I've half-fixed this on c2353175992a502e9eda580533629e97d4974d6e - JsonNullableFilter::Equals now takes Option<serde_json::Value>. Still unsure about AnyNull, maybe is_any_null() is the best option.

tgrgds commented 1 year ago

Temporary fix that has worked for me is to set a default value instead:

model some_model {
    id                     String               @id @unique @db.Uuid
    some_column            Json                 @default("[]")
}

Is this the only workaround until your fix is released?

Brendonovich commented 1 year ago

I guess so, I haven't explored any workarounds myself

m1guelpf commented 12 months ago

Hit this issue as well (and switched to main to keep going). Noticed that any nullable JSON fields are absent from the SetParams enum, making it impossible to set our update their values (this also happens for arrays of custom Prisma enums).

model Predictions {
  id String @id @default(uuid())
  input Json
  metrics Json?
  output Json   @default("{}")
  webhookFilter WebhookEvent[]
}
#[derive(Debug, Clone)]
pub enum SetParam {
  Id(super::_prisma::write_params::StringParam),
  Input(super::_prisma::write_params::JsonParam),
  Output(super::_prisma::write_params::JsonParam),
}
matthewgapp commented 11 months ago

I have this same issue. @m1guelpf by chance, what sha did you reference when you switched to main? Code gen via the CLI on the latest main seems to be broken.

m1guelpf commented 11 months ago

@matthewgapp rev bb1c2d3 works for me