Skip to content

Commit

Permalink
Fix #4605 - Do not cache commands with Contains on Enumerable parameter.
Browse files Browse the repository at this point in the history
  • Loading branch information
mikary committed Mar 9, 2016
1 parent dde1912 commit 8ea9646
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public SqlTranslatingExpressionVisitor(

public virtual Expression ClientEvalPredicate { get; private set; }

public virtual bool HasContainsParameter { get; private set; }

public override Expression Visit(Expression expression)
{
var translatedExpression = _compositeExpressionFragmentTranslator.Translate(expression);
Expand Down Expand Up @@ -541,6 +543,11 @@ protected override Expression VisitSubQuery(SubQueryExpression expression)
|| fromExpression.NodeType == ExpressionType.ListInit
|| fromExpression.NodeType == ExpressionType.NewArrayInit)
{
if (fromExpression.NodeType == ExpressionType.Parameter)
{
HasContainsParameter = true;
}

var memberItem = contains.Item as MemberExpression;

if (memberItem != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class SelectExpression : TableExpressionBase
private int _subqueryDepth = -1;

private bool _isDistinct;
private bool _hasContainsParameter;

public virtual Expression Predicate { get; [param: CanBeNull] set; }

Expand Down Expand Up @@ -72,6 +73,7 @@ var selectExpression
_limit = _limit,
_offset = _offset,
_isDistinct = _isDistinct,
_hasContainsParameter = _hasContainsParameter,
_subqueryDepth = _subqueryDepth,
IsProjectStar = IsProjectStar,
Predicate = Predicate
Expand Down Expand Up @@ -186,6 +188,16 @@ public virtual bool IsDistinct
}
}

public virtual bool HasContainsParameter
{
get
{
return _hasContainsParameter
|| _tables.OfType<SelectExpression>().Any(t => t.HasContainsParameter);
}
set { _hasContainsParameter = value; }
}

public virtual Expression Limit
{
get { return _limit; }
Expand Down Expand Up @@ -288,12 +300,14 @@ public virtual SelectExpression PushDownSubquery()
subquery._limit = _limit;
subquery._offset = _offset;
subquery._isDistinct = _isDistinct;
subquery._hasContainsParameter = _hasContainsParameter;
subquery._subqueryDepth = _subqueryDepth;
subquery.IsProjectStar = IsProjectStar || !subquery._projection.Any();

_limit = null;
_offset = null;
_isDistinct = false;
_hasContainsParameter = false;

Predicate = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,13 @@ public ShaperCommandContext(
public virtual IRelationalCommand GetRelationalCommand(
[NotNull] IReadOnlyDictionary<string, object> parameters)
{
return _commandCache.GetOrAdd(
new CommandCacheKey(parameters),
cck => QuerySqlGeneratorFactory().GenerateSql(parameters));
var generator = QuerySqlGeneratorFactory();

return generator.CanCacheCommand
? _commandCache.GetOrAdd(
new CommandCacheKey(parameters),
cck => generator.GenerateSql(parameters))
: generator.GenerateSql(parameters); ;
}

public virtual void NotifyReaderCreated([NotNull] DbDataReader dataReader)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,11 @@ var sqlTranslatingExpressionVisitor
= selectExpression.Predicate == null
? sqlPredicateExpression
: Expression.AndAlso(selectExpression.Predicate, sqlPredicateExpression);

if(sqlTranslatingExpressionVisitor.HasContainsParameter)
{
selectExpression.HasContainsParameter = true;
}
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ public DefaultQuerySqlGenerator(
SelectExpression = selectExpression;
}

public virtual bool CanCacheCommand => !SelectExpression.HasContainsParameter;

protected virtual SelectExpression SelectExpression { get; }

protected virtual ISqlGenerationHelper SqlGenerator => _sqlGenerationHelper;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public interface IQuerySqlGenerator
{
IRelationalCommand GenerateSql([NotNull] IReadOnlyDictionary<string, object> parameterValues);

bool CanCacheCommand { get; }

IRelationalValueBufferFactory CreateValueBufferFactory(
[NotNull] IRelationalValueBufferFactoryFactory relationalValueBufferFactoryFactory,
[NotNull] DbDataReader dataReader);
Expand Down

0 comments on commit 8ea9646

Please sign in to comment.