using Microsoft.SqlServer.TransactSql.ScriptDom; using SQLLinter.Common; namespace SQLLinter.Infrastructure.Rules; public class UpperLowerRule : BaseRuleVisitor, IRule { public override string Text => "Использование функций UPPER или LOWER при выполнении сравнений в операторах SELECT не требуется при запуске базы данных в режиме без учета регистра."; public override void Visit(SelectStatement node) { var visitor = new ChildQueryComparisonVisitor(); node.Accept(visitor); if (visitor.QueryExpressionUpperLowerFunctionFound) { AddViolation(node); } } public class ChildQueryComparisonVisitor : TSqlFragmentVisitor { public bool QueryExpressionUpperLowerFunctionFound { get; private set; } public override void Visit(QueryExpression node) { var visitor = new ChildBooleanComparisonVisitor(); node.Accept(visitor); if (visitor.UpperLowerFunctionCallInComparison) { QueryExpressionUpperLowerFunctionFound = true; } } } public class ChildBooleanComparisonVisitor : TSqlFragmentVisitor { public bool UpperLowerFunctionCallInComparison { get; private set; } public override void Visit(BooleanComparisonExpression node) { var visitor = new ChildFunctionCallVisitor(); node.Accept(visitor); if (visitor.UpperLowerFound) { UpperLowerFunctionCallInComparison = true; } } } public class ChildFunctionCallVisitor : TSqlFragmentVisitor { public bool UpperLowerFound { get; private set; } public override void Visit(FunctionCall node) { if (node.FunctionName.Value.Equals("UPPER", StringComparison.OrdinalIgnoreCase) || node.FunctionName.Value.Equals("LOWER", StringComparison.OrdinalIgnoreCase)) { UpperLowerFound = true; } } } }