Skip to content

Fix #4493: NullReferenceException combining optimistic concurrency and partitioning#4496

Merged
jeremydmiller merged 1 commit into
8.0from
fix/4493-optimistic-partitioning-8.0
May 19, 2026
Merged

Fix #4493: NullReferenceException combining optimistic concurrency and partitioning#4496
jeremydmiller merged 1 commit into
8.0from
fix/4493-optimistic-partitioning-8.0

Conversation

@jeremydmiller
Copy link
Copy Markdown
Member

Summary

Closes #4493.

UpsertFunction's partition-column scan called arg.Column.Equals(colName, ...) on each UpsertArgument when building the partition WHERE-clause fragment. CurrentVersionArgument deliberately sets Column to null (it's a sentinel that doesn't map to a stored column), so when optimistic concurrency was enabled on a document that also participated in AllDocumentsAreMultiTenantedWithPartitioning(...), DocumentSchema construction blew up with NullReferenceException during ApplyAllConfiguredChangesToDatabaseAsync — exactly the symptom in the reporter's repro.

The fix

-                var arg = Arguments.FirstOrDefault(a =>
-                    a.Column.Equals(colName, StringComparison.OrdinalIgnoreCase));
+                var arg = Arguments.FirstOrDefault(a =>
+                    string.Equals(a.Column, colName, StringComparison.OrdinalIgnoreCase));

string.Equals(null, "foo", ...) is null-safe and returns false, so a CurrentVersionArgument is naturally skipped — the only path that was crashing.

Test plan

  • New regression test CoreTests/Partitioning/Bug_4493_optimistic_partitioning.cs reproduces the exact configuration from the reporter's repro (.UseOptimisticConcurrency(true) + AllDocumentsAreMultiTenantedWithPartitioning with two list partitions) and round-trips a document through one of the partitions.
  • Fails with NullReferenceException at UpsertFunction.cs:127 without the fix (verified locally).
  • Passes with the fix on net8.0 / net9.0 / net10.0.
  • Adjacent partitioning tests (CoreTests.Partitioning.*) all 27 still pass.

Master companion PR will follow.

🤖 Generated with Claude Code

…d partitioning

UpsertFunction's partition-column scan called
arg.Column.Equals(colName, ...) on each UpsertArgument when building
the partition WHERE-clause fragment. CurrentVersionArgument
deliberately sets Column to null (it's a sentinel that doesn't map
to a stored column), so when optimistic concurrency was enabled on
a document that also participated in AllDocumentsAreMultiTenantedWith-
Partitioning(...), DocumentSchema construction blew up with
NullReferenceException during ApplyAllConfiguredChangesToDatabase-
Async — exactly the symptom in the reporter's repro.

Switch from arg.Column.Equals(...) to the null-safe
string.Equals(arg.Column, colName, ...) overload. Behavior is
otherwise unchanged.

Regression test in src/CoreTests/Partitioning/
Bug_4493_optimistic_partitioning.cs covers the exact configuration
shape from the reporter's repro: UseOptimisticConcurrency(true) on
a document plus AllDocumentsAreMultiTenantedWithPartitioning with
two list partitions. Verified the test reproduces the NRE without
the fix and passes with it, on net8.0 / net9.0 / net10.0.

Closes #4493.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller merged commit b7b23c8 into 8.0 May 19, 2026
@jeremydmiller jeremydmiller deleted the fix/4493-optimistic-partitioning-8.0 branch May 19, 2026 15:35
jeremydmiller added a commit that referenced this pull request May 19, 2026
Companion to the 8.0-line fix in #4496. The bug — NullReferenceException
when combining .UseOptimisticConcurrency(true) with
AllDocumentsAreMultiTenantedWithPartitioning(...) — doesn't reproduce
on master because the offending code path
(Marten/Storage/UpsertFunction.cs) was retired in #4461's closed-shape
storage rewrite. The cherry-pick of the 8.0 patch therefore omits
the UpsertFunction.cs edit (file no longer exists) and lands only
the regression test.

Test exercises the exact configuration shape from the reporter's
repro: .UseOptimisticConcurrency(true) on a document plus
AllDocumentsAreMultiTenantedWithPartitioning with two list
partitions, then applies the schema and round-trips a document
through one of the partitions. Acts as a regression-prevention
guard against any future change that re-introduces a similar
null-traversal in the partition-aware DDL generation.

Passes on net9.0 / net10.0.

Closes #4493.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeremydmiller jeremydmiller mentioned this pull request May 19, 2026
38 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant