public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (_methodInfoDatePartMapping.TryGetValue(method, out var datePart))
            {
                return(!datePart.Equals("year") &&
                       !datePart.Equals("month") &&
                       arguments[0] is SqlConstantExpression sqlConstant &&
                       ((double)sqlConstant.Value >= int.MaxValue ||
                        (double)sqlConstant.Value <= int.MinValue)
            ? null
            : _sqlExpressionFactory.Function(
                           "DATE_ADD",
                           new[]
                {
                    instance,
                    _sqlExpressionFactory.ComplexFunctionArgument(new SqlExpression[]
                    {
                        _sqlExpressionFactory.Fragment("INTERVAL"),
                        _sqlExpressionFactory.Convert(arguments[0], typeof(int)),
                        _sqlExpressionFactory.Fragment(datePart)
                    }, typeof(string))
                },
                           instance.Type,
                           instance.TypeMapping));
            }

            return(null);
        }
        public virtual SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments)
        {
            if (_indexOfMethodInfo.Equals(method))
            {
                return(new MySQLStringComparisonMethodTranslator(_sqlExpressionFactory)
                       .MakeIndexOfExpression(instance, arguments[0], _sqlExpressionFactory.Constant(StringComparison.CurrentCulture)));
            }

            if (_replaceMethodInfo.Equals(method))
            {
                var stringTypeMapping = ExpressionExtensions.InferTypeMapping(instance, arguments[0], arguments[1]);

                return(_sqlExpressionFactory.Function(
                           "REPLACE",
                           new[]
                {
                    _sqlExpressionFactory.ApplyTypeMapping(instance, stringTypeMapping),
                    _sqlExpressionFactory.ApplyTypeMapping(arguments[0], stringTypeMapping),
                    _sqlExpressionFactory.ApplyTypeMapping(arguments[1], stringTypeMapping)
                },
                           method.ReturnType,
                           stringTypeMapping));
            }

            if (_toLowerMethodInfo.Equals(method) ||
                _toUpperMethodInfo.Equals(method))
            {
                return(_sqlExpressionFactory.Function(
                           _toLowerMethodInfo.Equals(method) ? "LOWER" : "UPPER",
                           new[] { instance },
                           method.ReturnType,
                           instance.TypeMapping));
            }

            if (_substringMethodInfo.Equals(method))
            {
                return(_sqlExpressionFactory.Function(
                           "SUBSTRING",
                           new[]
                {
                    instance,
                    _sqlExpressionFactory.Add(
                        arguments[0],
                        _sqlExpressionFactory.Constant(1)),
                    arguments[1]
                },
                           method.ReturnType,
                           instance.TypeMapping));
            }

            if (_isNullOrWhiteSpaceMethodInfo.Equals(method))
            {
                return(_sqlExpressionFactory.OrElse(
                           _sqlExpressionFactory.IsNull(arguments[0]),
                           _sqlExpressionFactory.Equal(
                               ProcessTrimMethod(arguments[0], null, null),
                               _sqlExpressionFactory.Constant(string.Empty))));
            }

            if (_trimStartMethodInfoWithoutArgs?.Equals(method) == true ||
                _trimStartMethodInfoWithCharArg?.Equals(method) == true ||
                _trimStartMethodInfoWithCharArrayArg.Equals(method))
            {
                return(ProcessTrimMethod(instance, arguments.Count > 0 ? arguments[0] : null, "LEADING"));
            }

            if (_trimEndMethodInfoWithoutArgs?.Equals(method) == true ||
                _trimEndMethodInfoWithCharArg?.Equals(method) == true ||
                _trimEndMethodInfoWithCharArrayArg.Equals(method))
            {
                return(ProcessTrimMethod(instance, arguments.Count > 0 ? arguments[0] : null, "TRAILING"));
            }

            if (_trimMethodInfoWithoutArgs?.Equals(method) == true ||
                _trimMethodInfoWithCharArg?.Equals(method) == true ||
                _trimMethodInfoWithCharArrayArg.Equals(method))
            {
                return(ProcessTrimMethod(instance, arguments.Count > 0 ? arguments[0] : null, null));
            }

            if (_containsMethodInfo.Equals(method))
            {
                return(new MySQLStringComparisonMethodTranslator(_sqlExpressionFactory)
                       .MakeContainsExpression(instance, arguments[0], _sqlExpressionFactory.Constant(StringComparison.OrdinalIgnoreCase)));
            }

            if (_startsWithMethodInfo.Equals(method))
            {
                return(new MySQLStringComparisonMethodTranslator(_sqlExpressionFactory)
                       .MakeStartsWithExpression(instance, arguments[0], _sqlExpressionFactory.Constant(StringComparison.CurrentCulture)));
            }

            if (_endsWithMethodInfo.Equals(method))
            {
                return(new MySQLStringComparisonMethodTranslator(_sqlExpressionFactory)
                       .MakeEndsWithExpression(instance, arguments[0], _sqlExpressionFactory.Constant(StringComparison.CurrentCulture)));
            }

            if (_padLeftWithOneArg.Equals(method))
            {
                return(TranslatePadLeftRight(
                           true,
                           instance,
                           arguments[0],
                           _sqlExpressionFactory.Constant(" "),
                           method.ReturnType));
            }

            if (_padRightWithOneArg.Equals(method))
            {
                return(TranslatePadLeftRight(
                           false,
                           instance,
                           arguments[0],
                           _sqlExpressionFactory.Constant(" "),
                           method.ReturnType));
            }

            if (_padLeftWithTwoArgs.Equals(method))
            {
                return(TranslatePadLeftRight(
                           true,
                           instance,
                           arguments[0],
                           arguments[1],
                           method.ReturnType));
            }

            if (_padRightWithTwoArgs.Equals(method))
            {
                return(TranslatePadLeftRight(
                           false,
                           instance,
                           arguments[0],
                           arguments[1],
                           method.ReturnType));
            }

            return(null);
        }