Commit 14e362f
committed
ALTER TABLE ADD [COLUMN] col TYPE [, …] / DROP COLUMN [IF EXISTS] col [, …] — closes the largest remaining EF Migrations DDL gap. ParseColumnList refactored to extract
ParseOneColumnIntoLists (the per-column parsing body — name + type + inline constraint loop), reusable from both CREATE TABLE and the new ALTER-side parser; CREATE TABLE behavior unchanged. New Simulation.AlterTableColumn.cs partial drives both shapes from the existing TryParseAlterTableAddConstraint / TryParseAlterTableDropConstraint dispatchers, routing on Keyword.Column (or any non-constraint leading identifier for the bare ADD col … form). HeapTable.Columns / StoredColumns / StorageOrdinals / Schema / Heap dropped readonly (they were already populated post-construction by the constructor's projection loop; now also mutated by ALTER TABLE column ops); new RecomputeStorageProjections() helper encapsulates the projection invariant. ADD COLUMN supports multi-column comma list, the optional COLUMN keyword, IDENTITY (seed/increment), inline DEFAULT (named or auto), inline CHECK / UNIQUE / PRIMARY KEY / REFERENCES, and computed columns (col AS expr [PERSISTED [NOT NULL]]); existing-table identity count seeded from HeapTable.IdentityOrdinal so a second IDENTITY raises Msg 2744. Backfill semantic matches probe-confirmed SQL Server quirks: nullable ADD always backfills NULL (DEFAULT applies only to future inserts), NOT NULL with DEFAULT evaluates once and snapshots the same value to every existing row (GETUTCDATE produces one timestamp not per-row), IDENTITY backfills seed / seed+inc / … in heap-scan order, ROWVERSION pulls per-row from the database-scoped counter, and NOT NULL without DEFAULT/IDENTITY/ROWVERSION on a non-empty table raises Msg 4901 (full canonical paragraph wording). Msg 2705 fires on column-name collision with an existing column OR a duplicate within the same multi-column ADD. New PK / UQ / CHECK / FK declarations route through the existing ResolveKeyConstraints / ResolveCheckConstraints / ResolveForeignKeys pipelines after shifting their FullOrdinals by existing column count so the resolvers see the post-add combined column view; any resolver failure (Msg 1505 unique-on-duplicates, etc.) unwinds the schema mutation via a try/catch that restores table.Columns + RecomputeStorageProjections + truncates the appended constraints. Three MoveNextRequired → MoveNextOptional changes in the shared column parser (after type-length close paren, after NOT NULL, after bare NULL, after IDENTITY's close paren, after inline CHECK's close paren) let the column parser terminate cleanly at end-of-batch — CREATE TABLE still hits the close ) of the column list, ALTER ADD COLUMN can run out of tokens. DROP COLUMN is two-pass-atomic: pass 1 resolves every name (Msg 4924 on miss unless IF EXISTS) and walks each column's dependencies via CollectColumnDependencies (PK/UQ via StorageOrdinals, outgoing FK via ChildColumnOrdinals, incoming FK via ReferencedColumnOrdinals on this table, CHECK via InlineColumn + structural predicate walk for table-level CHECKs, DEFAULT via HeapColumn.DefaultConstraint, index via Index.KeyColumns + IncludedColumns); pass 2 applies the mutation only when every column cleared. Msg 5074 lists every blocker on its own line with the probe-confirmed prefix split (The object 'X' for constraints, The index 'X' for indexes) — DropColumnHasDependenciesMixed accepts a per-blocker (name, isIndex) tuple. Surviving constraint / index / FK ordinals remap in place via oldStorageToNew[] / oldFullToNew[] arrays — KeyConstraint.StorageOrdinals elements, Index.KeyColumns slot replacement, Index.IncludedColumns elements, ForeignKey.ChildColumnOrdinals (outgoing) and ReferencedColumnOrdinals (incoming) all assigned. Heap re-encoded by decoding each row under the pre-drop StoredColumns layout, projecting through surviving ordinals, and encoding against the new StoredColumns; Heap field replaced wholesale. Five new error factories: AddColumnRequiresDefaultOrNullable (4901), DropColumnDoesNotExist (4924), DropColumnHasDependenciesMixed (5074 with multi-blocker enumeration), ColumnNamesMustBeUnique (2705); existing factories CannotFindObjectForAlterTable (4902), MultipleIdentityColumns (2744), PrimaryKeyOnNullableColumn (8111), DuplicateKeyOnCreate (1505) all reused. 33 new AlterTableColumnTests cover ADD (nullable / NOT NULL with and without DEFAULT / GETUTCDATE constant-snapshot / 4901 path / IDENTITY backfill / 2744 second-identity / optional COLUMN keyword / multi-column comma list / 2705 duplicate / inline CHECK / inline FK / computed column / sys.columns visibility) and DROP (basic remove / row preservation / 4924 missing / IF EXISTS / 5074 across DEFAULT/CHECK/PK/outgoing-FK/incoming-FK/index-key/index-include / multi-column atomicity / IDENTITY drop / round-trip ADD+DROP / middle-column drop preserving remaining-column read + PK enforcement + UNIQUE index enforcement). Two pre-existing tests asserting NotSupportedException on ALTER TABLE ADD COLUMN updated (one removed entirely; one re-targeted to ALTER COLUMN which is still deferred). CLAUDE.md "Not modeled" entry rewritten — ADD / DROP COLUMN listed alongside the already-shipped ADD / DROP CONSTRAINT shapes; ALTER COLUMN remains the only column-mutation shape still raising NotSupportedException. docs/claude/alter-table.md gains a "Column ops" section with the grammar, backfill semantic table, error-path matrix, dependency-rejection enumeration, storage rewrite mechanics, and four documented fidelity gaps (eager rewrite vs metadata-only optimization, non-transactional column DDL, table-variable column ops, single-primary-error vs trailing-informational pair).1 parent c7f5ec3 commit 14e362f
10 files changed
Lines changed: 1467 additions & 229 deletions
File tree
- SqlServerSimulator.Tests
- SqlServerSimulator
- Errors
- Simulation
- Storage
- docs/claude
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
178 | 178 | | |
179 | 179 | | |
180 | 180 | | |
181 | | - | |
| 181 | + | |
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 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 | + | |
| 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 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 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 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
0 commit comments