Skip to content

docs: note ISNULL rolling-deploy pattern for JSON/TVP NOT NULL columns#7991

Open
Hinton wants to merge 1 commit into
mainfrom
docs/dapper-isnull-rolling-deploy
Open

docs: note ISNULL rolling-deploy pattern for JSON/TVP NOT NULL columns#7991
Hinton wants to merge 1 commit into
mainfrom
docs/dapper-isnull-rolling-deploy

Conversation

@Hinton

@Hinton Hinton commented Jul 16, 2026

Copy link
Copy Markdown
Member

🎟️ Tracking

Came out of review feedback on #7957 (PM-40208).

📔 Objective

Add the missing backwards-compat rule to .claude/rules/database-dapper.md, in the "Add a column" section right after the existing DEFAULT-constraint guidance:

A NOT NULL column written through an OPENJSON or TVP path also needs ISNULL([Column], <default>) at every insert/update site. A scalar procedure parameter stays backwards-compatible via its own default (@Column BIT = 0), but a JSON/TVP field has no per-field default — during a rolling deployment an old server omits it, OPENJSON yields NULL, and the write violates the NOT NULL constraint.

The rule pairs directly with the adjacent default-constraint mechanic and cites the OrganizationUser_CreateMany/_UpdateMany/_CreateManyWithCollectionsAndGroups procedures as the canonical example. Docs/rules only — no code or schema changes.

Related contributing docs change: bitwarden/contributing-docs#833

A NOT NULL column populated via OPENJSON or a TVP needs ISNULL(col, <default>) at each write site: during a rolling deployment an old server omits the field, OPENJSON/the TVP yields NULL, and the write violates the NOT NULL constraint. Scalar parameters avoid this via their own defaults; JSON/TVP fields have no per-field default.
@Hinton Hinton requested a review from a team as a code owner July 16, 2026 08:42
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This is a docs-only change to .claude/rules/database-dapper.md, adding a backwards-compatibility rule for NOT NULL columns written through OPENJSON/TVP paths. The guidance sits correctly in the "Add a column" section alongside the existing DEFAULT-constraint mechanic, and its claims are grounded in real procedures — verified against OrganizationUser_CreateMany.sql, which uses OPENJSON ... WITH exactly as described. No security, correctness, or breaking-change concerns; no code or schema changes.

Code Review Details

No findings. The addition is technically accurate (an old server omitting a JSON field during a rolling deployment does yield NULL from OPENJSON, violating a NOT NULL constraint), concise, and actionable, with a canonical example and no duplication of existing guidance.

@Hinton Hinton added the t:docs Change Type - Documentation label Jul 16, 2026
@Hinton Hinton requested a review from rkac-bw July 16, 2026 08:44
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 62.12%. Comparing base (aabd1e0) to head (911c345).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7991      +/-   ##
==========================================
+ Coverage   62.08%   62.12%   +0.03%     
==========================================
  Files        2284     2284              
  Lines       99728    99666      -62     
  Branches     9016     9016              
==========================================
+ Hits        61914    61915       +1     
+ Misses      35639    35576      -63     
  Partials     2175     2175              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rkac-bw

rkac-bw commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Just to complicate things TVP can have default values but would require a tvp _V2, there has been resistance to using TVP's though , thus we have been using JSON

CREATE TYPE [dbo].[CollectionAccessSelectionType_V2] AS TABLE (
[Id] UNIQUEIDENTIFIER NOT NULL,
[ReadOnly] BIT NOT NULL,
[HidePasswords] BIT NOT NULL,
[Manage] BIT NOT NULL DEFAULT 0 -- new column, defaulted
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t:docs Change Type - Documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants