Commit 62f9c08
committed
MERGE WHEN MATCHED expansion: full branch-family parser + executor — WHEN MATCHED [AND <cond>] THEN UPDATE SET … / DELETE, WHEN NOT MATCHED [BY TARGET] [AND <cond>] THEN INSERT … VALUES …, WHEN NOT MATCHED BY SOURCE [AND <cond>] THEN UPDATE / DELETE. Source lifted from VALUES-only to any Selection (SELECT / set-op chain), gated by a parse-time materializer that picks VALUES-tuple-eval vs Selection.Execute. Single-pass executor: target × source scan collects per-target match lists, dispatches first-AND-satisfied WHEN clause; queued inserts/updates/deletes apply atomically (PK/UNIQUE validation runs on the union via sentinel-address EnforceKeyConstraintsForUpdate so a constraint violation rolls back the entire MERGE). $action pseudo-column tokenized as a single $action UnquotedString (replaces the default $-as-money + action-as-name split), recognized in OUTPUT through any AS-alias wrapper via IsMergeActionRef drilling past NamedExpression; projects uppercase 'INSERT' / 'UPDATE' / 'DELETE' as nvarchar(10). New MergeOutputProjection handles the 4-way INSERTED / DELETED / source-alias / $action surface that the existing OutputProjection (INSERT-shape) and MutationOutputProjection (UPDATE/DELETE-shape) don't compose. Multi-match guard: target row matched by >1 source row + chosen action UPDATE → Msg 8672; DELETE is forgiving (probe-confirmed). Action-kind rejection: Msg 10711 for INSERT in MATCHED / NOT MATCHED BY SOURCE; Msg 10710 for UPDATE/DELETE in NOT MATCHED BY TARGET; Msg 10714 for multiple NOT MATCHED BY TARGET clauses; Msg 5324 for AND-after-no-AND in MATCHED / NOT MATCHED BY SOURCE; Msg 10713 for missing trailing ;. Triggers fire INSERT → UPDATE → DELETE, each kind once with combined affected rows (probe-confirmed). New contextual keywords (Source, Target) for the BY SOURCE / BY TARGET grammar. 22 new MergeTests cover every branch combination, all error paths, source-subquery + set-op shapes, $action across branches, multi-match guard (UPDATE raises, DELETE doesn't), AND first-match-wins, trigger order, and atomic rollback. CLAUDE.md "Not modeled" rewritten (MERGE WHEN MATCHED branches + $action + source subqueries shipped; CTE-headed sources / MERGE-into-view / $action-into-@t deferred); docs/claude/dml.md expanded with the MERGE deep-dive (grammar table, per-phase execution model, $action + trigger + EF reach notes).
1 parent 35ce1c5 commit 62f9c08
9 files changed
Lines changed: 1586 additions & 243 deletions
File tree
- SqlServerSimulator.Tests
- SqlServerSimulator
- Errors
- Parser
- Simulation
- docs/claude
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
116 | 116 | | |
117 | 117 | | |
118 | 118 | | |
119 | | - | |
| 119 | + | |
120 | 120 | | |
121 | | - | |
122 | | - | |
| 121 | + | |
123 | 122 | | |
124 | 123 | | |
125 | 124 | | |
| |||
165 | 164 | | |
166 | 165 | | |
167 | 166 | | |
168 | | - | |
| 167 | + | |
169 | 168 | | |
170 | 169 | | |
171 | 170 | | |
| |||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | 209 | | |
220 | 210 | | |
221 | 211 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
105 | 105 | | |
106 | 106 | | |
107 | 107 | | |
108 | | - | |
| 108 | + | |
109 | 109 | | |
110 | 110 | | |
111 | 111 | | |
| |||
Lines changed: 59 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
75 | 134 | | |
76 | 135 | | |
77 | 136 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
66 | 66 | | |
67 | 67 | | |
68 | 68 | | |
| 69 | + | |
69 | 70 | | |
| 71 | + | |
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| 50 | + | |
50 | 51 | | |
51 | 52 | | |
52 | 53 | | |
| |||
280 | 281 | | |
281 | 282 | | |
282 | 283 | | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
283 | 321 | | |
284 | 322 | | |
285 | 323 | | |
| |||
0 commit comments