Ejemplo n.º 1
0
        public override ExpressionNode VisitNullIfExpression(NullIfExpression expression)
        {
            // First visit all expressions
            base.VisitNullIfExpression(expression);

            // Since a NULLIF expression can be expressed using a CASE expression we convert
            // them to simplify the evaluation and optimization engine.
            //
            // NULLIF(expression1, expression1) is equivalent to this CASE expression:
            //
            // CASE
            //   WHEN expression1 = expression2 THEN NULL
            //	 ELSE expression1
            // END

            CaseExpression caseExpression = new CaseExpression();

            caseExpression.WhenExpressions    = new ExpressionNode[1];
            caseExpression.ThenExpressions    = new ExpressionNode[1];
            caseExpression.WhenExpressions[0] = new BinaryExpression(BinaryOperator.Equal, expression.LeftExpression, expression.RightExpression);
            caseExpression.ThenExpressions[0] = LiteralExpression.FromNull();
            caseExpression.ElseExpression     = expression.LeftExpression;

            return(VisitExpression(caseExpression));
        }
Ejemplo n.º 2
0
        private ExpressionNode ParsePrimaryExpression()
        {
            switch (_token.Id)
            {
            case TokenId.NULL:
                NextToken();
                return(LiteralExpression.FromNull());

            case TokenId.TRUE:
            case TokenId.FALSE:
                return(ParseBooleanLiteral());

            case TokenId.Date:
                return(ParseDateLiteral());

            case TokenId.Number:
                return(ParseNumberLiteral());

            case TokenId.String:
                return(LiteralExpression.FromString(ParseString()));

            case TokenId.EXISTS:
            {
                ExistsSubselect result = new ExistsSubselect();
                NextToken();
                Match(TokenId.LeftParentheses);
                result.Query = ParseQuery();
                Match(TokenId.RightParentheses);

                return(result);
            }

            case TokenId.ParameterMarker:
            {
                _rangeRecorder.Begin();
                NextToken();
                Identifier  name            = ParseIdentifier();
                SourceRange nameSourceRange = _rangeRecorder.End();

                ParameterExpression result = new ParameterExpression();
                result.Name            = name;
                result.NameSourceRange = nameSourceRange;
                return(result);
            }

            case TokenId.CAST:
            {
                NextToken();
                CastExpression castExpression = new CastExpression();
                Match(TokenId.LeftParentheses);
                castExpression.Expression = ParseExpression();
                Match(TokenId.AS);
                castExpression.TypeReference = ParseTypeReference();
                Match(TokenId.RightParentheses);

                return(castExpression);
            }

            case TokenId.CASE:
            {
                NextToken();

                CaseExpression caseExpression = new CaseExpression();

                if (_token.Id != TokenId.WHEN && _token.Id != TokenId.ELSE && _token.Id != TokenId.END)
                {
                    caseExpression.InputExpression = ParseExpression();
                }

                List <ExpressionNode> whenExpressionList = new List <ExpressionNode>();
                List <ExpressionNode> expressionList     = new List <ExpressionNode>();

                if (_token.Id != TokenId.WHEN)
                {
                    Match(TokenId.WHEN);
                }
                else
                {
                    while (_token.Id == TokenId.WHEN)
                    {
                        NextToken();

                        whenExpressionList.Add(ParseExpression());
                        Match(TokenId.THEN);
                        expressionList.Add(ParseExpression());
                    }
                }

                caseExpression.WhenExpressions = whenExpressionList.ToArray();
                caseExpression.ThenExpressions = expressionList.ToArray();

                if (_token.Id == TokenId.ELSE)
                {
                    NextToken();
                    caseExpression.ElseExpression = ParseExpression();
                }

                Match(TokenId.END);

                return(caseExpression);
            }

            case TokenId.COALESCE:
            {
                NextToken();
                CoalesceExpression coalesceExpression = new CoalesceExpression();
                coalesceExpression.Expressions = ParseExpressionList();
                return(coalesceExpression);
            }

            case TokenId.NULLIF:
            {
                NextToken();
                NullIfExpression nullIfExpression = new NullIfExpression();
                Match(TokenId.LeftParentheses);
                nullIfExpression.LeftExpression = ParseExpression();
                Match(TokenId.Comma);
                nullIfExpression.RightExpression = ParseExpression();
                Match(TokenId.RightParentheses);
                return(nullIfExpression);
            }

            case TokenId.Identifier:
            {
                _rangeRecorder.Begin();
                Identifier  name            = ParseIdentifier();
                SourceRange nameSourceRange = _rangeRecorder.End();

                if (_token.Id != TokenId.LeftParentheses)
                {
                    NameExpression result = new NameExpression();
                    result.Name            = name;
                    result.NameSourceRange = nameSourceRange;
                    return(result);
                }
                else
                {
                    bool             hasAsteriskModifier;
                    ExpressionNode[] args;

                    if (_lookahead.Id != TokenId.Multiply)
                    {
                        hasAsteriskModifier = false;
                        args = ParseExpressionList();
                    }
                    else
                    {
                        NextToken();
                        NextToken();
                        Match(TokenId.RightParentheses);

                        hasAsteriskModifier = true;
                        args = new ExpressionNode[0];
                    }

                    FunctionInvocationExpression result = new FunctionInvocationExpression();
                    result.Name                = name;
                    result.NameSourceRange     = nameSourceRange;
                    result.Arguments           = args;
                    result.HasAsteriskModifier = hasAsteriskModifier;
                    return(result);
                }
            }

            case TokenId.LeftParentheses:
            {
                NextToken();

                ExpressionNode expr;

                if (_token.Id != TokenId.SELECT)
                {
                    expr = ParseExpression();
                }
                else
                {
                    SingleRowSubselect singleRowSubselect = new SingleRowSubselect();
                    singleRowSubselect.Query = ParseQuery();
                    expr = singleRowSubselect;
                }

                Match(TokenId.RightParentheses);
                return(expr);
            }

            default:
            {
                _errorReporter.SimpleExpressionExpected(_token.Range, _token.Text);
                return(LiteralExpression.FromNull());
            }
            }
        }