hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.17k stars 2.76k forks source link

Hasura tries to set default values for generated column when doing nested upserts #4506

Closed Xetera closed 4 years ago

Xetera commented 4 years ago

I've had a look at #3681 and #3572 and it looks like the merged PR for that did fix regular inserts for tables with generated columns but it doesn't seem like this affected a specific case of nested upserts. I've included a repo with a reproducible behavior that shows this if needed. The query I'm using to trigger this is this: (sorry for the strange kpop examples)

mutation GroupEdit($data: [groups_insert_input!]!, $on_conflict: groups_on_conflict!) {
  group: insert_groups(objects: $data, on_conflict: $on_conflict) {
    affected_rows
    returning {
      name
      members {
        idol {
          full_name
          korean_stage_name
        }
      }
    }
  }
}

When calling it with input like

{
  "data": [
    {
      "name": "TWICE",
      "korean_name": "트와이스",
      "company_name": "JYP",
      "status": "ACTIVE",
      "members": {
        "data": [
          {
            "idol_id": 576
          }
        ],
        "on_conflict": {
          "constraint": "group_members_id_key",
          "update_columns": []
        }
      }
    }
  ],
  "on_conflict": {
    "constraint": "groups_id_key",
    "update_columns": []
  }
}

All is well and hasura responds as expected, however when the "members": { data: [] } block is changed to

members: {
  "data":[{
    "idol_id": 576
  }, {
    "idol_id": 577
  }]
}

Or when the nested upsert input is above the length of 1 the response becomes

{
  "errors": [
    {
      "extensions": {
        "internal": {
          "statement": "WITH \"public_group_members__mutation_result_alias\" AS (INSERT INTO \"public\".\"group_members\" ( \"status\", \"join_date\", \"role\", \"idol_id\", \"updated_at\", \"departure_date\", \"created_at\", \"id\", \"group_id\" ) VALUES (DEFAULT, DEFAULT, DEFAULT, ($2)::integer, DEFAULT, DEFAULT, DEFAULT, DEFAULT, ($1)::integer), (DEFAULT, DEFAULT, DEFAULT, ($4)::integer, DEFAULT, DEFAULT, DEFAULT, DEFAULT, ($3)::integer) ON CONFLICT ON CONSTRAINT \"group_members_id_key\" DO NOTHING RETURNING * , CASE WHEN 'true' THEN NULL ELSE \"hdb_catalog\".\"check_violation\"('insert check constraint failed')  END ) SELECT  json_build_object('affected_rows', (SELECT  COUNT(*)  FROM \"public_group_members__mutation_result_alias\"      ) )        ",
          "prepared": true,
          "error": {
            "exec_status": "FatalError",
            "hint": null,
            "message": "cannot insert into column \"status\"",
            "status_code": "42601",
            "description": "Column \"status\" is a generated column."
          },
          "arguments": [
            "(Oid 0,Just (\"140\",Text))",
            "(Oid 23,Just (\"\\NUL\\NUL\\STX@\",Binary))",
            "(Oid 0,Just (\"140\",Text))",
            "(Oid 23,Just (\"\\NUL\\NUL\\STXA\",Binary))"
          ]
        },
        "path": "$.selectionSet.insert_groups.args.objects[0].members.data",
        "code": "unexpected"
      },
      "message": "postgres query error"
    }
  ]
}

Postgres version: 12 Hasura version: 1.2.0-beta.2.cli-migrations

rikinsk commented 4 years ago

related #4633

codingkarthik commented 4 years ago

@Xetera This issue is a dupe of #4633

Basically, this issue is caused due to a bug in postgres. More details in my comment here

Speaking specifically to the issue's title, yes, hasura sets the default value which should ideally work even for generated column.