Prisma1: Updating unique strings to null seems to result in an internal server error

Created on 14 May 2018  路  10Comments  路  Source: prisma/prisma1

Bug Report

Current behavior

type A {
  id: ID! @unique
  b: String! @unique
  key: String! @unique
}
mutation a {
  createA(data: {
    b: "abc"
    key: "abc"
  }) {
    id
  }
}

mutation b {
  updateA(
    where: { b: "abc" }
    data: {
      key: null
    }) {
    id
  }
}

results in

"exception": "java.util.NoSuchElementException: Bad(InvalidValueForScalarType(None,String)).get",
"stack_trace": "org.scalactic.Bad.get(Or.scala:1368)\\n org.scalactic.Bad.get(Or.scala:1305)\\n com.prisma.api.mutactions.DatabaseMutactions.updateNodeSelectorValue(DatabaseMutactions.scala:219)\\n com.prisma.api.mutactions.DatabaseMutactions.$anonfun$getMutactionsForUpdate$1(DatabaseMutactions.scala:36)\\n scala.Option.map(Option.scala:146)\\n com.prisma.api.mutactions.DatabaseMutactions.getMutactionsForUpdate(DatabaseMutactions.scala:36)\\n com.prisma.api.mutations.Update.$anonfun$prepareMutactions$1(Update.scala:35)\\n scala.util.Success.$anonfun$map$1(Try.scala:251)\\n scala.util.Success.map(Try.scala:209)\\n scala.concurrent.Future.$anonfun$map$1(Future.scala:287)\\n scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:29)\\n scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:29)\\n scala.concurrent.impl.CallbackRunnable.run(Promise.scala:60)\\n scala.concurrent.impl.ExecutionContextImpl$AdaptedForkJoinTask.exec(ExecutionContextImpl.scala:140)\\n java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)\\n java.util.concurrent.ForkJoinPool$WorkQueue.pollAndExecAll(ForkJoinPool.java:1021)\\n java.util.concurrent.ForkJoinPool$WorkQueue.execLocalTasks(ForkJoinPool.java:1046)\\n java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1058)\\n java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)\\n java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)",

Expected behavior?

Not sure if this should be rejected or allowed due to unique constraint.

I think it should be allowed.

bu2-confirmed areapi areconnectomysql statustale

All 10 comments

The error shown is a bug since it should be allowed to set null even when @unique is set. Following the SQL standard we do not consider multiple nulls to be a violation of the unique property.

Key is a required field though, so the mutation would be illegal from that perspective. But there should be a different error message for that.

I just tried reproducing this and failed. I get the expected error message. I also tried it with key not being required and that just worked. Do you have some more info to reproduce this?

bildschirmfoto 2018-05-15 um 10 20 37

@do4gr I'm the one that raised this issue with @marktani on Slack.

I believe the issue is related to using the same property that you want to set to null as the property in the where selector.

We are testing it via the playground by running the following mutation which in the resolver sets the code property to null. If I change the where clause to use a different selector, eg: email or id it works as expected and code is set to null.

mutation{
  updatePassword(where:{code:"xyz123"}
    data:{
      password: "blabla"
      passwordVerify: "blabla"
    }){
      success
      message
    }
}

I have a custom mutation called updatePassword, here are the relevant parts from my schema.graphql

updatePassword(data: UpdatePasswordData!, where: UpdatePasswordWhere!): SuccessPayload!

input UpdatePasswordWhere {
  code: String!
}

input UpdatePasswordData {
  password: String!
  passwordVerify: String!
}

type SuccessPayload {
  success: Boolean!
  message: String!
}

I've clipped some of the code for brevity, but I believe everything important is there, let me know if I can provide more. Here is the actual resolver function itself where we try to set the property named code to null:

async updatePassword(parent, { data, where }, ctx: Context, info) {
......
const updatedData = { ...data, password, code: null }
    try {
      const updatedUser = await ctx.db.mutation.updateUser({
        data: updatedData,
        where: { code: where.code }
      })
      return {
        success: true,
        message: 'Password Updated'
      }
    } catch (e) {
...

Then we get the error that @marktani outlined above.

I should note, please feel free to ping me on Prisma Slack (steveb), happy to work through it in real-time.

Thanks for the detailed reproduction @k00k! I'll try to look into it tomorrow.

Sorry for the long delay. I can reproduce it now. You're correct it only happens if you try to set the where parameter to null.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

A proper fix for this is available in 1.12-beta now.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This is now released.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jannone picture jannone  路  3Comments

sedubois picture sedubois  路  3Comments

ragnorc picture ragnorc  路  3Comments

MitkoTschimev picture MitkoTschimev  路  3Comments

schickling picture schickling  路  3Comments