Skip to content

Commit 4b80703

Browse files
Copilotrenemadsen
andcommitted
Fix JSON_EXTRACT usage and identifier type for JSON_TABLE implementation
Co-authored-by: renemadsen <76994+renemadsen@users.noreply.github.com>
1 parent e17a1e9 commit 4b80703

1 file changed

Lines changed: 11 additions & 12 deletions

File tree

src/EFCore.MySql/Query/Internal/MySqlQueryableMethodTranslatingExpressionVisitor.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -280,18 +280,17 @@ protected override ShapedQueryExpression TransformJsonQueryToTable(JsonQueryExpr
280280
throw new UnreachableException();
281281
}
282282

283-
// For MySQL JSON_TABLE, we need to extract the nested JSON document using JSON_EXTRACT
284-
// Build the full path by combining the JSON column path with the query expression path
285-
var fullPath = jsonQueryExpression.Path.ToList();
283+
// MySQL JSON_TABLE requires the nested JSON document as raw JSON (not extracted as a scalar value).
284+
// We need to use JSON_EXTRACT (not JSON_VALUE) to get the JSON fragment with proper structure.
285+
// Unlike Npgsql which can use JsonScalarExpression (translates to json extraction in PostgreSQL),
286+
// MySQL's JsonScalarExpression translates to JSON_VALUE which strips quotes and can't feed JSON_TABLE.
286287

287-
// Create a JSON_EXTRACT expression to get the nested JSON document
288-
// JSON_EXTRACT returns the JSON fragment as-is (with quotes for strings)
289288
SqlExpression jsonSource;
290-
if (fullPath.Count > 0)
289+
if (jsonQueryExpression.Path.Count > 0)
291290
{
292-
// Build JSON path string like $.path.to.array
291+
// Build the JSON path for extraction
293292
var pathBuilder = new System.Text.StringBuilder("$");
294-
foreach (var segment in fullPath)
293+
foreach (var segment in jsonQueryExpression.Path)
295294
{
296295
if (segment.PropertyName is not null)
297296
{
@@ -303,7 +302,7 @@ protected override ShapedQueryExpression TransformJsonQueryToTable(JsonQueryExpr
303302
}
304303
}
305304

306-
// Use JSON_EXTRACT to get the nested JSON document
305+
// Use JSON_EXTRACT to get the nested JSON document (not JSON_VALUE which extracts scalars)
307306
jsonSource = _sqlExpressionFactory.Function(
308307
"JSON_EXTRACT",
309308
[jsonQueryExpression.JsonColumn, _sqlExpressionFactory.Constant(pathBuilder.ToString())],
@@ -314,7 +313,7 @@ protected override ShapedQueryExpression TransformJsonQueryToTable(JsonQueryExpr
314313
}
315314
else
316315
{
317-
// No path, use the JSON column directly
316+
// No path - use the JSON column directly
318317
jsonSource = jsonQueryExpression.JsonColumn;
319318
}
320319

@@ -327,15 +326,15 @@ [new PathSegment(_sqlExpressionFactory.Constant("*", RelationalTypeMapping.NullM
327326
[.. columnInfos]);
328327

329328
// MySQL JSON_TABLE returns a 'key' column for array ordering (similar to PostgreSQL's ordinality)
330-
var keyColumnTypeMapping = _typeMappingSource.FindMapping(typeof(uint))!;
329+
var keyColumnTypeMapping = _typeMappingSource.FindMapping(typeof(int))!;
331330

332331
#pragma warning disable EF1001 // Internal EF Core API usage.
333332
// Use CreateSelect helper method (from base class) to create the SelectExpression
334333
var selectExpression = CreateSelect(
335334
jsonQueryExpression,
336335
jsonTableExpression,
337336
"key",
338-
typeof(uint),
337+
typeof(int),
339338
keyColumnTypeMapping);
340339
#pragma warning restore EF1001 // Internal EF Core API usage.
341340

0 commit comments

Comments
 (0)