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); }
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); } }
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); } }