Skip to content

Commit b397077

Browse files
Copilotrenemadsen
andcommitted
Fix MariaDB CAST AS json by converting to CAST AS CHAR instead of skipping CAST
Co-authored-by: renemadsen <76994+renemadsen@users.noreply.github.com>
1 parent c804851 commit b397077

1 file changed

Lines changed: 12 additions & 9 deletions

File tree

src/EFCore.MySql/Query/ExpressionVisitors/Internal/MySqlQuerySqlGenerator.cs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -513,11 +513,12 @@ protected override Expression VisitJsonScalar(JsonScalarExpression jsonScalarExp
513513
castStoreType = GetCastStoreType(jsonScalarExpression.TypeMapping);
514514
// }
515515

516-
// MariaDB does not support CAST(... AS json), so skip the CAST when targeting json type with JsonDataTypeEmulation enabled.
517-
// This prevents SQL syntax errors like "near 'json) IS NULL'" on MariaDB.
516+
// MariaDB does not support CAST(... AS json), so use CHAR when targeting json type with JsonDataTypeEmulation enabled.
517+
// This prevents SQL syntax errors like "near 'json) IS NULL'" on MariaDB while maintaining correct NULL comparison semantics.
518+
// MariaDB stores JSON as LONGTEXT, so casting to CHAR preserves the same behavior as the native JSON type.
518519
if (castStoreType == "json" && _options.ServerVersion.Supports.JsonDataTypeEmulation)
519520
{
520-
castStoreType = null;
521+
castStoreType = "char";
521522
}
522523

523524
if (castStoreType is not null)
@@ -725,13 +726,15 @@ private SqlUnaryExpression VisitConvert(SqlUnaryExpression sqlUnaryExpression)
725726
operandUnary.OperatorType == ExpressionType.Convert &&
726727
castMapping.Equals(GetCastStoreType(operandUnary.TypeMapping), StringComparison.OrdinalIgnoreCase);
727728

728-
// MariaDB does not support CAST(... AS json) syntax, so we skip the CAST when JsonDataTypeEmulation is enabled (MariaDB).
729-
// For MySQL 8+, which has native JSON type support, we generate the CAST when needed.
730-
// This prevents SQL syntax errors like "near 'json)) IS NULL'" on MariaDB.
731-
var skipCastForMariaDbJson = castMapping == "json" && _options.ServerVersion.Supports.JsonDataTypeEmulation;
729+
// MariaDB does not support CAST(... AS json) syntax. Instead, use CAST(... AS CHAR) for MariaDB when JsonDataTypeEmulation is enabled.
730+
// This maintains correct NULL comparison semantics while avoiding SQL syntax errors on MariaDB.
731+
// MariaDB stores JSON as LONGTEXT, so casting to CHAR preserves the expected behavior.
732+
if (castMapping == "json" && _options.ServerVersion.Supports.JsonDataTypeEmulation)
733+
{
734+
castMapping = "char";
735+
}
732736

733-
if (!skipCastForMariaDbJson &&
734-
(castMapping == "json" && !_options.ServerVersion.Supports.JsonDataTypeEmulation ||
737+
if ((castMapping == "json" && !_options.ServerVersion.Supports.JsonDataTypeEmulation ||
735738
!castMapping.Equals(sqlUnaryExpression.Operand.TypeMapping.StoreType, StringComparison.OrdinalIgnoreCase) &&
736739
!sameInnerCastStoreType))
737740
{

0 commit comments

Comments
 (0)