Skip to content

Commit

Permalink
More cleanup (#31233)
Browse files Browse the repository at this point in the history
  • Loading branch information
roji authored Jul 12, 2023
1 parent f3723a5 commit f67dbc8
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 284 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public static bool IsOrdinalKeyProperty(this IReadOnlyProperty property)
(property.DeclaringType as IEntityType)?.IsOwned() == true, $"Expected {property.DeclaringType.DisplayName()} to be owned.");
Check.DebugAssert(property.GetJsonPropertyName().Length == 0, $"Expected {property.Name} to be non-persisted.");

return property.FindContainingPrimaryKey() is IReadOnlyKey { Properties.Count: > 1 }
return property.FindContainingPrimaryKey() is { Properties.Count: > 1 }
&& !property.IsForeignKey()
&& property.ClrType == typeof(int)
&& (property.ValueGenerated & ValueGenerated.OnAdd) != 0;
Expand Down
39 changes: 10 additions & 29 deletions src/EFCore.Cosmos/Query/Internal/SqlExpressionFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,19 @@ public SqlExpressionFactory(ITypeMappingSource typeMappingSource, IModel model)
/// </summary>
[return: NotNullIfNotNull("sqlExpression")]
public virtual SqlExpression? ApplyTypeMapping(SqlExpression? sqlExpression, CoreTypeMapping? typeMapping)
{
if (sqlExpression is not { TypeMapping: null })
{
return sqlExpression;
}

#pragma warning disable IDE0066 // Convert switch statement to expression
switch (sqlExpression)
#pragma warning restore IDE0066 // Convert switch statement to expression
=> sqlExpression switch
{
case SqlConditionalExpression sqlConditionalExpression:
return ApplyTypeMappingOnSqlConditional(sqlConditionalExpression, typeMapping);

case SqlBinaryExpression sqlBinaryExpression:
return ApplyTypeMappingOnSqlBinary(sqlBinaryExpression, typeMapping);

case SqlUnaryExpression sqlUnaryExpression:
return ApplyTypeMappingOnSqlUnary(sqlUnaryExpression, typeMapping);
null or { TypeMapping: not null } => sqlExpression,

case SqlConstantExpression sqlConstantExpression:
return sqlConstantExpression.ApplyTypeMapping(typeMapping);
SqlConditionalExpression sqlConditionalExpression => ApplyTypeMappingOnSqlConditional(sqlConditionalExpression, typeMapping),
SqlBinaryExpression sqlBinaryExpression => ApplyTypeMappingOnSqlBinary(sqlBinaryExpression, typeMapping),
SqlUnaryExpression sqlUnaryExpression => ApplyTypeMappingOnSqlUnary(sqlUnaryExpression, typeMapping),
SqlConstantExpression sqlConstantExpression => sqlConstantExpression.ApplyTypeMapping(typeMapping),
SqlParameterExpression sqlParameterExpression => sqlParameterExpression.ApplyTypeMapping(typeMapping),
SqlFunctionExpression sqlFunctionExpression => sqlFunctionExpression.ApplyTypeMapping(typeMapping),

case SqlParameterExpression sqlParameterExpression:
return sqlParameterExpression.ApplyTypeMapping(typeMapping);

case SqlFunctionExpression sqlFunctionExpression:
return sqlFunctionExpression.ApplyTypeMapping(typeMapping);

default:
return sqlExpression;
}
}
_ => sqlExpression
};

private SqlExpression ApplyTypeMappingOnSqlConditional(
SqlConditionalExpression sqlConditionalExpression,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static class RelationalPropertyExtensions
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public static bool IsOrdinalKeyProperty(this IReadOnlyProperty property)
=> property.FindContainingPrimaryKey() is IReadOnlyKey { Properties.Count: > 1 }
=> property.FindContainingPrimaryKey() is { Properties.Count: > 1 }
&& !property.IsForeignKey()
&& property.ClrType == typeof(int)
&& property.GetJsonPropertyName() == null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,13 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent
=> TranslateAggregateWithSelector(source, selector, QueryableMethods.GetAverageWithoutSelector, throwWhenEmpty: true, resultType);

/// <inheritdoc />
protected override ShapedQueryExpression? TranslateCast(ShapedQueryExpression source, Type resultType)
protected override ShapedQueryExpression TranslateCast(ShapedQueryExpression source, Type resultType)
=> source.ShaperExpression.Type != resultType
? source.UpdateShaperExpression(Expression.Convert(source.ShaperExpression, resultType))
: source;

/// <inheritdoc />
protected override ShapedQueryExpression? TranslateConcat(ShapedQueryExpression source1, ShapedQueryExpression source2)
protected override ShapedQueryExpression TranslateConcat(ShapedQueryExpression source1, ShapedQueryExpression source2)
{
((SelectExpression)source1.QueryExpression).ApplyUnion((SelectExpression)source2.QueryExpression, distinct: false);

Expand Down Expand Up @@ -598,7 +598,7 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent
}
/// <inheritdoc />
protected override ShapedQueryExpression? TranslateDistinct(ShapedQueryExpression source)
protected override ShapedQueryExpression TranslateDistinct(ShapedQueryExpression source)
{
var selectExpression = (SelectExpression)source.QueryExpression;
if (selectExpression.Orderings.Count > 0
Expand Down Expand Up @@ -637,7 +637,7 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent
}
/// <inheritdoc />
protected override ShapedQueryExpression? TranslateExcept(ShapedQueryExpression source1, ShapedQueryExpression source2)
protected override ShapedQueryExpression TranslateExcept(ShapedQueryExpression source1, ShapedQueryExpression source2)
{
((SelectExpression)source1.QueryExpression).ApplyExcept((SelectExpression)source2.QueryExpression, distinct: true);
Expand Down Expand Up @@ -797,7 +797,7 @@ private static ShapedQueryExpression CreateShapedQueryExpression(IEntityType ent
=> null;
/// <inheritdoc />
protected override ShapedQueryExpression? TranslateIntersect(ShapedQueryExpression source1, ShapedQueryExpression source2)
protected override ShapedQueryExpression TranslateIntersect(ShapedQueryExpression source1, ShapedQueryExpression source2)
{
((SelectExpression)source1.QueryExpression).ApplyIntersect((SelectExpression)source2.QueryExpression, distinct: true);
Expand Down Expand Up @@ -1230,7 +1230,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
}

/// <inheritdoc />
protected override ShapedQueryExpression? TranslateUnion(ShapedQueryExpression source1, ShapedQueryExpression source2)
protected override ShapedQueryExpression TranslateUnion(ShapedQueryExpression source1, ShapedQueryExpression source2)
{
((SelectExpression)source1.QueryExpression).ApplyUnion((SelectExpression)source2.QueryExpression, distinct: true);

Expand Down Expand Up @@ -1927,15 +1927,15 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
source = methodCallExpression.Arguments[0];
var selectMethodCallExpression = default(MethodCallExpression);
if (source is MethodCallExpression { Method: MethodInfo { IsGenericMethod: true } } sourceMethodCall
if (source is MethodCallExpression { Method.IsGenericMethod: true } sourceMethodCall
&& sourceMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.Select)
{
selectMethodCallExpression = sourceMethodCall;
source = sourceMethodCall.Arguments[0];
}
var asQueryableMethodCallExpression = default(MethodCallExpression);
if (source is MethodCallExpression { Method: MethodInfo { IsGenericMethod: true } } maybeAsQueryableMethodCall
if (source is MethodCallExpression { Method.IsGenericMethod: true } maybeAsQueryableMethodCall
&& maybeAsQueryableMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.AsQueryable)
{
asQueryableMethodCallExpression = maybeAsQueryableMethodCall;
Expand All @@ -1946,7 +1946,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
if (source is JsonQueryExpression jsonQueryExpression)
{
var collectionIndexExpression = _sqlTranslator.Translate(methodCallExpression.Arguments[1]!);
var collectionIndexExpression = _sqlTranslator.Translate(methodCallExpression.Arguments[1]);
if (collectionIndexExpression == null)
{
// before we return from failed translation
Expand All @@ -1960,7 +1960,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp
methodCallExpression);
}
var newJsonQuery = jsonQueryExpression.BindCollectionElement(collectionIndexExpression!);
var newJsonQuery = jsonQueryExpression.BindCollectionElement(collectionIndexExpression);
var entityShaper = new RelationalEntityShaperExpression(
jsonQueryExpression.EntityType,
Expand Down Expand Up @@ -2021,56 +2021,56 @@ static Expression PrepareFailedTranslationResult(

static bool IsValidSelectorForJsonArrayElementAccess(Expression expression, JsonQueryExpression baselineJsonQuery)
{
// JSON_QUERY($[0]).Property
if (expression is MemberExpression
{
Expression: RelationalEntityShaperExpression { ValueBufferExpression: JsonQueryExpression memberJqe }
}
&& JsonQueryExpressionIsRootedIn(memberJqe, baselineJsonQuery))
switch (expression)
{
return true;
}

// MCNE(JSON_QUERY($[0].Collection))
// MCNE(JSON_QUERY($[0].Collection).AsQueryable())
// MCNE(JSON_QUERY($[0].Collection).Select(xx => xx.Includes())
// MCNE(JSON_QUERY($[0].Collection).AsQueryable().Select(xx => xx.Includes())
if (expression is MaterializeCollectionNavigationExpression mcne)
{
var subquery = mcne.Subquery;
if (subquery is MethodCallExpression { Method: MethodInfo { IsGenericMethod: true } } selectMethodCall
&& selectMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.Select
&& selectMethodCall.Arguments[1].UnwrapLambdaFromQuote() is LambdaExpression selectorLambda
&& StripIncludes(selectorLambda.Body) == selectorLambda.Parameters[0])
// JSON_QUERY($[0]).Property
case MemberExpression
{
Expression: RelationalEntityShaperExpression { ValueBufferExpression: JsonQueryExpression memberJqe }
}
when JsonQueryExpressionIsRootedIn(memberJqe, baselineJsonQuery):
{
subquery = selectMethodCall.Arguments[0];
return true;
}

if (subquery is MethodCallExpression { Method: MethodInfo { IsGenericMethod: true } } asQueryableMethodCall
&& asQueryableMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.AsQueryable)
// MCNE(JSON_QUERY($[0].Collection))
// MCNE(JSON_QUERY($[0].Collection).AsQueryable())
// MCNE(JSON_QUERY($[0].Collection).Select(xx => xx.Includes())
// MCNE(JSON_QUERY($[0].Collection).AsQueryable().Select(xx => xx.Includes())
case MaterializeCollectionNavigationExpression { Subquery: var subquery }:
{
subquery = asQueryableMethodCall.Arguments[0];
}
if (subquery is MethodCallExpression { Method.IsGenericMethod: true } selectMethodCall
&& selectMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.Select
&& selectMethodCall.Arguments[1].UnwrapLambdaFromQuote() is LambdaExpression selectorLambda
&& StripIncludes(selectorLambda.Body) == selectorLambda.Parameters[0])
{
subquery = selectMethodCall.Arguments[0];
}

if (subquery is JsonQueryExpression subqueryJqe
&& JsonQueryExpressionIsRootedIn(subqueryJqe, baselineJsonQuery))
{
return true;
if (subquery is MethodCallExpression { Method.IsGenericMethod: true } asQueryableMethodCall
&& asQueryableMethodCall.Method.GetGenericMethodDefinition() == QueryableMethods.AsQueryable)
{
subquery = asQueryableMethodCall.Arguments[0];
}

if (subquery is JsonQueryExpression subqueryJqe
&& JsonQueryExpressionIsRootedIn(subqueryJqe, baselineJsonQuery))
{
return true;
}

goto default;
}
}

// JSON_QUERY($[0]).Includes()
// JSON_QUERY($[0].Reference).Includes()
// JSON_QUERY($[0])
// JSON_QUERY($[0].Reference)
expression = StripIncludes(expression);
if (expression is RelationalEntityShaperExpression { ValueBufferExpression: JsonQueryExpression reseJqe }
&& JsonQueryExpressionIsRootedIn(reseJqe, baselineJsonQuery))
{
return true;
default:
// JSON_QUERY($[0]).Includes()
// JSON_QUERY($[0].Reference).Includes()
// JSON_QUERY($[0])
// JSON_QUERY($[0].Reference)
expression = StripIncludes(expression);
return expression is RelationalEntityShaperExpression { ValueBufferExpression: JsonQueryExpression reseJqe }
&& JsonQueryExpressionIsRootedIn(reseJqe, baselineJsonQuery);
}

return false;
}

static bool JsonQueryExpressionIsRootedIn(JsonQueryExpression expressionToTest, JsonQueryExpression root)
Expand Down Expand Up @@ -2324,20 +2324,6 @@ private static Expression AccessField(
string fieldName)
=> Expression.Field(targetExpression, transparentIdentifierType.GetTypeInfo().GetDeclaredField(fieldName)!);

private static void HandleGroupByForAggregate(SelectExpression selectExpression, bool eraseProjection = false)
{
if (selectExpression.GroupBy.Count > 0)
{
if (eraseProjection)
{
// Erasing client projections erase projectionMapping projections too
selectExpression.ReplaceProjection(new List<Expression>());
}

selectExpression.PushdownIntoSubquery();
}
}

private static Expression MatchShaperNullabilityForSetOperation(Expression shaper1, Expression shaper2, bool makeNullable)
{
switch (shaper1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ private static TValue ThrowReadValueException<TValue>(
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static TValue ThrowExtractJsonPropertyException<TValue>(
Exception exception,
IProperty property)
private static TValue ThrowExtractJsonPropertyException<TValue>(Exception exception, IProperty property)
{
var entityType = property.DeclaringType.DisplayName();
var propertyName = property.Name;
Expand Down
Loading

0 comments on commit f67dbc8

Please sign in to comment.