Start Debugging

Marten 9.55 Fixes the Turkish I in Document Table Names: Rename Before You Upgrade

Marten 9.55.0 lowers document aliases, DDL template keys and flat-table upsert function names with the invariant culture. Apps running under tr-TR or az-AZ that store documents in tables like mt_doc_ınvoice must rename them first, or their data appears to vanish.

Marten 9.55.0 shipped on October 28, 2026, and its release notes open with a “read before upgrading” section that only matters to some apps, but matters a lot to those. If your process runs under a Turkish (tr-TR) or Azerbaijani (az-AZ) culture and you have a document type with an uppercase I in its name, the table Marten looks for has changed.

Where the dotless ı came from

Marten derives a document’s alias, and therefore its table name, from the type name. Until 9.55 it did that with string.ToLower(), which uses the current culture. In Turkic cultures the lowercase form of I is the dotless ı (U+0131), not i:

using System.Globalization;

var tr = CultureInfo.GetCultureInfo("tr-TR");

Console.WriteLine("Invoice".ToLower(tr));        // ınvoice
Console.WriteLine("Invoice".ToLowerInvariant()); // invoice

So a document type Invoice lived in mt_doc_ınvoice on a Turkish server and in mt_doc_invoice everywhere else. PR #5778 switches DocumentMapping to ToLowerInvariant(). From 9.55.0 on, the same type maps to mt_doc_invoice regardless of culture, and Marten will happily create that table empty next to your old one.

Two more identifiers in the same release

PR #5783 fixed two more places that lowered with the current culture:

Renaming the tables

Do this before the 9.55 build touches the database. This DO block renames every Marten document table that contains a dotless ı:

DO $$
DECLARE r record;
BEGIN
  FOR r IN
    SELECT schemaname, tablename
    FROM pg_tables
    WHERE tablename LIKE 'mt\_doc\_%' AND tablename LIKE '%ı%'
  LOOP
    EXECUTE format('ALTER TABLE %I.%I RENAME TO %I',
      r.schemaname, r.tablename, replace(r.tablename, 'ı', 'i'));
  END LOOP;
END $$;

The release notes also ask you to rename the matching upsert functions. Alternatively, drop the old mt_upsert_, mt_insert_, mt_update_ and mt_overwrite_ functions whose names contain ı and let Marten regenerate them; SELECT proname FROM pg_proc WHERE proname LIKE '%ı%' lists them. Then run await store.Storage.ApplyAllConfiguredChangesToDatabaseAsync() against a copy first and check the generated diff. Any index or constraint names that still carry the old spelling will show up there.

If your apps set <InvariantGlobalization>true</InvariantGlobalization> or run with an English culture, the names they generate are unchanged and there is nothing to do.

One more release note for everyone else

StoredDocument.Version for projection documents using UseVersionFromMatchingStream is now <mt_version>:<epoch microseconds> instead of the bare mt_version (#5773), so code that parsed it as an integer will break. The release also fixes HiLo id generation staying broken after a database outage on a fresh store.

One caveat the PR calls out: JasperFx’s ToTableAlias, which feeds event type names in mt_events.type, is still culture-sensitive. Changing it would orphan existing event rows under tr-TR, so it is tracked separately. If you run Marten on a Turkish server, keep an eye on that follow-up.

dotnet add package Marten --version 9.55.0

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Back