Commit 4fbe9f8
authored
Mutations on table with triggers - MsSql (#1630)
## Why make this change?
When there is a DML trigger configured on a table, we cannot use OUTPUT
clause to return data. When an insert DML trigger is configured, OUTPUT
clause cannot be used to return data because of the insert operation.
When an update DML trigger is configured, OUTPUT clause cannot be used
to return data because of the update operation. In such cases, we need
to use a subsequent select statement to get the data after the mutation.
## Details
**What would handling of different kind of mutations look like when a
trigger is enabled on a table?**
1. **DELETE:** We don't need to return any data for deletions, so
nothing will change for deletions.
2. **UPDATE:** For updates, we will cease to use the output clause.
Instead, we will do a subsequent select query on the table to get the
data. Since PK would already be provided to us we can easily do a select
query. Not to mention, we can do this only when we determine that there
is indeed a trigger enabled on the table. If not, we can continue with
the same query that we generate in present day.
3. **INSERT:** When it comes to insertions, we can perform insertions on
two kind of tables:
1. **Tables with non-auto generated primary keys:** When we have tables
with non-autogen PK, we can insert values of non-autogen PK fields into
a temporary table (we might not know value of every PK before hand
because PK can have a default value as well) and then perform an inner
join for the subsequent select on the actual table and the temporary
table based on the values of these PK fields.
2. **Tables with auto-gen primary keys:** Tables with an autogenerated
PK column fall into this category.. For tables with autogen PK, we would
not be aware of the PK beforehand and so we cannot directly perform the
subsequent select query. To get the autogen primary key, we can use
`SCOPE_IDENTITY()` method provided by Sql Server.. Once we get the
autogen PK, in addition to having an inner join for non-autogen PKs as
discussed in the previous approach, we can add an additional `WHERE`
predicate `where autogen_PK_field = SCOPE_IDENTITY()`. Let us discuss
more about this approach and the concerns:
**Delving deeper into
[Approach#3](#452 (comment)
We can use `OUTPUT` clause coupled with `INTO` clause to store the
values for the primary keys in a temporary table. And then do a
subsequent select query on the table to get the data using those primary
keys. In the temporary table, we insert only those columns from the PK
which are not autogenerated. Why? Because we cannot insert a value for
an autogenerated column even in a temporary table. Hence in the select
query, we will add an additional WHERE predicate (alongwith the join)
for the autogenerated column in the PK. It is to be noted that **MsSql
supports only one IDENTITY/autogenerated column per table**.
We can choose to go with this approach only if we determine that there
are any triggers enabled on the table.
Two assumptions which I am making here that I want to put ahead (btw, I
don't think those are valid use cases) are:
1. **What if primary key column has a datatype of timestamp?** This
concern arise because we cannot insert value for `timestamp` column
(which is what the approach includes - inserting value via `INTO`
clause). Well, `rowversion`/`timestamp` is intended for versioning and
tracking changes within a table, rather than serving as a primary key.
Also, by design, primary key values should not be modified after they
have been assigned to a record. So having a PK with timestamp datatype
does not seem to be a valid use case to me.
2. **What if the trigger updates the values of the primary keys** and
the subsequent select query we are going to perform returns no data
because the values of the PK has been changed in the table? This concern
arises because technically, it is possible for triggers to update the
value of PK columns. However, this is generally not recommended and can
lead to undesirable consequences. Changing the value of a primary key
can result in data integrity issues, as it may cause conflicts or break
referential integrity constraints if other tables are referencing the
primary key. It can also lead to confusion and difficulty in identifying
records uniquely.
## What is this change?
1. Added properties `IsUpdateDMLTriggerEnabled` and
`IsInsertDMLTriggerEnabled` to `SourceDefinition` class which if true
will indicate that there is a corresponding DML trigger enabled on the
table.
2. Added method `SqlMetadataProvider.PopulateTriggerMetadataForTable`
whose overridden implementation in `MsSqlMetadataProvider` will populate
the properties mentioned in (1) with appropriate metadata values.
3. Refactored how queries are built in the `SqlInsertStructure`,
`SqlUpsertQueryStructure`, `SqlUpdateStructure` so that when trigger is
configured for the mutation operation, a subsequent select query is used
instead of the `OUTPUT` clause to return data.
4. In case of insertions in table with auto-gen PK, we get the latest
value of the auto-gen column using `SCOPE_IDENTITY() ` function provided
by sql server. Reference:
https://learn.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql?view=sql-server-ver16
## How was this tested?
- [x] Integration Tests - Added mutations tests to Rest/GQL performing
inserts/updates/upserts on tables with insert/update DML trigger
enabled. Tests are added for tables with autogen/non-autogen PK as the
queries differ in the two cases.1 parent a5f9db0 commit 4fbe9f8
File tree
15 files changed
+963
-25
lines changed- config-generators
- src
- Config/DatabasePrimitives
- Core
- Resolvers
- Services/MetadataProviders
- Service.Tests
- Snapshots
- SqlTests
- GraphQLMutationTests
- RestApiTests
- Insert
- Patch
- Put
15 files changed
+963
-25
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| 42 | + | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
154 | 154 | | |
155 | 155 | | |
156 | 156 | | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
157 | 172 | | |
158 | 173 | | |
159 | 174 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
76 | 82 | | |
77 | 83 | | |
78 | 84 | | |
| |||
Large diffs are not rendered by default.
Lines changed: 38 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
4 | 8 | | |
| 9 | + | |
5 | 10 | | |
6 | 11 | | |
7 | 12 | | |
| |||
40 | 45 | | |
41 | 46 | | |
42 | 47 | | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
43 | 81 | | |
44 | 82 | | |
Lines changed: 20 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | | - | |
| 72 | + | |
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| |||
361 | 361 | | |
362 | 362 | | |
363 | 363 | | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
364 | 377 | | |
365 | 378 | | |
366 | 379 | | |
| |||
975 | 988 | | |
976 | 989 | | |
977 | 990 | | |
| 991 | + | |
| 992 | + | |
| 993 | + | |
| 994 | + | |
| 995 | + | |
| 996 | + | |
978 | 997 | | |
979 | 998 | | |
980 | 999 | | |
981 | | - | |
982 | 1000 | | |
983 | 1001 | | |
984 | 1002 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
| 51 | + | |
50 | 52 | | |
51 | 53 | | |
52 | 54 | | |
| |||
256 | 258 | | |
257 | 259 | | |
258 | 260 | | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
259 | 278 | | |
260 | 279 | | |
261 | 280 | | |
| |||
468 | 487 | | |
469 | 488 | | |
470 | 489 | | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
471 | 497 | | |
472 | 498 | | |
473 | 499 | | |
| |||
545 | 571 | | |
546 | 572 | | |
547 | 573 | | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
Lines changed: 52 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2359 | 2359 | | |
2360 | 2360 | | |
2361 | 2361 | | |
| 2362 | + | |
| 2363 | + | |
| 2364 | + | |
| 2365 | + | |
| 2366 | + | |
| 2367 | + | |
| 2368 | + | |
| 2369 | + | |
| 2370 | + | |
| 2371 | + | |
| 2372 | + | |
| 2373 | + | |
| 2374 | + | |
| 2375 | + | |
| 2376 | + | |
| 2377 | + | |
| 2378 | + | |
| 2379 | + | |
| 2380 | + | |
| 2381 | + | |
| 2382 | + | |
| 2383 | + | |
| 2384 | + | |
| 2385 | + | |
| 2386 | + | |
| 2387 | + | |
| 2388 | + | |
| 2389 | + | |
| 2390 | + | |
| 2391 | + | |
| 2392 | + | |
| 2393 | + | |
| 2394 | + | |
| 2395 | + | |
| 2396 | + | |
| 2397 | + | |
| 2398 | + | |
| 2399 | + | |
| 2400 | + | |
| 2401 | + | |
| 2402 | + | |
| 2403 | + | |
| 2404 | + | |
| 2405 | + | |
| 2406 | + | |
| 2407 | + | |
| 2408 | + | |
| 2409 | + | |
| 2410 | + | |
| 2411 | + | |
| 2412 | + | |
| 2413 | + | |
2362 | 2414 | | |
2363 | 2415 | | |
2364 | 2416 | | |
| |||
0 commit comments