Skip to content

Commit

Permalink
Check if parameter.Name is not null before comparing it with query pa…
Browse files Browse the repository at this point in the history
…rameter

Resolves #20485

Parameters which are used inside lambda should get replaced with appropriate shaper/selector.
All other parameters should be query parameters otherwise it is an error.
Resolves #18502

Non query parameters should not get translated. Query parameters which are translated will always have value in QueryContext.
  • Loading branch information
smitpatel committed Apr 3, 2020
1 parent d481d1d commit 379142e
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;

namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
Expand Down Expand Up @@ -121,10 +122,15 @@ public override Expression Visit(Expression expression)
return parameterExpression;
}

return Expression.Call(
_getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type),
QueryCompilationContext.QueryContextParameter,
Expression.Constant(parameterExpression.Name));
if (parameterExpression.Name?.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal) == true)
{
return Expression.Call(
_getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type),
QueryCompilationContext.QueryContextParameter,
Expression.Constant(parameterExpression.Name));
}

throw new InvalidOperationException(CoreStrings.TranslationFailed(parameterExpression.Print()));

case MaterializeCollectionNavigationExpression _:
return base.Visit(expression);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
{
Expand Down Expand Up @@ -391,7 +393,9 @@ protected override Expression VisitConstant(ConstantExpression constantExpressio
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
protected override Expression VisitParameter(ParameterExpression parameterExpression)
=> new SqlParameterExpression(parameterExpression, null);
=> parameterExpression.Name?.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal) == true
? new SqlParameterExpression(Check.NotNull(parameterExpression, nameof(parameterExpression)), null)
: null;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ protected override Expression VisitExtension(Expression extensionExpression)

protected override Expression VisitParameter(ParameterExpression parameterExpression)
{
if (parameterExpression.Name.StartsWith(CompiledQueryParameterPrefix, StringComparison.Ordinal))
if (parameterExpression.Name?.StartsWith(CompiledQueryParameterPrefix, StringComparison.Ordinal) == true)
{
return Expression.Call(
_getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,15 @@ public override Expression Visit(Expression expression)
return expression;

case ParameterExpression parameterExpression:
return Expression.Call(
_getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type),
QueryCompilationContext.QueryContextParameter,
Expression.Constant(parameterExpression.Name));
if (parameterExpression.Name?.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal) == true)
{
return Expression.Call(
_getParameterValueMethodInfo.MakeGenericMethod(parameterExpression.Type),
QueryCompilationContext.QueryContextParameter,
Expression.Constant(parameterExpression.Name));
}

throw new InvalidOperationException(CoreStrings.TranslationFailed(parameterExpression.Print()));

case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression:
return _selectExpression.AddCollectionProjection(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Microsoft.EntityFrameworkCore.Utilities;

namespace Microsoft.EntityFrameworkCore.Query
{
Expand Down Expand Up @@ -539,7 +540,9 @@ protected override Expression VisitConstant(ConstantExpression constantExpressio
=> new SqlConstantExpression(constantExpression, null);

protected override Expression VisitParameter(ParameterExpression parameterExpression)
=> new SqlParameterExpression(parameterExpression, null);
=> parameterExpression.Name?.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal) == true
? new SqlParameterExpression(Check.NotNull(parameterExpression, nameof(parameterExpression)), null)
: null;

protected override Expression VisitExtension(Expression extensionExpression)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ private Expression VisitContainsMethodCall(MethodCallExpression methodCallExpres
rewrittenSource = Expression.Constant(keyList, keyListType);
}
else if (newSource is ParameterExpression listParam
&& listParam.Name.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal))
&& listParam.Name?.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal) == true)
{
// The source list is a parameter. Add a runtime parameter that will contain a list of the extracted keys for each execution.
var lambda = Expression.Lambda(
Expand Down Expand Up @@ -938,7 +938,7 @@ private Expression CreatePropertyAccessExpression(Expression target, IProperty p
// If the target is a query parameter, we can't simply add a property access over it, but must instead cause a new
// parameter to be added at runtime, with the value of the property on the base parameter.
if (target is ParameterExpression baseParameterExpression
&& baseParameterExpression.Name.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal))
&& baseParameterExpression.Name?.StartsWith(CompiledQueryCache.CompiledQueryParameterPrefix, StringComparison.Ordinal) == true)
{
// Generate an expression to get the base parameter from the query context's parameter list, and extract the
// property from that
Expand Down

0 comments on commit 379142e

Please sign in to comment.