Example #1
0
        private void VisitFilter(FunctionCall functionCall)
        {
            var(elementType, column, lambda) = HandleArrayFunctionWithPredicate(functionCall, "filter");

            //Create an expression that calls Where() on the array with the lambda.
            var whereCall = ArrayFunctionUtils.CallWhere(elementType, column, lambda);

            var nullCheck = Expression.Condition(Expression.Equal(column, Expression.Constant(null, column.Type)), Expression.Constant(null, whereCall.Type), whereCall);

            AddExpressionToStack(nullCheck);
        }
Example #2
0
        private void VisitAnyMatch(FunctionCall functionCall)
        {
            var(elementType, column, lambda) = HandleArrayFunctionWithPredicate(functionCall, "any_match");

            //Create an expression that calls Any() on the array with the lambda.
            var anyCall = ArrayFunctionUtils.CallAny(elementType, column, lambda);

            var result = _visitorMetadata.OperationsProvider.MakeAnyCall(column, anyCall);

            AddExpressionToStack(result);
        }
Example #3
0
        private void VisitFirst(FunctionCall functionCall)
        {
            if (functionCall.Parameters.Count != 1 && functionCall.Parameters.Count != 2)
            {
                throw new SqlErrorException("'first' must contain either one or two parameters");
            }

            if (!(functionCall.Parameters[0] is ScalarExpression scalarExpression))
            {
                throw new SqlErrorException("'first' first parameter must be a scalar expression");
            }

            scalarExpression.Accept(this);
            var column = PopStack();

            //Check that is in an array (IEnumerable)
            if (!ArrayUtils.IsArray(column.Type))
            {
                throw new SqlErrorException("'first' first parameter must be an array/list.");
            }

            //Get the type that the array contains
            var elementType = ArrayUtils.GetArrayElementType(column.Type);

            Expression lambda = null;

            if (functionCall.Parameters.Count == 2)
            {
                if (!(functionCall.Parameters[1] is SqlParser.Expressions.LambdaExpression lambdaExpression))
                {
                    throw new SqlErrorException("'first' second parameter must be a lambda expression");
                }

                if (lambdaExpression.Parameters.Count != 1)
                {
                    throw new SqlErrorException("'first' lambda expression can only have one input parameter");
                }

                //Add the type to the lambda settings in the base visitor
                if (_lambdaParameters == null)
                {
                    _lambdaParameters = new Stack <Dictionary <string, ParameterExpression> >();
                }

                _lambdaParameters.Push(new Dictionary <string, ParameterExpression>()
                {
                    { lambdaExpression.Parameters.First(), Expression.Parameter(elementType) }
                });

                //Visit the lambda expression
                lambdaExpression.Accept(this);
                lambda = PopStack();

                if (!(lambda is System.Linq.Expressions.LambdaExpression expr) || expr.ReturnType != typeof(bool))
                {
                    throw new SqlErrorException("Lambda expression in 'first' must return a boolean.");
                }
            }

            var whereCall = ArrayFunctionUtils.CallFirstOrDefault(elementType, column, lambda);

            var nullableType = NullableUtils.ToNullable(whereCall.Type);

            if (nullableType != whereCall.Type)
            {
                whereCall = Expression.Convert(whereCall, nullableType);
            }

            var nullCheck = Expression.Condition(Expression.Equal(column, Expression.Constant(null, column.Type)), Expression.Constant(null, nullableType), whereCall);

            AddExpressionToStack(nullCheck);
        }