예제 #1
0
        protected SqlSelectColumn(SqlParserState state, out AmpElement error)
        {
            Kind = SqlKind.SelectColumnSyntax;

            if (SqlParser.TryParse <SqlExpression>(state, out var sqlExpression))
            {
                Expression = sqlExpression;
            }
            else
            {
                error = state.Error;
                return;
            }

            if (state.IsKind(SqlKind.AsToken))
            {
                AsToken = state.CurrentToken;
                state.Read();
            }

            if (state.IsKind(SqlKind.IdentifierToken) || state.IsKind(SqlKind.QuotedIdentifierToken))
            {
                NameToken = state.CurrentToken;
                state.Read();
            }
            else if (AsToken != null)
            {
                error = SqlParseError.Construct(state);
                return;
            }

            error = null;
        }
예제 #2
0
        protected SqlLimitClause(SqlParserState state, out AmpElement error)
        {
            if (state.IsKind(SqlKind.FetchToken))
            {
                items.Add(state.CurrentToken);
                state.Read();

                if (state.IsKind(SqlKind.FirstToken))
                {
                    items.Add(state.CurrentToken);
                    state.Read();

                    if (state.IsKind(SqlKind.NumericValueToken))
                    {
                        items.Add(state.CurrentToken);
                        state.Read();

                        if (state.IsKind(SqlKind.RowsToken))
                        {
                            items.Add(state.CurrentToken);
                            state.Read();

                            if (state.IsKind(SqlKind.OnlyToken))
                            {
                                items.Add(state.CurrentToken);
                                state.Read();
                            }
                        }
                    }
                }
            }
            error = null;
        }
예제 #3
0
        protected SqlCommaSeparatedTokenList(SqlParserState state, out AmpElement error)
            : base(Enumerable.Empty <TElement>())
        {
            List <AmpElement <SqlKind> > items = new List <AmpElement <SqlKind> >();

            while (true)
            {
                if (SqlParser.TryParse <TElement>(state, out var v))
                {
                    items.Add(v);
                }
                else
                {
                    error = state.Error;
                    return;
                }

                if (state.IsKind(SqlKind.CommaToken))
                {
                    items.Add(state.CurrentToken);
                    state.Read();
                    continue;
                }
                else
                {
                    break;
                }
            }
            SetItems(items);
            error = null;
        }
예제 #4
0
        protected SqlFromClause(SqlParserState state, out AmpElement error)
        {
            Kind = SqlKind.FromClause;
            if (state.IsKind(SqlKind.FromToken))
            {
                FromToken = state.CurrentToken;
                state.Read();
            }
            else
            {
                error = SqlParseError.Construct(state);
                return;
            }

            if (SqlParser.TryParse <SqlCommaSeparatedTokenList <SqlSelectSource> >(state, out var sources))
            {
                Sources = sources;
            }
            else
            {
                error = state.Error;
                return;
            }

            error = null;
        }
예제 #5
0
        protected SqlWhereClause(SqlParserState state, out AmpElement error)
        {
            Kind = SqlKind.WhereClause;
            if (state.IsKind(SqlKind.WhereToken))
            {
                WhereToken = state.CurrentToken;
                state.Read();
            }
            else
            {
                error = SqlParseError.Construct(state);
                return;
            }

            if (SqlParser.TryParse <SqlExpression>(state, out var expr))
            {
                Expression = expr;
            }
            else
            {
                error = state.Error;
                return;
            }

            error = null;
        }
예제 #6
0
        protected SqlJoinClause(SqlParserState state, out AmpElement error)
        {
            Kind = SqlKind.JoinClause;

            if (state.IsKind(SqlKind.LeftToken) || state.IsKind(SqlKind.RightToken))
            {
                SideToken = state.CurrentToken;
                state.Read();
            }

            if (state.IsKind(SqlKind.OuterToken) || state.IsKind(SqlKind.InnerToken))
            {
                OuterToken = state.CurrentToken;
                state.Read();
            }

            if (!state.IsKind(SqlKind.JoinToken))
            {
                error = SqlParseError.Construct(state);
                return;
            }

            JoinToken = state.CurrentToken;
            state.Read();

            if (SqlParser.TryParse <SqlSelectSource>(state, out var source))
            {
                Source = source;
            }
            else
            {
                error = state.Error;
                return;
            }

            if (state.IsKind(SqlKind.OnToken))
            {
                OnToken = state.CurrentToken;
                state.Read();


                if (SqlParser.TryParse <SqlExpression>(state, out var onExpression))
                {
                    OnExpression = onExpression;
                }
                else
                {
                    error = state.Error;
                    return;
                }
            }

            error = null;
        }
예제 #7
0
        protected SqlExpression(SqlParserState state, out AmpElement error)
        {
            if (state.IsKind(SqlKind.NotToken, SqlKind.MinusOperatorToken, SqlKind.PlusOperatorToken, SqlKind.TildeOperatorToken))
            {
                items.Add(state.CurrentToken);
                state.Read();
            }

            if (state.IsKind(SqlKind.ExistsToken) && state.PeekKind(SqlKind.OpenParenToken))
            {
                items.Add(state.CurrentToken);
                state.Read();
                // Fall through in OpenParenToken
            }

            if (state.IsKind(SqlKind.OpenParenToken))
            {
                items.Add(state.CurrentToken);
                state.Read();

                if (state.IsKind(SqlKind.SelectToken) &&
                    SqlParser.TryParse <SqlSelect>(state, out var subSelect))
                {
                    items.Add(subSelect);
                }
                else if (SqlParser.TryParse <SqlExpression>(state, out var expr))
                {
                    items.Add(expr);
                }
                else
                {
                    error = state.Error ?? SqlParseError.Construct(state);
                    return;
                }

                if (state.IsKind(SqlKind.CloseParenToken))
                {
                    items.Add(state.CurrentToken);
                    state.Read();
                }
                else
                {
                    error = state.Error ?? SqlParseError.Construct(state);
                    return;
                }
            }
            else if (state.IsKind(SqlKind.IdentifierToken) || state.IsKind(SqlKind.QuotedIdentifierToken))
            {
                if (state.PeekItem(0)?.Kind == SqlKind.DotToken &&
                    (state.PeekItem(1)?.Kind == SqlKind.IdentifierToken || state.PeekItem(1)?.Kind == SqlKind.QuotedIdentifierToken))
                {
                    items.Add(new AmpElementList <SqlKind>(state.ReadMany(3)));
                }
                else
                {
                    items.Add(state.CurrentToken);
                    state.Read();
                }

                if (state.IsKind(SqlKind.OpenParenToken))
                {
                    items.Add(state.CurrentToken);
                    state.Read();

                    if (!SqlParser.TryParse <SqlCommaSeparatedTokenList <SqlExpression> >(state, out var arguments))
                    {
                        error = state.Error;
                        return;
                    }

                    items.Add(arguments);

                    if (state.IsKind(SqlKind.CloseParenToken))
                    {
                        items.Add(state.CurrentToken);
                        state.Read();
                    }
                    else
                    {
                        error = SqlParseError.Construct(state);
                        return;
                    }
                }
            }
            else if (state.IsKind(SqlKind.NumericValueToken, SqlKind.DoubleValueToken, SqlKind.StringToken, SqlKind.NullToken))
            {
                items.Add(state.CurrentToken);
                state.Read();
            }
            else if (state.IsKind(SqlKind.CaseToken))
            {
                if (!SqlParser.TryParse <SqlCaseClause>(state, out var @case))
                {
                    error = state.Error;
                    return;
                }
                items.Add(@case);
            }
            else
            {
                error = state.Error ?? SqlParseError.Construct(state);
                return;
            }

            switch (state.Current.Kind)
            {
            case SqlKind.IsNullToken:
            case SqlKind.NotNullToken:
                items.Add(state.CurrentToken);
                state.Read();
                break;

            case SqlKind.NotToken when state.PeekKind(SqlKind.NullToken):
                items.Add(state.CurrentToken);

                state.Read();
                items.Add(state.CurrentToken);
                state.Read();
                break;
            }

            switch (state.Current.Kind)
            {
            case SqlKind.EqualOperatorToken:
            case SqlKind.NotEqualToken:
            case SqlKind.LessThanOrEqualToken:
            case SqlKind.LessThanToken:
            case SqlKind.GreaterThanOrEqualToken:
            case SqlKind.GreaterThanToken:
            case SqlKind.AndToken:
            case SqlKind.OrToken:
            case SqlKind.LikeToken:
            case SqlKind.ConcatToken:
            case SqlKind.PlusOperatorToken:
            case SqlKind.MinusOperatorToken:
            case SqlKind.AsteriksOperatorToken:
            case SqlKind.DivOperatorToken:
            case SqlKind.ShiftLeftToken:
            case SqlKind.InToken:
            case SqlKind.ShiftRightToken:
            case SqlKind.BetweenToken:
            case SqlKind.IsToken:
                if (state.Current.Kind == SqlKind.IsToken && state.PeekKind(SqlKind.NotToken))
                {
                    items.Add(state.CurrentToken);
                    state.Read();
                }
                items.Add(state.CurrentToken);
                state.Read();

                if (SqlParser.TryParse <SqlExpression>(state, out var subExpression))
                {
                    items.Add(subExpression);
                }
                else
                {
                    error = state.Error;
                    return;
                }
                break;

            case SqlKind.NotToken when state.PeekKind(SqlKind.BetweenToken, SqlKind.InToken):
                // TODO: Many more
                items.Add(state.CurrentToken);

                state.Read();
                goto case SqlKind.BetweenToken;

            default:
                break;
            }

            error = null;
        }
예제 #8
0
        protected SqlCaseClause(SqlParserState state, out AmpElement error)
        {
            Kind = SqlKind.SqlCaseClause;
            if (!state.IsKind(SqlKind.CaseToken))
            {
                error = SqlParseError.Construct(state);
                return;
            }

            CaseToken = state.CurrentToken;
            state.Read();

            if (!state.IsKind(SqlKind.WhenToken, SqlKind.ElseToken, SqlKind.EndToken))
            {
                if (!SqlParser.TryParse <SqlExpression>(state, out var caseExpr))
                {
                    error = SqlParseError.Construct(state);
                    return;
                }
                CaseExpression = caseExpr;
            }

            List <SqlWhenClause> whens = new List <SqlWhenClause>();

            while (state.IsKind(SqlKind.WhenToken))
            {
                SqlToken whenToken = state.CurrentToken;
                state.Read();

                if (!SqlParser.TryParse <SqlExpression>(state, out var whenExpr))
                {
                    error = SqlParseError.Construct(state);
                    return;
                }

                if (!state.IsKind(SqlKind.ThenToken))
                {
                    error = SqlParseError.Construct(state);
                    return;
                }
                SqlToken thenToken = state.CurrentToken;
                state.Read();


                if (!SqlParser.TryParse <SqlExpression>(state, out var thenExpr))
                {
                    error = SqlParseError.Construct(state);
                    return;
                }

                whens.Add(new SqlWhenClause(whenToken, whenExpr, thenToken, thenExpr));
            }
            Whens = SqlSyntaxList <SqlWhenClause> .FromItems(whens);

            if (state.IsKind(SqlKind.ElseToken))
            {
                ElseToken = state.CurrentToken;
                state.Read();

                if (!SqlParser.TryParse <SqlExpression>(state, out var elseExpr))
                {
                    error = SqlParseError.Construct(state);
                    return;
                }
                ElseExpression = elseExpr;
            }

            if (state.IsKind(SqlKind.EndToken))
            {
                EndToken = state.CurrentToken;
                state.Read();
                error = null;
            }
            else
            {
                error = SqlParseError.Construct(state);
            }
        }
예제 #9
0
        protected SqlSelect(SqlParserState state, out AmpElement error)
        {
            Kind = SqlKind.SelectSyntax;

            if (state.IsKind(SqlKind.WithToken))
            {
                if (!SqlParser.TryParse <SqlWithClause>(state, out var wp))
                {
                    error = state.Error;
                    return;
                }
                WithPart = wp;
            }

            if (state.IsKind(SqlKind.SelectToken))
            {
                SelectToken = (SqlToken)state.Current;
                state.Read();
            }

            if (state.IsKind(SqlKind.DistinctToken))
            {
                DistinctAllModifier = state.CurrentToken;
                state.Read();
            }
            else if (state.IsKind(SqlKind.AllToken))
            {
                DistinctAllModifier = state.CurrentToken;
                state.Read();
            }

            if (SqlParser.TryParse <SqlCommaSeparatedTokenList <SqlSelectColumn> >(state, out var cols))
            {
                ResultColumns = cols;
            }
            else
            {
                error = state.Error;
                return;
            }

            if (state.IsKind(SqlKind.FromToken))
            {
                if (!SqlParser.TryParse <SqlFromClause>(state, out var from))
                {
                    error = state.Error;
                    return;
                }
                FromClause = from;
            }

            List <SqlJoinClause> joins = new List <SqlJoinClause>();

            while (state.IsKind(SqlKind.JoinToken, SqlKind.OuterJoinToken, SqlKind.LeftToken, SqlKind.RightToken, SqlKind.InnerToken, SqlKind.CrossToken))
            {
                if (!SqlParser.TryParse <SqlJoinClause>(state, out var joinClause))
                {
                    error = state.Error;
                    return;
                }
                joins.Add(joinClause);
            }

            if (joins.Count > 0)
            {
                JoinClauses = SqlSyntaxList <SqlJoinClause> .FromItems(joins);
            }

            if (state.IsKind(SqlKind.WhereToken))
            {
                if (!SqlParser.TryParse <SqlWhereClause>(state, out var where))
                {
                    error = state.Error;
                    return;
                }
                WhereClause = where;
            }

            // GROUP BY
            // COMPOUND
            // ORDER BY


            if (state.IsKind(SqlKind.FetchToken))
            {
                if (!SqlParser.TryParse <SqlLimitClause>(state, out var limit))
                {
                    error = state.Error;
                    return;
                }
                LimitClause = limit;
            }


            error = null;
        }