Skip to content

Fix HasColumnType("boolean") generating invalid boolean(1) DDL - #471

Open
selvasmallive wants to merge 1 commit into
microting:masterfrom
selvasmallive:fix/boolean-store-type-alias
Open

selvasmallive wants to merge 1 commit into
microting:masterfrom
selvasmallive:fix/boolean-store-type-alias

Conversation

@selvasmallive

Copy link
Copy Markdown

Problem

Configuring a bool property with the BOOLEAN or BOOL store type produces DDL the server rejects:

modelBuilder.Entity<TestEntity>().Property(e => e.Flag).HasColumnType("boolean");
`Flag` boolean(1) NOT NULL
You have an error in your SQL syntax; ... near '(1) NOT NULL'

Reported for Pomelo 8.0.3 in PomeloFoundation#2045. It reproduces unchanged on master here (10.0.12, EF Core 10.0.12, MySQL 8.4.10) for boolean, BOOLEAN, bool and BOOL (checked with GenerateCreateScript and EnsureCreated).

Root cause

MySqlTypeMappingSource has no store type entry for bool or boolean. The lookup by store type name misses, falls through to the CLR type lookup and returns the default bool mapping, which is tinyint with size: 1 and StoreTypePostfix.Size. EF Core then applies the configured store type name to that mapping and keeps the size postfix, giving boolean(1).

BOOL and BOOLEAN are synonyms for TINYINT(1) and do not accept a display width.

Change

Register bool and boolean as store types mapped to a MySqlBoolTypeMapping without a size postfix, next to the existing tinyint(1) / bit(1) registration. Four lines in MySqlTypeMappingSource.

The configured name is preserved (boolean stays boolean in the migration and in the DDL); the server stores the column as tinyint(1).

Tests

New test/EFCore.MySql.Tests/Migrations/MySqlBooleanStoreTypeAliasTest.cs, 7 test cases:

  • the type mapping source returns boolean / BOOLEAN / bool / BOOL unsuffixed;
  • the default (tinyint(1)) and explicit tinyint(1) mappings are unchanged;
  • the relational model keeps the configured store type for each column;
  • a table with boolean and bool columns is created on the server, seeded, read back and filtered.

All 7 fail on master (the fixture's EnsureCreated hits the syntax error) and pass with the change.

Results on MySQL 8.4.10, Windows, .NET SDK 10.0.101:

Suite Result
EFCore.MySql.Tests 91 passed, 0 failed
EFCore.MySql.FunctionalTests, full 29,563 passed, 0 failed, 467 skipped (identical totals to master)

I have no MariaDB instance locally, so MariaDB coverage relies on CI here.

Compatibility

  • Columns without an explicit type, and columns configured as tinyint(1), bit(1) or bit, map exactly as before.
  • Anyone who has HasColumnType("boolean") today could not have created that column through EF, since the generated DDL was invalid. For such a model the snapshot and the current model now both resolve to boolean, so I expect no spurious migration; I have not tested an upgrade of an existing migrations folder.
  • The aliases are registered inside the existing ClrBoolean != MySqlBooleanType.None block, so the None setting behaves as before.

Fixes the fork's equivalent of PomeloFoundation#2045.

🤖 Generated with Claude Code

HasColumnType("boolean") on a bool property generated `boolean(1)`,
which MySQL rejects. The type mapping source had no entry for the
aliases, so the lookup fell back to the default bool mapping
(tinyint with size 1) and the size postfix was applied to the
configured store type name.

Register `bool` and `boolean` as bool mappings without a size.

See PomeloFoundation#2045.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants