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/Translation/Resolvers/RedundandSubqueriesResolver.cs

63 lines
1.7 KiB

2 years ago
using System.Linq.Expressions;
using Connected.Expressions.Expressions;
using Connected.Expressions.Visitors;
namespace Connected.Expressions.Translation.Resolvers;
internal class RedundandSubqueriesResolver : DatabaseVisitor
{
private RedundandSubqueriesResolver()
{
}
private List<SelectExpression>? Redundant { get; set; }
internal static List<SelectExpression> Resolve(Expression expression)
{
var retriever = new RedundandSubqueriesResolver();
retriever.Visit(expression);
return retriever.Redundant;
}
private static bool IsRedudantSubquery(SelectExpression expression)
{
return (IsSimpleProjection(expression) || RedundantSubqueries.IsNameMapProjection(expression))
&& !expression.IsDistinct
&& !expression.IsReverse
&& expression.Take is null
&& expression.Skip is null
&& expression.Where is null
&& (expression.OrderBy is null || !expression.OrderBy.Any())
&& (expression.GroupBy is null || !expression.GroupBy.Any());
}
internal static bool IsSimpleProjection(SelectExpression select)
{
foreach (var decl in select.Columns)
{
if (decl.Expression is not ColumnExpression col || decl.Name != col.Name)
return false;
}
return true;
}
protected override Expression VisitSelect(SelectExpression expression)
{
if (IsRedudantSubquery(expression))
{
Redundant ??= new List<SelectExpression>();
Redundant.Add(expression);
}
return expression;
}
protected override Expression VisitSubquery(SubqueryExpression expression)
{
return expression;
}
}