Skip to content

Commit 56175e6

Browse files
committed
ALTER TABLE … (CHECK | NOCHECK) CONSTRAINT (ALL | name [, …]) trust toggling for the bulk-import idiom (NOCHECK on FK + CHECK to push large batches that would otherwise violate, then CHECK to re-enable). Adds an independent IsDisabled flag (mutable bool) to both ForeignKey + CheckConstraint, separate from the existing IsNotTrusted — the enforcement loops (EnforceCheckConstraints in Simulation.Coerce.cs; EnforceOutgoingForeignKeys + EnforceIncomingForeignKeys + EnforceIncomingFkOnUpdate in Simulation.ForeignKeys.cs) now skip when IsDisabled. Probe-confirmed semantic: disabled CASCADE FK leaves children orphaned when parent deletes (cascade actions suppress alongside NO-ACTION rejects), and bare CHECK CONSTRAINT name (no WITH-prefix) re-enables enforcement without revalidating existing data — IsDisabled = false but IsNotTrusted stays true, the common gotcha. The WITH-prefix at the front of the ALTER widens from bool withNoCheck to a tri-state bool? withCheckExplicit (null = no prefix, false = WITH NOCHECK, true = WITH CHECK) so each action branch applies its own default: ADD defaults to validate (WITH NOCHECK skips), CHECK CONSTRAINT defaults to skip-validate (WITH CHECK revalidates and clears IsNotTrusted on success, raising Msg 547 with the "ALTER TABLE statement" prefix on existing-row failure). NOCHECK CONSTRAINT ignores the WITH-prefix entirely (real SQL Server accepts but ignores; NOCHECK always implies "don't validate"). The new TryParseAlterTableTrustToggle handler in Simulation.AlterTableConstraint.cs reuses the existing ValidateExistingRowsForForeignKey / ValidateExistingRowsForCheckConstraint helpers from the ADD-side bundle to drive the WITH CHECK revalidation. ALL keyword targets every FK + CHECK on the table at once; comma-separated name lists resolve atomically (any Msg 4917 prevents all mutations — probe-confirmed). New Msg 4917 factory ("Constraint 'name' does not exist.") covers the missing-name path. sys.foreign_keys.is_disabled and sys.check_constraints.is_disabled now read from the new flag (previously hardcoded 0). 14 new AlterTableTrustToggleTests cover NOCHECK/CHECK toggling on FK + CHECK, the cascade-suppressed-while-disabled case, bare vs WITH-CHECK re-enable distinction, WITH CHECK CHECK CONSTRAINT revalidation including Msg 547 failure paths, ALL keyword across all three actions, Msg 4917 missing-name path, multi-name atomicity, and the end-to-end bulk-import recipe. docs/claude/alter-table.md gains a trust-toggling section with the IsDisabled-vs-IsNotTrusted matrix and the bulk-import recipe; CLAUDE.md trigger-phrase + "Not modeled" entry updated; foreign-keys.md fidelity gap for WITH CHECK CHECK CONSTRAINT (re-trust) removed.
1 parent fe8e432 commit 56175e6

12 files changed

Lines changed: 524 additions & 29 deletions

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ Per-feature deep-dives live under `docs/claude/`. Each entry below is a trigger:
152152
- **Touching `CREATE TRIGGER` / `ALTER TRIGGER` / `DROP TRIGGER` / `DISABLE`/`ENABLE TRIGGER`, the `INSERTED` / `DELETED` pseudo-table materialization, the `TriggerFrame` / `FiringTriggerIds` recursion guard, `TRIGGER_NESTLEVEL()`, or `sys.triggers`**[`docs/claude/triggers.md`](docs/claude/triggers.md).
153153
- **Touching `FOREIGN KEY` parsing (`REFERENCES` inline / `FOREIGN KEY (cols) REFERENCES other(cols)` table-level), referential-action wiring (`ON DELETE` / `ON UPDATE` × `NO ACTION` / `CASCADE` / `SET NULL` / `SET DEFAULT`), the FK enforcement loop in `Simulation.ForeignKeys.cs`, the `HeapTable.OutgoingForeignKeys` / `IncomingForeignKeys` lists, cascade-cycle detection (Msg 1785), DROP-TABLE protection (Msg 3726), or `sys.foreign_keys` / `sys.foreign_key_columns`**[`docs/claude/foreign-keys.md`](docs/claude/foreign-keys.md).
154154
- **Touching `PERIOD FOR SYSTEM_TIME` / `GENERATED ALWAYS AS ROW START / END [HIDDEN]` / `WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = …))` DDL, `ALTER TABLE … SET (SYSTEM_VERSIONING = OFF)`, the auto-created history sibling, `FOR SYSTEM_TIME ALL / AS OF` query syntax, or `HeapTable.PeriodColumns` / `HeapTable.SystemVersioning` / `HeapColumn.GeneratedAs` / `HeapColumn.IsHidden`**[`docs/claude/temporal-tables.md`](docs/claude/temporal-tables.md).
155-
- **Touching `ALTER TABLE … ADD CONSTRAINT` (PK / UQ / FK / CHECK / DEFAULT), `ALTER TABLE … DROP CONSTRAINT [IF EXISTS]`, `WITH CHECK` / `WITH NOCHECK`, the existing-data-validation scan, the constraint-name uniqueness check, the atomic multi-drop pipeline, or `sys.check_constraints` / `sys.key_constraints` / `sys.default_constraints`**[`docs/claude/alter-table.md`](docs/claude/alter-table.md).
155+
- **Touching `ALTER TABLE … ADD CONSTRAINT` (PK / UQ / FK / CHECK / DEFAULT), `ALTER TABLE … DROP CONSTRAINT [IF EXISTS]`, `ALTER TABLE … (CHECK | NOCHECK) CONSTRAINT (ALL | name [,…])` trust toggling, `WITH CHECK` / `WITH NOCHECK`, the existing-data-validation scan, the constraint-name uniqueness check, the atomic multi-drop / multi-toggle pipeline, the `IsDisabled` / `IsNotTrusted` enforcement gates, or `sys.check_constraints` / `sys.key_constraints` / `sys.default_constraints`**[`docs/claude/alter-table.md`](docs/claude/alter-table.md).
156156
- **Adding a new top-level statement parser or changing the dispatch loop's statement-separator rules**[`docs/claude/grammar.md`](docs/claude/grammar.md) + [`docs/claude/control-flow.md`](docs/claude/control-flow.md).
157157

158158
## Not modeled
@@ -177,7 +177,7 @@ Per-feature deep-dives live under `docs/claude/`. Each entry below is a trigger:
177177
- T-SQL `GOTO` / labels — `IF` / `BEGIN…END` / `WHILE` / `BREAK` / `CONTINUE` / `RETURN` (bare + UDF-body and stored-procedure-body value form) ship; unconditional jumps don't.
178178
- CLR functions, INSTEAD OF UPDATE / DELETE on *non-updatable* views (INSTEAD OF INSERT on any view ships; INSTEAD OF UPDATE / DELETE on updatable single-base views ships). DDL / logon triggers also unmodeled. Scalar UDFs, inline TVFs, multi-statement TVFs (`RETURNS @r TABLE (cols) AS BEGIN ... END` — EF Core `HasDbFunction` end-to-end), views, DML-through-views (single-source updatable shape), stored procedures (including CREATE / ALTER / DROP, EXEC with input/output/default params, `@rc = EXEC` return-code capture, `CommandType.StoredProcedure`, `EXEC (@sql)` and `sp_executesql` dynamic SQL), user-defined table types + table-valued parameters (CREATE TYPE … AS TABLE / DROP TYPE / DECLARE @t MyType / READONLY proc params / EXEC with TVP arg / ADO.NET Structured parameter via the `DbParameter.TypeName` C# 14 extension property + DataTable/IDataReader sources), sequence objects (CREATE / ALTER / DROP SEQUENCE / NEXT VALUE FOR / sys.sequences — supports EF Core HiLo identity strategy end-to-end), and DML triggers (CREATE / ALTER / CREATE OR ALTER / DROP TRIGGER, FOR-as-AFTER synonym, AFTER on heap tables + INSTEAD OF on heap tables / views, multi-action INSERT,UPDATE,DELETE, INSERTED/DELETED pseudo-tables, multiple AFTER triggers per parent / one INSTEAD OF per action per target (Msg 2111), DISABLE/ENABLE TRIGGER, TRIGGER_NESTLEVEL(), direct-recursion suppression matching RECURSIVE_TRIGGERS OFF, sys.triggers + sys.objects integration, trigger-error rolls back firing DML, MERGE per-action routing through INSTEAD OF, DROP TABLE / DROP VIEW cascade-drops attached triggers) ship (see `docs/claude/programmable.md`, `docs/claude/table-valued-parameters.md`, `docs/claude/sequences.md`, and `docs/claude/triggers.md`). JOIN-view single-base-table UPDATE/DELETE, OUTPUT through views, and multi-source alias-form UPDATE/DELETE through views are deferred (Msg 4405 or `NotSupportedException` at the DML site). `BEGIN ATOMIC` / `BEGIN DISTRIBUTED TRANSACTION` raise `NotSupportedException` at dispatch. Value-form `RETURN N` is legal inside a scalar-UDF body and a stored-procedure body; bare batch / dynamic-SQL scope raises Msg 178. TRY/CATCH + THROW + RAISERROR (printf-style `%s %d/%i %u %o %x %X %% %ld %I64d` with width / precision / left-align / zero-pad; severity routing 0-10 informational vs 11-18 catchable; `WITH SETERROR`/`NOWAIT` ship, `WITH LOG` uniformly raises Msg 2778; numeric `msg_id` raises Msg 2732 for 50000 / `< 13000` and Msg 18054 otherwise — `sys.messages` registry / `sp_addmessage` not modeled) + live `@@ERROR` + `ERROR_*()` functions ship (see `docs/claude/control-flow.md`).
179179
- **`PRINT` message capture** — the statement parses + evaluates the operand (so operand-side errors like Msg 245 surface), but the message is discarded. `DbConnection` has no `InfoMessage` event (that's a `SqlConnection` extension), so adding a public observability surface would mean a new event on `SimulatedDbConnection`. Defer until an application needs it.
180-
- **`ALTER TABLE` grammar beyond SET / ADD CONSTRAINT / DROP CONSTRAINT**`SET (SYSTEM_VERSIONING = OFF)` (see [`docs/claude/temporal-tables.md`](docs/claude/temporal-tables.md)), `[WITH CHECK | WITH NOCHECK] ADD [CONSTRAINT name] (PRIMARY KEY | UNIQUE | FOREIGN KEY | CHECK | DEFAULT) …` and `DROP CONSTRAINT [IF EXISTS] name [, …]` (see [`docs/claude/alter-table.md`](docs/claude/alter-table.md)) all ship. ADD / DROP COLUMN, ALTER COLUMN, DROP PERIOD FOR SYSTEM_TIME, REBUILD, SWITCH PARTITION, the SET-versioning-on direction, `WITH CHECK CHECK CONSTRAINT` (re-trust), and every other shape raise `NotSupportedException`. Multi-constraint ADD (`ADD CONSTRAINT pk1 PK (a), CONSTRAINT fk1 FK …`) also raises.
180+
- **`ALTER TABLE` grammar beyond SET / ADD / DROP / CHECK / NOCHECK CONSTRAINT**`SET (SYSTEM_VERSIONING = OFF)` (see [`docs/claude/temporal-tables.md`](docs/claude/temporal-tables.md)), `[WITH CHECK | WITH NOCHECK] ADD [CONSTRAINT name] (PRIMARY KEY | UNIQUE | FOREIGN KEY | CHECK | DEFAULT) …`, `DROP CONSTRAINT [IF EXISTS] name [, …]`, and `[WITH CHECK | WITH NOCHECK] (CHECK | NOCHECK) CONSTRAINT (ALL | name [, …])` (trust toggling for bulk imports — sets / clears `is_disabled` + `is_not_trusted`; see [`docs/claude/alter-table.md`](docs/claude/alter-table.md)) all ship. ADD / DROP COLUMN, ALTER COLUMN, DROP PERIOD FOR SYSTEM_TIME, REBUILD, SWITCH PARTITION, the SET-versioning-on direction, and every other shape raise `NotSupportedException`. Multi-constraint ADD (`ADD CONSTRAINT pk1 PK (a), CONSTRAINT fk1 FK …`) also raises.
181181
- `hierarchyid`, `geography`, `geometry`.
182182

183183
## Quirks (modeled, not byte-identical to SQL Server)
Lines changed: 252 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
using System.Data.Common;
2+
using static Microsoft.VisualStudio.TestTools.UnitTesting.Assert;
3+
4+
namespace SqlServerSimulator;
5+
6+
/// <summary>
7+
/// Behavioral tests for <c>ALTER TABLE … (CHECK | NOCHECK) CONSTRAINT (ALL |
8+
/// name [,…])</c> trust-toggle shapes. <c>NOCHECK</c> disables enforcement
9+
/// (sets IsDisabled + IsNotTrusted); bare <c>CHECK</c> re-enables without
10+
/// revalidating (leaves IsNotTrusted = true); <c>WITH CHECK CHECK
11+
/// CONSTRAINT</c> revalidates and clears IsNotTrusted on success.
12+
/// Probe-confirmed against SQL Server 2025 on 2026-05-13.
13+
/// </summary>
14+
[TestClass]
15+
public sealed class AlterTableTrustToggleTests
16+
{
17+
// --- NOCHECK CONSTRAINT (disable) ---
18+
19+
[TestMethod]
20+
public void NoCheckConstraint_FK_DisablesEnforcement()
21+
{
22+
var sim = new Simulation();
23+
// Bulk-import scenario: disable FK, insert orphan, re-enable.
24+
_ = sim.ExecuteNonQuery("""
25+
create table p (id int not null primary key);
26+
create table c (id int not null primary key, p_id int null constraint fk_cp references p(id));
27+
alter table c nocheck constraint fk_cp;
28+
insert c values (1, 999)
29+
""");
30+
AreEqual(1, sim.ExecuteScalar("select count(*) from c"));
31+
IsTrue((bool)sim.ExecuteScalar("select is_disabled from sys.foreign_keys where name = 'fk_cp'")!);
32+
IsTrue((bool)sim.ExecuteScalar("select is_not_trusted from sys.foreign_keys where name = 'fk_cp'")!);
33+
}
34+
35+
[TestMethod]
36+
public void NoCheckConstraint_FK_SkipsCascadeOnDelete()
37+
{
38+
var sim = new Simulation();
39+
// Probe-confirmed: disabled CASCADE FK leaves children orphaned when
40+
// parent is deleted (cascade action is suppressed alongside the
41+
// NO-ACTION reject).
42+
_ = sim.ExecuteNonQuery("""
43+
create table p (id int not null primary key);
44+
create table c (id int not null primary key, p_id int null constraint fk_cp references p(id) on delete cascade);
45+
insert p values (1);
46+
insert c values (10, 1), (20, 1);
47+
alter table c nocheck constraint fk_cp;
48+
delete p
49+
""");
50+
AreEqual(2, sim.ExecuteScalar("select count(*) from c"));
51+
}
52+
53+
[TestMethod]
54+
public void NoCheckConstraint_Check_DisablesPredicate()
55+
{
56+
var sim = new Simulation();
57+
_ = sim.ExecuteNonQuery("""
58+
create table t (qty int constraint ck_q check (qty > 0));
59+
alter table t nocheck constraint ck_q;
60+
insert t values (-5)
61+
""");
62+
AreEqual(-5, sim.ExecuteScalar("select qty from t"));
63+
}
64+
65+
// --- CHECK CONSTRAINT (re-enable without revalidate) ---
66+
67+
[TestMethod]
68+
public void CheckConstraint_BareReEnablesWithoutRevalidating()
69+
{
70+
var sim = new Simulation();
71+
// Probe-confirmed gotcha: bare CHECK CONSTRAINT (no WITH CHECK
72+
// prefix) re-enables enforcement but leaves IsNotTrusted = true.
73+
_ = sim.ExecuteNonQuery("""
74+
create table t (qty int constraint ck_q check (qty > 0));
75+
alter table t nocheck constraint ck_q;
76+
insert t values (-5);
77+
alter table t check constraint ck_q
78+
""");
79+
IsFalse((bool)sim.ExecuteScalar("select is_disabled from sys.check_constraints where name = 'ck_q'")!);
80+
IsTrue((bool)sim.ExecuteScalar("select is_not_trusted from sys.check_constraints where name = 'ck_q'")!);
81+
// New rows are now enforced.
82+
var ex = Throws<DbException>(() => sim.ExecuteNonQuery("insert t values (-10)"));
83+
AreEqual("547", ex.Data["HelpLink.EvtID"]);
84+
}
85+
86+
// --- WITH CHECK CHECK CONSTRAINT (re-validate + re-trust) ---
87+
88+
[TestMethod]
89+
public void WithCheckCheckConstraint_FK_RevalidatesAndClearsNotTrusted()
90+
{
91+
var sim = new Simulation();
92+
_ = sim.ExecuteNonQuery("""
93+
create table p (id int not null primary key);
94+
create table c (id int not null primary key, p_id int null constraint fk_cp references p(id));
95+
insert p values (1);
96+
insert c values (10, 1);
97+
alter table c nocheck constraint fk_cp;
98+
alter table c with check check constraint fk_cp
99+
""");
100+
IsFalse((bool)sim.ExecuteScalar("select is_disabled from sys.foreign_keys where name = 'fk_cp'")!);
101+
IsFalse((bool)sim.ExecuteScalar("select is_not_trusted from sys.foreign_keys where name = 'fk_cp'")!);
102+
}
103+
104+
[TestMethod]
105+
public void WithCheckCheckConstraint_FK_OrphanRaisesMsg547WithAlterPrefix()
106+
{
107+
var ex = new Simulation().AssertSqlError("""
108+
create table p (id int not null primary key);
109+
create table c (id int not null primary key, p_id int null constraint fk_cp references p(id));
110+
alter table c nocheck constraint fk_cp;
111+
insert c values (10, 999);
112+
alter table c with check check constraint fk_cp
113+
""", 547);
114+
Contains("ALTER TABLE statement conflicted with the FOREIGN KEY constraint", ex.Message);
115+
Contains("\"fk_cp\"", ex.Message);
116+
}
117+
118+
[TestMethod]
119+
public void WithCheckCheckConstraint_Check_BadRowRaisesMsg547()
120+
{
121+
var ex = new Simulation().AssertSqlError("""
122+
create table t (qty int constraint ck_q check (qty > 0));
123+
alter table t nocheck constraint ck_q;
124+
insert t values (-5);
125+
alter table t with check check constraint ck_q
126+
""", 547);
127+
Contains("ALTER TABLE statement conflicted with the CHECK constraint", ex.Message);
128+
Contains("\"ck_q\"", ex.Message);
129+
}
130+
131+
// --- ALL keyword ---
132+
133+
[TestMethod]
134+
public void NoCheckConstraintAll_DisablesEveryFkAndCheckOnTable()
135+
{
136+
var sim = new Simulation();
137+
_ = sim.ExecuteNonQuery("""
138+
create table p (id int not null primary key);
139+
create table c (
140+
id int not null primary key,
141+
p_id int null constraint fk_cp references p(id),
142+
qty int constraint ck_q check (qty > 0)
143+
);
144+
alter table c nocheck constraint all
145+
""");
146+
IsTrue((bool)sim.ExecuteScalar("select is_disabled from sys.foreign_keys where name = 'fk_cp'")!);
147+
IsTrue((bool)sim.ExecuteScalar("select is_disabled from sys.check_constraints where name = 'ck_q'")!);
148+
// Inserts with both violations now succeed.
149+
AreEqual(1, sim.ExecuteScalar("""
150+
insert c values (1, 999, -10);
151+
select count(*) from c
152+
"""));
153+
}
154+
155+
[TestMethod]
156+
public void CheckConstraintAll_BareReEnablesAllWithoutRevalidating()
157+
{
158+
var sim = new Simulation();
159+
_ = sim.ExecuteNonQuery("""
160+
create table p (id int not null primary key);
161+
create table c (
162+
id int not null primary key,
163+
p_id int null constraint fk_cp references p(id),
164+
qty int constraint ck_q check (qty > 0)
165+
);
166+
alter table c nocheck constraint all;
167+
alter table c check constraint all
168+
""");
169+
IsFalse((bool)sim.ExecuteScalar("select is_disabled from sys.foreign_keys where name = 'fk_cp'")!);
170+
IsTrue((bool)sim.ExecuteScalar("select is_not_trusted from sys.foreign_keys where name = 'fk_cp'")!);
171+
IsFalse((bool)sim.ExecuteScalar("select is_disabled from sys.check_constraints where name = 'ck_q'")!);
172+
IsTrue((bool)sim.ExecuteScalar("select is_not_trusted from sys.check_constraints where name = 'ck_q'")!);
173+
}
174+
175+
[TestMethod]
176+
public void WithCheckCheckConstraintAll_ClearsNotTrusted()
177+
{
178+
var sim = new Simulation();
179+
_ = sim.ExecuteNonQuery("""
180+
create table p (id int not null primary key);
181+
create table c (
182+
id int not null primary key,
183+
p_id int null constraint fk_cp references p(id),
184+
qty int constraint ck_q check (qty > 0)
185+
);
186+
insert p values (1);
187+
alter table c nocheck constraint all;
188+
alter table c with check check constraint all
189+
""");
190+
IsFalse((bool)sim.ExecuteScalar("select is_not_trusted from sys.foreign_keys where name = 'fk_cp'")!);
191+
IsFalse((bool)sim.ExecuteScalar("select is_not_trusted from sys.check_constraints where name = 'ck_q'")!);
192+
}
193+
194+
// --- Error paths ---
195+
196+
[TestMethod]
197+
public void NoCheckConstraint_NameNotFound_RaisesMsg4917()
198+
=> _ = new Simulation().AssertSqlError("""
199+
create table t (id int not null primary key);
200+
alter table t nocheck constraint missing
201+
""", 4917);
202+
203+
[TestMethod]
204+
public void WithCheckCheckConstraint_NameNotFound_RaisesMsg4917()
205+
=> _ = new Simulation().AssertSqlError("""
206+
create table t (id int not null primary key);
207+
alter table t with check check constraint missing
208+
""", 4917);
209+
210+
[TestMethod]
211+
public void MultiName_OneMissing_AtomicNoMutation()
212+
{
213+
var sim = new Simulation();
214+
_ = sim.ExecuteNonQuery("""
215+
create table t (id int not null primary key, qty int);
216+
alter table t add constraint ck_q check (qty > 0);
217+
alter table t nocheck constraint ck_q
218+
""");
219+
IsTrue((bool)sim.ExecuteScalar("select is_disabled from sys.check_constraints where name = 'ck_q'")!);
220+
var ex = Throws<DbException>(() => sim.ExecuteNonQuery("alter table t check constraint ck_q, missing"));
221+
AreEqual("4917", ex.Data["HelpLink.EvtID"]);
222+
// ck_q was disabled before; the failed multi-toggle leaves it disabled.
223+
IsTrue((bool)sim.ExecuteScalar("select is_disabled from sys.check_constraints where name = 'ck_q'")!);
224+
}
225+
226+
// --- Bulk-import recipe ---
227+
228+
[TestMethod]
229+
public void BulkImport_DisableImportReEnable_FlowEndToEnd()
230+
{
231+
var sim = new Simulation();
232+
// The intended bulk-import use case: disable all constraints, push
233+
// data (possibly with rows that would have violated), re-enable.
234+
_ = sim.ExecuteNonQuery("""
235+
create table p (id int not null primary key);
236+
create table c (
237+
id int not null primary key,
238+
p_id int null constraint fk_cp references p(id),
239+
qty int constraint ck_q check (qty > 0)
240+
);
241+
insert p values (1), (2);
242+
alter table c nocheck constraint all;
243+
insert c values (10, 1, 5), (20, 2, -3), (30, 99, 10);
244+
alter table c check constraint all
245+
""");
246+
AreEqual(3, sim.ExecuteScalar("select count(*) from c"));
247+
// After re-enable without WITH CHECK, IsNotTrusted = true; new
248+
// inserts enforce again so attempting a fresh orphan now fails.
249+
var ex = Throws<DbException>(() => sim.ExecuteNonQuery("insert c values (40, 999, 1)"));
250+
AreEqual("547", ex.Data["HelpLink.EvtID"]);
251+
}
252+
}

SqlServerSimulator/BuiltInResources.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ private static IEnumerable<SqlValue[]> EnumerateSysForeignKeys(Parser.BatchConte
807807
falseBit,
808808
SqlValue.FromInt32(fk.ReferencedTable.ObjectId),
809809
keyIndexId,
810-
falseBit,
810+
fk.IsDisabled ? trueBit : falseBit,
811811
falseBit,
812812
fk.IsNotTrusted ? trueBit : falseBit,
813813
SqlValue.FromByte((byte)fk.DeleteAction),
@@ -907,7 +907,7 @@ private static IEnumerable<SqlValue[]> EnumerateSysCheckConstraints(Parser.Batch
907907
falseBit,
908908
falseBit,
909909
falseBit,
910-
falseBit,
910+
ck.IsDisabled ? trueBit : falseBit,
911911
falseBit,
912912
ck.IsNotTrusted ? trueBit : falseBit,
913913
SqlValue.FromInt32(parentColumnId),

0 commit comments

Comments
 (0)