[rendered](https://github.com/hasura/graphql-engine-mono/blob/rakeshkky/rfc/mssql-mutations/rfcs/mutations-mssql.md) Open for suggestions/improvements. Please comment. https://github.com/hasura/graphql-engine-mono/pull/1974 GitOrigin-RevId: 4c27d9da99e6b41efafa1c6e5557731cb16c488f
5.5 KiB
RFC: Mutations for MSSQL Server
Metadata
Authors: Rakesh
State: Draft
Teams Involved: Data Sources, Docs and Console
Slack Channels: #team-data-sources, #feature-ms-sql
Other Docs:
Description
Generation and execution of GraphQL insert, delete and update mutations for MSSQL backend with permissions enforced.
Success criteria
Taking reference to Postgres mutations we should able to generate schema and execute mutations for MSSQL backend.
For example, let's say a table with name author
is tracked from a MSSQL server backend. Considering insert
mutations,
Schema Generation: The server should able to generate following GraphQL schema
type mutation_root {
insert_author(objects: [author_insert_input!]!): author_mutation_response
}
input author_insert_input{
id: Int!
name: String!
}
type author_mutation_response {
affected_rows: Int!
returning: [author!]
}
Query Execution: The server should able to execute following sample GraphQL mutation
mutation {
insert_author(objects: [{name: "Bob"}]){
affected_rows
returning{
id
name
}
}
}
Permissions: Users should able to define row-level and column-level permissions for inserts via Metadata API or Console UI
How
+----------+ Schema Parser generation +----+ Translation +-----+ With transactions +-----------------+
| Metadata | --------------------------> | IR | -------------> | SQL | -------------------> | Execution on DB |
+----------+ with permissions enforced +----+ +-----+ +-----------------+
Schema Generation
Generate schema for MSSQL mutations with permissions enforced. Existing logic for Postgres schema generation applies here with minimal changes applicable to IR abstraction.
Query Translation / Execution
+----+ +--------------+ +-----+
| IR | -------------> | Mutation AST | -----------> | SQL |
+----+ +--------------+ +-----+
Mutation AST is a data type which can be readily translated to SQL Text. We need to have data types for each mutation operation.
data Insert
for Insertdata Update
for Updatedata Delete
for Delete
Specimen SQL for reference: Unlike Postgres, we cannot integrate DML statements in common table expression of MSSQL. Only SELECTs are allowed in a common table expression. Our proposal is to use local variables to capture mutated rows and generated appropriate response using SELECT statement.
INSERT INTO test (name, age) OUTPUT INSERTED.<primarykey-column> values ('rakesh', 25)
WITH some_alias AS (SELECT * FROM test WHERE <primarykey-column> IN (<values fetched from above SQL>))
SELECT (SELECT * FROM some_alias FOR JSON PATH, INCLUDE_NULL_VALUES) AS [returning], count(*) AS [affected_rows] FROM some_alias FOR JSON PATH, WITHOUT_ARRAY_WRAPPER;
For tables without primary key, we choose not to generate mutations schema atleast in the initial iterations.
Permissions
Like in Postgres, we need to generate expression to evaluate the check condition and return it as an extra field. If check constraint is not satisfied we'll raise exception in the Haskell code.
INSERT INTO test (name, age) OUTPUT INSERTED.<primarykey-column> values ('rakesh', 25)
WITH alias AS (SELECT * FROM test where id IN (<values-returned-from-above-sql>))
SELECT (SELECT (SELECT * FROM alias FOR JSON PATH, INCLUDE_NULL_VALUES) AS [returning], count(*) AS [affected_rows] FROM alias FOR JSON PATH, WITHOUT_ARRAY_WRAPPER) AS [data], SUM(case when (id = 12) then 0 else 1 end) AS [check_constraint] FROM alias ;
Haskell interface to execute MSSQL transactions
Mutations are executed safely via database transactions. We need to have a separate interface/library to implement MSSQL Transactions. Preferably, the library implementation details should be specified in a separate RFC. Our in-house written Postgres' transaction library acts as good reference.
Testing
Generate pytests to test
- Simple mutations with returning affected rows and count
- Mutations involving all stock column types
- Mutations with permissions
Refer to Postgres mutation tests
Future Work
- Upsert feature
- Nested inserts
- Mutations for tables without primary keys