internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc)
        {
            // process the arguments
            SqlExpression result = base.VisitFunctionCall(fc);

            if (result is SqlFunctionCall)
            {
                SqlFunctionCall resultFunctionCall = (SqlFunctionCall)result;

                if (resultFunctionCall.Name == "LEN")
                {
                    SqlExpression expr = resultFunctionCall.Arguments[0];

                    if (expr.SqlType.IsLargeType && !expr.SqlType.SupportsLength)
                    {
                        result = sql.DATALENGTH(expr);

                        if (expr.SqlType.IsUnicodeType)
                        {
                            result = sql.ConvertToInt(sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression)));
                        }
                    }
                }

                // If the return type of the sql function is not compatible with
                // the expected CLR type of the function, inject a conversion. This
                // step must be performed AFTER SqlRetyper has run.
                Type clrType        = resultFunctionCall.SqlType.GetClosestRuntimeType();
                bool skipConversion = SqlMethodTransformer.SkipConversionForDateAdd(resultFunctionCall.Name,
                                                                                    resultFunctionCall.ClrType,
                                                                                    clrType);
                if ((resultFunctionCall.ClrType != clrType) && !skipConversion)
                {
                    result = sql.ConvertTo(resultFunctionCall.ClrType, resultFunctionCall);
                }
            }

            return(result);
        }