Skip to content

Commit 3d78514

Browse files
Copilotrenemadsen
andcommitted
CRITICAL FIX: Generate SQL for JsonScalarExpression with empty path
ROOT CAUSE IDENTIFIED: VisitJsonScalar() was returning early when path.Count == 0, which prevented SQL generation for entire JSON column projections. THE FIX: When path is empty (selecting entire JSON column, not a nested property), we now call Visit(jsonScalarExpression.Json) to generate the column name SQL. This fixes the empty column projections (`, ,`) for complex JSON types. The issue was that for complex JSON stored in JSON columns, when selecting the whole column (not a nested property like `.Address.City`), the path is empty. The old code just returned without generating any SQL, resulting in empty SELECT fragments. This should resolve both: 1. Empty SQL projections causing "near ', ,'" syntax errors 2. Enable proper reading of JSON data as MemoryStream via MySqlStructuralJsonTypeMapping Co-authored-by: renemadsen <76994+renemadsen@users.noreply.github.com>
1 parent 69bfbe4 commit 3d78514

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ protected override Expression VisitJsonScalar(JsonScalarExpression jsonScalarExp
477477
var path = jsonScalarExpression.Path;
478478
if (path.Count == 0)
479479
{
480+
// For empty paths (selecting the entire JSON column), just visit the JSON expression
481+
// This handles complex JSON types where we're projecting the whole column
482+
Visit(jsonScalarExpression.Json);
480483
return jsonScalarExpression;
481484
}
482485

@@ -1049,13 +1052,40 @@ protected override Expression VisitSelect(SelectExpression selectExpression)
10491052
{
10501053
System.IO.File.AppendAllText(logPath, $"[DEBUG SQL] SqlConstantExpression: Value={constant.Value}, TypeMapping={constant.TypeMapping?.GetType().Name ?? "null"}\n");
10511054
}
1055+
else if (projection.Expression.GetType().Name == "JsonScalarExpression")
1056+
{
1057+
// Use reflection to get properties since JsonScalarExpression is internal
1058+
var jsonExprType = projection.Expression.GetType();
1059+
var jsonProp = jsonExprType.GetProperty("Json");
1060+
var pathProp = jsonExprType.GetProperty("Path");
1061+
var typeMappingProp = jsonExprType.GetProperty("TypeMapping");
1062+
1063+
var jsonVal = jsonProp?.GetValue(projection.Expression);
1064+
var pathVal = pathProp?.GetValue(projection.Expression);
1065+
var typeMappingVal = typeMappingProp?.GetValue(projection.Expression);
1066+
1067+
System.IO.File.AppendAllText(logPath, $"[DEBUG SQL] JsonScalarExpression: Json={jsonVal}, Path={pathVal}, TypeMapping={typeMappingVal?.GetType().Name ?? "null"}\n");
1068+
1069+
if (typeMappingVal != null)
1070+
{
1071+
var tmType = typeMappingVal.GetType();
1072+
var clrTypeProp = tmType.GetProperty("ClrType");
1073+
var storeTypeProp = tmType.GetProperty("StoreType");
1074+
var clrType = clrTypeProp?.GetValue(typeMappingVal) as Type;
1075+
var storeType = storeTypeProp?.GetValue(typeMappingVal) as string;
1076+
System.IO.File.AppendAllText(logPath, $"[DEBUG SQL] TypeMapping: ClrType={clrType?.Name ?? "null"}, StoreType='{storeType}'\n");
1077+
}
1078+
}
10521079
else
10531080
{
10541081
System.IO.File.AppendAllText(logPath, $"[DEBUG SQL] Other Expression: {projection.Expression}\n");
10551082
}
10561083
}
10571084
}
1058-
catch { }
1085+
catch (Exception ex)
1086+
{
1087+
System.IO.File.AppendAllText(logPath, $"[DEBUG SQL] Error in logging: {ex.Message}\n");
1088+
}
10591089

10601090
var result = base.VisitSelect(selectExpression);
10611091

0 commit comments

Comments
 (0)