Graphql-engine: update_*_by_pk mutation with empty body should still return the target row

Created on 22 Oct 2020  路  4Comments  路  Source: hasura/graphql-engine

Consider the following GraphQL mutation:

  mutation ExampleMutation {
  update_user_by_pk(pk_columns: {id: 10}, _set: {}) {
    username
  }
}

Today, this returns update_user_by_pk: {} instead of update_user_by_pk: { username: "lilred" }.

This is problematic for my use case. I have a choice of several plug-ins that I can dispatch some request to, and they return a field to put in _set for update_user_by_pk. One of my plug-ins returns the empty object, but this breaks calling code because now when I submit the subsequent mutation I'm not getting the username back.

question

All 4 comments

Not having a _set value means there is no update to be performed and hence there is no way to return target rows from PG.

I haven't looked into the Hasura internals, so I apologize if I'm making a fool out of myself -

  • How are update_*_by_pk calls translated into SQL? If you could link me to the source I would appreciate it a ton.
  • Hasura could detect _set: {} in update_*_by_pk and execute a SELECT instead of an UPDATE. Is there a reason this couldn't work in principle? I'm not trying to imply that this is the correct thing to do, but it does seem like one possible way of accomplishing it.
  • Do you agree that this is counter-intuitive behaviour? If so, do you think it would be a good idea to "fix" it? I wouldn't mind taking a crack at it if someone can tell me where to look.

How are update_*_by_pk calls translated into SQL?

It's basically using the RETURNING clause to return the updated rows: https://www.postgresql.org/docs/12/sql-update.html

Hasura could detect _set: {} in update_*_by_pk and execute a SELECT instead of an UPDATE.

I guess it could do it but it would be against the semantics of update which only returns updated rows.

Do you agree that this is counter-intuitive behaviour?

I do not agree that this is counter-intuitive. Since there is nothing to update, hence nothing to return. In fact, it is worth looking into throwing a validation error for an empty _set : {} object for update mutations.

If you need a workaround, then you can set the primary key again:

update_user_by_pk(pk_columns: {id: 10}, _set: {id: 10})

I guess it could do it but it would be against the semantics of update which only returns updated rows.

I didn't expect "update" to include no-ops, but if Postgres is saying that a no-op counts, then I guess a no-op counts! Thank you for your time. I'll use that work-around.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

egislook picture egislook  路  3Comments

bogdansoare picture bogdansoare  路  3Comments

EmrysMyrddin picture EmrysMyrddin  路  3Comments

coco98 picture coco98  路  3Comments

marionschleifer picture marionschleifer  路  3Comments