예제 #1
0
        public static bool KeywordPrecedesTable(SqlLiteral value)
        {
            if (value == null || value.Type != SqlType.Keyword)
            {
                return(false);
            }

            switch (value.Text.ToLowerInvariant())
            {
            case "from":
            case "update":
                return(true);
            }

            if (value.Text.EndsWith("join", StringComparison.OrdinalIgnoreCase) ||
                value.Text.EndsWith("apply", StringComparison.OrdinalIgnoreCase) ||
                value.Text.EndsWith("into", StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            return(false);
        }
예제 #2
0
        public IEnumerable <SqlLiteral> BasicEnumerator()
        {
            _i = 0;
            while (_i < _text.Length)
            {
                switch (_state)
                {
                case State.Start:
                    _current = new SqlLiteral();
                    if (StartsWith('/', '*'))
                    {
                        _current.StartOffset = _i;
                        _i++;
                        _state = State.CommentMulti;
                    }
                    else if (StartsWith('-', '-'))
                    {
                        _current.StartOffset = _i;
                        _i++;
                        _state = State.CommentLine;
                    }
                    else if (StartsWith('N', '\''))
                    {
                        _current.StartOffset = _i;
                        _i++;
                        _state = State.StringLiteral;
                    }
                    else if (StartsWith('0', 'x'))
                    {
                        _current.StartOffset = _i;
                        _i++;
                        _state = State.BinaryLiteral;
                    }
                    else if (_text[_i] == '[')
                    {
                        _current.StartOffset = _i;
                        _state = State.IdentifierBracket;
                    }
                    else if (_text[_i] == '"')
                    {
                        _current.StartOffset = _i;
                        _state = State.IdentifierQuote;
                    }
                    else if (_text[_i] == '\'')
                    {
                        _current.StartOffset = _i;
                        _state = State.StringLiteral;
                    }
                    else if (_text[_i] == '$')
                    {
                        _current.StartOffset = _i;
                        _state = State.NumericLiteral;
                    }
                    else if (_text[_i] == '@')
                    {
                        _current.StartOffset = _i;
                        _state = State.Identifier;
                    }
                    else if (char.IsDigit(_text[_i]))
                    {
                        _current.StartOffset = _i;
                        _state = State.NumericLiteral;
                    }
                    else if (char.IsLetter(_text[_i]) || _text[_i] == '_')
                    {
                        _current.StartOffset = _i;
                        _state = State.Identifier;
                    }
                    else if (char.IsWhiteSpace(_text[_i]))
                    {
                        _state = State.Whitespace;
                    }
                    else
                    {
                        yield return(new SqlLiteral()
                        {
                            StartOffset = _i,
                            Text = _text[_i].ToString(),
                            Type = SqlType.Operator
                        });
                    }
                    break;

                case State.BinaryLiteral:
                    if (!IsHexDigit(_text[_i]))
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i - _current.StartOffset);
                        _current.Type = SqlType.Binary;
                        yield return(_current);

                        _i--;
                        _state = State.Start;
                    }
                    break;

                case State.CommentLine:
                    if (_text[_i] == '\r' || _text[_i] == '\n')
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i - _current.StartOffset);
                        _current.Type = SqlType.Comment;
                        yield return(_current);

                        _i--;
                        _state = State.Start;
                    }
                    break;

                case State.CommentMulti:
                    if (StartsWith('*', '/'))
                    {
                        _i++;
                        _current.Text = _text.Substring(_current.StartOffset, _i + 1 - _current.StartOffset);
                        _current.Type = SqlType.Comment;
                        yield return(_current);

                        _state = State.Start;
                    }
                    break;

                case State.Identifier:
                    if (!char.IsLetterOrDigit(_text[_i]) && _text[_i] != '_')
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i - _current.StartOffset);
                        _current.Type = SqlType.Identifier;
                        yield return(_current);

                        _i--;
                        _state = State.Start;
                    }
                    break;

                case State.IdentifierBracket:
                    if (_text[_i] == ']')
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i + 1 - _current.StartOffset);
                        _current.Type = SqlType.Identifier;
                        yield return(_current);

                        _state = State.Start;
                    }
                    break;

                case State.IdentifierQuote:
                    if (_text[_i] == '"')
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i + 1 - _current.StartOffset);
                        _current.Type = SqlType.Identifier;
                        yield return(_current);

                        _state = State.Start;
                    }
                    break;

                case State.NumericLiteral:
                    if (_text[_i] == '.')
                    {
                        _state = State.NumDecimalLiteral;
                    }
                    else if (StartsWith('e', '+') || StartsWith('e', '-') ||
                             StartsWith('E', '+') || StartsWith('E', '-'))
                    {
                        _i++;
                        _state = State.NumExponentLiteral;
                    }
                    else if (_text[_i] == 'e' || _text[_i] == 'E')
                    {
                        _i++;
                        _state = State.NumExponentLiteral;
                    }
                    else if (!char.IsDigit(_text[_i]))
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i - _current.StartOffset);
                        _current.Type = SqlType.Number;
                        yield return(_current);

                        _i--;
                        _state = State.Start;
                    }
                    break;

                case State.NumDecimalLiteral:
                    if (StartsWith('e', '+') || StartsWith('e', '-') ||
                        StartsWith('E', '+') || StartsWith('E', '-'))
                    {
                        _i++;
                        _state = State.NumExponentLiteral;
                    }
                    else if (_text[_i] == 'e' || _text[_i] == 'E')
                    {
                        _i++;
                        _state = State.NumExponentLiteral;
                    }
                    else if (!char.IsDigit(_text[_i]))
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i - _current.StartOffset);
                        _current.Type = SqlType.Number;
                        yield return(_current);

                        _i--;
                        _state = State.Start;
                    }
                    break;

                case State.NumExponentLiteral:
                    if (!char.IsDigit(_text[_i]))
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i - _current.StartOffset);
                        _current.Type = SqlType.Number;
                        yield return(_current);

                        _i--;
                        _state = State.Start;
                    }
                    break;

                case State.StringLiteral:
                    if (StartsWith('\'', '\''))
                    {
                        _i++;
                    }
                    else if (_text[_i] == '\'')
                    {
                        _current.Text = _text.Substring(_current.StartOffset, _i + 1 - _current.StartOffset);
                        _current.Type = SqlType.String;
                        yield return(_current);

                        _state = State.Start;
                    }
                    break;

                case State.Whitespace:
                    if (!char.IsWhiteSpace(_text[_i]))
                    {
                        _i--;
                        _state = State.Start;
                    }
                    break;
                }
                _i++;
            }

            if (_state != State.Start && _current.StartOffset >= 0)
            {
                _current.Text = _text.Substring(_current.StartOffset);
                switch (_state)
                {
                case State.BinaryLiteral:
                    _current.Type = SqlType.Binary;
                    break;

                case State.Start:
                case State.Whitespace:
                case State.CommentLine:
                case State.CommentMulti:
                    _current.Type = SqlType.Comment;
                    break;

                case State.Identifier:
                case State.IdentifierBracket:
                case State.IdentifierQuote:
                    _current.Type = SqlType.Identifier;
                    break;

                case State.NumDecimalLiteral:
                case State.NumericLiteral:
                case State.NumExponentLiteral:
                    _current.Type = SqlType.Number;
                    break;

                case State.StringLiteral:
                    _current.Type = SqlType.String;
                    break;
                }
                yield return(_current);
            }
        }
예제 #3
0
        public IEnumerator <SqlNode> GetEnumerator()
        {
            SqlLiteral prevLiteral = null;
            SqlName    prevName    = null;

            var en = MarkKeywords().GetEnumerator();

            if (!en.MoveNext())
            {
                yield break;
            }
            prevLiteral = en.Current;

            while (en.MoveNext())
            {
                if (prevLiteral != null && (KeywordPrecedesTable(prevLiteral) ||
                                            prevLiteral.Text.StartsWith("create ", StringComparison.OrdinalIgnoreCase)))
                {
                    prevName         = new SqlName();
                    prevName.IsTable = true;
                    yield return(prevLiteral);

                    if (prevName.TryAdd(en.Current))
                    {
                        prevLiteral = null;
                    }
                    else
                    {
                        prevLiteral = en.Current;
                        prevName    = null;
                    }
                }
                else if (prevLiteral != null && prevLiteral.Type == SqlType.Identifier && en.Current.Text == ".")
                {
                    prevName = new SqlName();
                    if (prevName.TryAdd(prevLiteral) && prevName.TryAdd(en.Current))
                    {
                        prevLiteral = null;
                    }
                    else
                    {
                        yield return(prevLiteral);

                        prevLiteral = en.Current;
                        prevName    = null;
                    }
                }
                else if (prevName != null)
                {
                    if (!prevName.TryAdd(en.Current))
                    {
                        yield return(prevName);

                        prevName    = null;
                        prevLiteral = en.Current;
                    }
                }
                else
                {
                    yield return(prevLiteral);

                    prevLiteral = en.Current;
                }
            }

            if (prevLiteral != null)
            {
                yield return(prevLiteral);
            }
            if (prevName != null)
            {
                yield return(prevName);
            }
        }