You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Framework/Connected.Expressions/Evaluation/ExpressionNominator.cs

70 lines
1.6 KiB

2 years ago

using System.Linq.Expressions;
using Connected.Expressions.Expressions;
using Connected.Expressions.Languages;
using Connected.Expressions.Translation.Projections;
using Connected.Expressions.Visitors;
namespace Connected.Expressions.Evaluation;
internal sealed class ExpressionNominator : DatabaseVisitor
{
private ExpressionNominator(QueryLanguage language, ProjectionAffinity affinity)
{
Language = language;
Affinity = affinity;
Candidates = new HashSet<Expression>();
}
private QueryLanguage Language { get; }
private ProjectionAffinity Affinity { get; }
private HashSet<Expression> Candidates { get; set; }
private bool IsBlocked { get; set; }
public static HashSet<Expression> Nominate(QueryLanguage language, ProjectionAffinity affinity, Expression expression)
{
var nominator = new ExpressionNominator(language, affinity);
nominator.Visit(expression);
return nominator.Candidates;
}
protected override Expression? Visit(Expression? expression)
{
if (expression is not null)
{
var saveIsBlocked = IsBlocked;
IsBlocked = false;
if (Language.MustBeColumn(expression))
Candidates.Add(expression);
else
{
base.Visit(expression);
if (!IsBlocked)
{
if (Language.MustBeColumn(expression) || (Affinity == ProjectionAffinity.Server && Language.CanBeColumn(expression)))
Candidates.Add(expression);
else
IsBlocked = true;
}
IsBlocked |= saveIsBlocked;
}
}
return expression;
}
protected override Expression VisitProjection(ProjectionExpression expression)
{
Visit(expression.Projector);
return expression;
}
}