# `DELETE` mutations on SQL Server ## Metadata ``` --- authors: Abby (@sassela), Gil (@soupi) --- ``` ## User story As a user, I would like to be able to delete rows from a certain mssql table using a predicate, similarly to how I'm able to do so for a postgres table. Deleting rows from a table should be done via sending a GraphQL mutation to the `/v1/graphql` endpoint. Delete mutations should respect [row-level permissions](https://hasura.io/docs/latest/graphql/core/auth/authorization/permission-rules.html#delete-permissions). ## Interface ### Request Users can specify a deletion mutation in one of the following ways: * `delete` syntax - Delete via a predicate on one of the root table fields: https://hasura.io/docs/latest/graphql/core/api-reference/graphql-api/mutation.html#delete-syntax https://hasura.io/docs/latest/graphql/core/databases/postgres/mutations/delete.html#delete-objects-based-on-their-fields - Delete via a predicate on one of the nested object fields: https://hasura.io/docs/latest/graphql/core/databases/postgres/mutations/delete.html#delete-objects-based-on-nested-objects-fields - Delete all objects in a table using the {} expression as the where argument: https://hasura.io/docs/latest/graphql/core/databases/postgres/mutations/delete.html#delete-all-objects `delete` syntax: ``` mutation [] { ( [where-argument!] ) { [mutation-response!] } } ``` * `delete_by_pk` syntax: https://hasura.io/docs/latest/graphql/core/api-reference/graphql-api/mutation.html#delete-by-pk-syntax ### Response The mutation response is specified in the [GraphQL spec](https://spec.graphql.org/June2018/#sec-Mutation), including: ```graphql { data # the returned data is specified by the `mutation-response` section { affected_rows returning { # the `returning` statement can include nested objects response-field1 response-field2 .. } } } ``` or ... ```graphql { errors { extensions message } } ``` ## Success - [test_graphql_mutations.py](https://github.com/hasura/graphql-engine-mono/blob/main/server/tests-py/test_graphql_mutations.py) tests pass for MSSQL: - test for each of the above linked queries - basic deletes: `TestGraphqlDeleteBasic` - table permissions: `TestGraphqlDeletePermissions` - constraints and errors: `TestGraphqlDeleteConstraints` - custom schema - custom names: `TestGraphqlMutationCustomGraphQLTableName` - custom root fields: `TestGraphqlMutationCustomSchema` - delete mutations are executable via the console and CLI - delete mutations on SQL Server are documented in Hasura docs. The [existing Postgres docs](https://hasura.io/docs/latest/graphql/core/databases/postgres/mutations/delete.html) can be used as a guide. ## Checkpoints *These checkpoints do not necessarily need to be delivered in the same PR. In fact, prefer smaller PRs where they are functional, tested, and self-contained.* - [generate `DELETE` mutations schema](https://github.com/hasura/graphql-engine/issues/7625) by completing the `msBuildTableDeleteMutationFields` function - [generate and execute `DELETE` SQL by adding an `executeDelete` function](https://github.com/hasura/graphql-engine/issues/7626) - `convertDelete` can be used as a reference implementation for SQL generation - `executeInsert` can be used as a reference implementation for mutation response generation - We cannot retrieve `returning` fields once the delete statement is executed.Consider the following options to fetch `returning` output: 1. Use [table variables](https://docs.microsoft.com/en-us/sql/t-sql/data-types/table-transact-sql) in conjunction with the [`OUTPUT` clause](https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sq) to capture the delete statement's output. 2. `SELECT` then `DELETE`: Fetch the data for `returning` and `affected_rows` fields first, by running the `SELECT` query generated by `mkMutationOutputSelect` inclusive of the `DELETE` query's `WHERE` and permissions filters, i.e. ```sql WITH with_alias AS ( SELECT * FROM table_name WHERE )