コード例 #1
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    SqlScalarExpression left  = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression right = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);

                    return(SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Equal, left, right));
                }

                if (methodCallExpression.Arguments.Count == 2)
                {
                    SqlScalarExpression left            = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression right           = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    SqlScalarExpression caseSensitivity = SqlStringWithComparisonVisitor.GetCaseSensitivityExpression(methodCallExpression.Arguments[1]);

                    return(SqlFunctionCallScalarExpression.CreateBuiltin(
                               SqlFunctionCallScalarExpression.Names.StringEquals,
                               left,
                               right,
                               caseSensitivity));
                }

                return(null);
            }
コード例 #2
0
        public void ARRAY_CONCAT()
        {
            // ARRAY_CONCAT(["apples"], ["strawberries"], ["bananas"])
            AssertEvaluation(
                CosmosArray.Create(CosmosString.Create("apples"), CosmosString.Create("strawberries"), CosmosString.Create("bananas")),
                SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.ArrayConcat,
                    JTokenToSqlScalarExpression.Convert(new JArray("apples")),
                    JTokenToSqlScalarExpression.Convert(new JArray("strawberries")),
                    JTokenToSqlScalarExpression.Convert(new JArray("bananas"))));

            // ARRAY_CONCAT("apples", ["strawberries"], ["bananas"])
            AssertEvaluation(
                Undefined,
                SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.ArrayConcat,
                    JTokenToSqlScalarExpression.Convert("apples"),
                    JTokenToSqlScalarExpression.Convert(new JArray("strawberries")),
                    JTokenToSqlScalarExpression.Convert(new JArray("bananas"))));

            // ARRAY_CONCAT(undefined, ["strawberries"], ["bananas"])
            AssertEvaluation(
                Undefined,
                SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.ArrayConcat,
                    SqlLiteralScalarExpression.SqlUndefinedLiteralScalarExpression,
                    JTokenToSqlScalarExpression.Convert(new JArray("strawberries")),
                    JTokenToSqlScalarExpression.Convert(new JArray("bananas"))));
        }
コード例 #3
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                Expression searchList       = null;
                Expression searchExpression = null;

                // If non static Contains
                if (methodCallExpression.Arguments.Count == 1)
                {
                    searchList       = methodCallExpression.Object;
                    searchExpression = methodCallExpression.Arguments[0];
                }
                // if extension method (static) Contains
                else if (methodCallExpression.Arguments.Count == 2)
                {
                    searchList       = methodCallExpression.Arguments[0];
                    searchExpression = methodCallExpression.Arguments[1];
                }

                if (searchList == null || searchExpression == null)
                {
                    return(null);
                }

                if (searchList.NodeType == ExpressionType.Constant)
                {
                    return(this.VisitIN(searchExpression, (ConstantExpression)searchList, context));
                }

                SqlScalarExpression array      = ExpressionToSql.VisitScalarExpression(searchList, context);
                SqlScalarExpression expression = ExpressionToSql.VisitScalarExpression(searchExpression, context);

                return(SqlFunctionCallScalarExpression.CreateBuiltin("ARRAY_CONTAINS", array, expression));
            }
コード例 #4
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                bool validInNet     = false;
                bool validInNetCore = false;

                if (methodCallExpression.Arguments.Count == 1 &&
                    methodCallExpression.Arguments[0].NodeType == ExpressionType.Constant &&
                    methodCallExpression.Arguments[0].Type == typeof(char[]))
                {
                    char[] argumentsExpressions = (char[])((ConstantExpression)methodCallExpression.Arguments[0]).Value;
                    if (argumentsExpressions.Length == 0)
                    {
                        validInNet = true;
                    }
                }
                else if (methodCallExpression.Arguments.Count == 0)
                {
                    validInNetCore = true;
                }

                if (validInNet || validInNetCore)
                {
                    SqlScalarExpression str = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("RTRIM", str));
                }

                return(null);
            }
コード例 #5
0
        public void LEFT()
        {
            // LEFT("Hello", -3)
            AssertEvaluation(
                expected: CosmosString.Empty,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Left,
                    hello,
                    negativeThree));

            // LEFT("Hello", 0)
            AssertEvaluation(
                expected: CosmosString.Empty,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Left,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(0))));

            // LEFT("Hello", 2)
            AssertEvaluation(
                expected: CosmosString.Create("He"),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Left,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(2))));

            // LEFT("Hello", 6)
            AssertEvaluation(
                expected: CosmosString.Create("Hello"),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Left,
                    hello,
                    six));
        }
コード例 #6
0
                public override bool Visit(SqlFunctionCallScalarExpression scalarExpression)
                {
                    if (this.MatchesGroupByExpression(scalarExpression))
                    {
                        return(true);
                    }

                    if (!scalarExpression.IsUdf)
                    {
                        if (AggregateIdentifiers.Contains(scalarExpression.Name))
                        {
                            // If the function call is an aggregate
                            return(true);
                        }
                    }

                    foreach (SqlScalarExpression arguments in scalarExpression.Arguments)
                    {
                        if (!arguments.Accept(this))
                        {
                            return(false);
                        }
                    }

                    return(true);
                }
コード例 #7
0
                public override bool Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression)
                {
                    Aggregate aggregate;

                    return(!sqlFunctionCallScalarExpression.IsUdf &&
                           Enum.TryParse(value: sqlFunctionCallScalarExpression.Name.Value, ignoreCase: true, result: out aggregate));
                }
コード例 #8
0
 public void ABS()
 {
     AssertEvaluation(
         CosmosNumber64.Create(Math.Abs(5)),
         SqlFunctionCallScalarExpression.CreateBuiltin(
             SqlFunctionCallScalarExpression.Identifiers.Abs,
             five));
 }
コード例 #9
0
 public void UPPER()
 {
     // UPPER("\u00B5")
     // MICRO SIGN does not have an upper casing
     AssertEvaluation(
         expected: CosmosString.Create("\u00B5"),
         sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
             SqlFunctionCallScalarExpression.Identifiers.Upper,
             SqlLiteralScalarExpression.Create(SqlStringLiteral.Create("\u00B5"))));
 }
コード例 #10
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    SqlScalarExpression str = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("LENGTH", str));
                }

                return(null);
            }
コード例 #11
0
 public void SUBSTRING()
 {
     // Substring("Hello", -3, 5)
     AssertEvaluation(
         expected: CosmosString.Empty,
         sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
             SqlFunctionCallScalarExpression.Identifiers.Substring,
             hello,
             negativeThree,
             five));
 }
コード例 #12
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 2)
                {
                    SqlScalarExpression haystack = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    SqlScalarExpression needle   = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[1], context);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("CONTAINS", haystack, needle));
                }

                return(null);
            }
コード例 #13
0
 public void CONTAINS()
 {
     // CONTAINS("hello", "")
     // -> all strings contain empty string.
     AssertEvaluation(
         expected: CosmosBoolean.Create(true),
         sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
             SqlFunctionCallScalarExpression.Identifiers.Contains,
             SqlLiteralScalarExpression.Create(SqlStringLiteral.Create("Hello")),
             SqlLiteralScalarExpression.Create(SqlStringLiteral.Create(string.Empty))));
 }
コード例 #14
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 2)
                {
                    SqlScalarExpression array1 = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    SqlScalarExpression array2 = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[1], context);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("ARRAY_CONCAT", array1, array2));
                }

                return(null);
            }
コード例 #15
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 2)
                {
                    SqlScalarExpression haystack        = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression needle          = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    SqlScalarExpression caseInsensitive = SqlStringWithComparisonVisitor.GetCaseInsensitiveExpression(methodCallExpression.Arguments[1]);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("CONTAINS", haystack, needle, caseInsensitive));
                }

                return(null);
            }
コード例 #16
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    List <SqlScalarExpression> arguments = new List <SqlScalarExpression>();
                    SqlScalarExpression        array     = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);

                    return(SqlFunctionCallScalarExpression.CreateBuiltin("ARRAY_LENGTH", array));
                }

                return(null);
            }
コード例 #17
0
 public void REPLACE()
 {
     // REPLACE("Hello", "", "World")
     // replacing the empty string within a string is undefined behavior
     // SQL Server just returns the original string and that's the behavior the backend matches
     AssertEvaluation(
         expected: Undefined,
         sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
             SqlFunctionCallScalarExpression.Identifiers.Replace,
             hello,
             SqlLiteralScalarExpression.Create(SqlStringLiteral.Create(string.Empty)),
             world));
 }
コード例 #18
0
        public override SqlObject Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression)
        {
            SqlScalarExpression[] items = new SqlScalarExpression[sqlFunctionCallScalarExpression.Arguments.Length];
            for (int i = 0; i < sqlFunctionCallScalarExpression.Arguments.Length; i++)
            {
                items[i] = sqlFunctionCallScalarExpression.Arguments[i].Accept(this) as SqlScalarExpression;
            }

            return(SqlFunctionCallScalarExpression.Create(
                       sqlFunctionCallScalarExpression.Name,
                       sqlFunctionCallScalarExpression.IsUdf,
                       items));
        }
コード例 #19
0
        public void RIGHT()
        {
            // Right("Hello", -3)
            AssertEvaluation(
                expected: CosmosString.Empty,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Right,
                    hello,
                    negativeThree));

            // Right("Hello", 1.5)
            AssertEvaluation(
                expected: Undefined,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Right,
                    hello,
                    floatingPoint));

            // Right("Hello", 0)
            AssertEvaluation(
                expected: CosmosString.Empty,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Right,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(0))));

            // Right("Hello", 2)
            AssertEvaluation(
                expected: CosmosString.Create("lo"),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Right,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(2))));

            // Right("Hello", 6)
            AssertEvaluation(
                expected: CosmosString.Create("Hello"),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Right,
                    hello,
                    six));

            // Right("Hello", int.MaxValue + 1)
            AssertEvaluation(
                expected: CosmosString.Create("Hello"),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Right,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create((long)int.MaxValue + 1))));
        }
コード例 #20
0
        private SqlScalarExpression VisitBuiltinFunction(MethodCallExpression methodCallExpression, TranslationContext context)
        {
            List <SqlScalarExpression> arguments = new List <SqlScalarExpression>();

            if (methodCallExpression.Object != null)
            {
                arguments.Add(ExpressionToSql.VisitNonSubqueryScalarExpression(methodCallExpression.Object, context));
            }

            foreach (Expression argument in methodCallExpression.Arguments)
            {
                arguments.Add(ExpressionToSql.VisitNonSubqueryScalarExpression(argument, context));
            }

            return(SqlFunctionCallScalarExpression.CreateBuiltin(this.SqlName, arguments.ToArray()));
        }
コード例 #21
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    SqlScalarExpression memberExpression = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression indexExpression  = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    var arguments = new SqlScalarExpression[] {
                        memberExpression,
                        indexExpression,
                        ExpressionToSql.VisitScalarExpression(Expression.Constant(1), context)
                    };

                    return(SqlFunctionCallScalarExpression.CreateBuiltin("SUBSTRING", arguments));
                }

                return(null);
            }
コード例 #22
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1 &&
                    methodCallExpression.Arguments[0] is NewArrayExpression newArrayExpression)
                {
                    ReadOnlyCollection <Expression> argumentsExpressions = newArrayExpression.Expressions;
                    List <SqlScalarExpression>      arguments            = new List <SqlScalarExpression>();
                    foreach (Expression argument in argumentsExpressions)
                    {
                        arguments.Add(ExpressionToSql.VisitScalarExpression(argument, context));
                    }

                    return(SqlFunctionCallScalarExpression.CreateBuiltin("CONCAT", arguments));
                }

                return(null);
            }
コード例 #23
0
        public override int Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression)
        {
            int hashCode = SqlFunctionCallScalarExpressionHashCode;

            if (sqlFunctionCallScalarExpression.IsUdf)
            {
                hashCode = CombineHashes(hashCode, SqlFunctionCallScalarExpressionUdfHashCode);
            }

            hashCode = CombineHashes(hashCode, sqlFunctionCallScalarExpression.Name.Accept(this));
            for (int i = 0; i < sqlFunctionCallScalarExpression.Arguments.Length; i++)
            {
                hashCode = CombineHashes(hashCode, sqlFunctionCallScalarExpression.Arguments[i].Accept(this));
            }

            return(hashCode);
        }
コード例 #24
0
        public override SqlObject VisitFunctionCallScalarExpression([NotNull] sqlParser.FunctionCallScalarExpressionContext context)
        {
            Contract.Requires(context != null);
            // (K_UDF '.')? IDENTIFIER '(' scalar_expression_list? ')'

            bool          udf                    = context.K_UDF() != null;
            SqlIdentifier identifier             = SqlIdentifier.Create(context.IDENTIFIER().GetText());
            List <SqlScalarExpression> arguments = new List <SqlScalarExpression>();

            if (context.scalar_expression_list() != null)
            {
                foreach (sqlParser.Scalar_expressionContext scalarExpressionContext in context.scalar_expression_list().scalar_expression())
                {
                    arguments.Add((SqlScalarExpression)this.Visit(scalarExpressionContext));
                }
            }

            return(SqlFunctionCallScalarExpression.Create(identifier, udf, arguments.ToImmutableArray()));
        }
コード例 #25
0
        public void ROUND()
        {
            // ROUND(4.84090499760142E+15)
            // offline engine has double precision errors
            AssertEvaluation(
                expected: CosmosNumber64.Create(4.84090499760142E+15),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Round,
                    SqlLiteralScalarExpression.Create(
                        SqlNumberLiteral.Create(
                            JToken.Parse("4840904997601420").Value <double>()))));

            // ROUND(0.5, 1)
            // -> should round up
            AssertEvaluation(
                expected: CosmosNumber64.Create(1),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Round,
                    SqlLiteralScalarExpression.Create(
                        SqlNumberLiteral.Create(0.5))));
        }
コード例 #26
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                int argumentCount = methodCallExpression.Arguments.Count;

                if (argumentCount == 0 || argumentCount > 2)
                {
                    return(null);
                }

                List <SqlScalarExpression> arguments = new List <SqlScalarExpression>
                {
                    ExpressionToSql.VisitNonSubqueryScalarExpression(methodCallExpression.Object, context),
                    ExpressionToSql.VisitNonSubqueryScalarExpression(methodCallExpression.Arguments[0], context)
                };

                if (argumentCount > 1)
                {
                    arguments.Add(GetCaseInsensitiveExpression(methodCallExpression.Arguments[1]));
                }

                return(SqlFunctionCallScalarExpression.CreateBuiltin(this.SqlName, arguments.ToArray()));
            }
コード例 #27
0
        public void REPLICATE()
        {
            // REPLICATE("Hello", -1)
            // -> undefined
            AssertEvaluation(
                expected: Undefined,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Replicate,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(-1))));

            // REPLICATE("Hello", 1.5)
            // -> REPLICATE("Hello", 1) due to truncation
            AssertEvaluation(
                expected: CosmosString.Create("Hello"),
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Replicate,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(1.5))));

            // REPLICATE("Hello", 10000)
            // -> undefined due to 10kb string cap
            AssertEvaluation(
                expected: Undefined,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Replicate,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(10000))));

            // REPLICATE("Hello", EXP(400))
            // -> undefined due to 10kb string cap
            AssertEvaluation(
                expected: Undefined,
                sqlScalarExpression: SqlFunctionCallScalarExpression.CreateBuiltin(
                    SqlFunctionCallScalarExpression.Identifiers.Replicate,
                    hello,
                    SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(Math.Exp(400)))));
        }
コード例 #28
0
        public override void Visit(SqlFunctionCallScalarExpression sqlFunctionCallScalarExpression)
        {
            if (sqlFunctionCallScalarExpression.IsUdf)
            {
                this.writer.Write("udf.");
            }

            sqlFunctionCallScalarExpression.Name.Accept(this);
            int numberOfArguments = sqlFunctionCallScalarExpression.Arguments.Count();

            if (numberOfArguments == 0)
            {
                this.writer.Write("()");
            }
            else if (numberOfArguments == 1)
            {
                this.writer.Write("(");
                sqlFunctionCallScalarExpression.Arguments[0].Accept(this);
                this.writer.Write(")");
            }
            else
            {
                this.WriteStartContext("(");

                for (int i = 0; i < sqlFunctionCallScalarExpression.Arguments.Length; i++)
                {
                    if (i > 0)
                    {
                        this.WriteDelimiter(",");
                    }

                    sqlFunctionCallScalarExpression.Arguments[i].Accept(this);
                }

                this.WriteEndContext(")");
            }
        }
コード例 #29
0
        public override CosmosElement Visit(SqlFunctionCallScalarExpression scalarExpression, CosmosElement document)
        {
            List <CosmosElement> arguments = new List <CosmosElement>();

            foreach (SqlScalarExpression argument in scalarExpression.Arguments)
            {
                CosmosElement evaluatedArgument = argument.Accept(this, document);
                arguments.Add(evaluatedArgument);
            }

            if (scalarExpression.IsUdf)
            {
                throw new NotSupportedException("Udfs are not supported.");
            }

            if (scalarExpression.Name.Value.StartsWith("ST_", StringComparison.OrdinalIgnoreCase))
            {
                throw new NotSupportedException("Spatial functions are not supported.");
            }

            return(BuiltinFunctionEvaluator.EvaluateFunctionCall(
                       scalarExpression.Name.Value,
                       arguments));
        }
コード例 #30
0
        public override bool Visit(SqlFunctionCallScalarExpression first, SqlObject secondAsObject)
        {
            if (!(secondAsObject is SqlFunctionCallScalarExpression second))
            {
                return(false);
            }

            if (first.IsUdf != second.IsUdf)
            {
                return(false);
            }

            if (!Equals(first.Name, second.Name))
            {
                return(false);
            }

            if (!SequenceEquals(first.Arguments, second.Arguments))
            {
                return(false);
            }

            return(true);
        }