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/JoinColumnResolver.cs

78 lines
1.7 KiB

2 years ago
using System.Linq.Expressions;
using Connected.Expressions.Expressions;
namespace Connected.Expressions.Translation.Resolvers;
internal sealed class JoinColumnResolver
{
private JoinColumnResolver(HashSet<Alias> aliases)
{
Aliases = aliases;
Columns = new HashSet<ColumnExpression>();
}
private HashSet<Alias> Aliases { get; }
private HashSet<ColumnExpression> Columns { get; }
public static HashSet<ColumnExpression> Resolve(HashSet<Alias> aliases, SelectExpression select)
{
var resolver = new JoinColumnResolver(aliases);
resolver.Resolve(select.Where);
return resolver.Columns;
}
private void Resolve(Expression? expression)
{
if (expression is BinaryExpression b)
{
switch (b.NodeType)
{
case ExpressionType.Equal:
case ExpressionType.NotEqual:
if (IsExternalColumn(b.Left) && GetColumn(b.Right) is not null)
{
if (GetColumn(b.Right) is ColumnExpression right)
Columns.Add(right);
}
else if (IsExternalColumn(b.Right) && GetColumn(b.Left) is not null)
{
if (GetColumn(b.Left) is ColumnExpression left)
Columns.Add(left);
}
break;
case ExpressionType.And:
case ExpressionType.AndAlso:
if (b.Type == typeof(bool) || b.Type == typeof(bool?))
{
Resolve(b.Left);
Resolve(b.Right);
}
break;
}
}
}
private static ColumnExpression? GetColumn(Expression exp)
{
while (exp.NodeType == ExpressionType.Convert)
exp = ((UnaryExpression)exp).Operand;
return exp as ColumnExpression;
}
private bool IsExternalColumn(Expression exp)
{
var col = GetColumn(exp);
if (col is not null && !Aliases.Contains(col.Alias))
return true;
return false;
}
}