mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-12-23 11:12:51 +00:00
Tentatively added support for path identifiers
This commit is contained in:
parent
93ea5d2458
commit
819c0958d6
3 changed files with 49 additions and 2 deletions
|
|
@ -183,6 +183,11 @@ pub trait Dialect: Debug + Any {
|
|||
false
|
||||
}
|
||||
|
||||
/// Returns whether the dialect supports path-like identifiers
|
||||
fn supports_path_like_identifiers(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Most dialects do not have custom operators. Override this method to provide custom operators.
|
||||
fn is_custom_operator_part(&self, _ch: char) -> bool {
|
||||
false
|
||||
|
|
|
|||
|
|
@ -158,6 +158,10 @@ impl Dialect for SnowflakeDialect {
|
|||
|| ch == '_'
|
||||
}
|
||||
|
||||
fn supports_path_like_identifiers(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// See https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#escape_sequences
|
||||
fn supports_string_literal_backslash_escape(&self) -> bool {
|
||||
true
|
||||
|
|
@ -1067,8 +1071,22 @@ pub fn parse_stage_name_identifier(parser: &mut Parser) -> Result<Ident, ParserE
|
|||
Token::Plus => ident.push('+'),
|
||||
Token::Minus => ident.push('-'),
|
||||
Token::Number(n, _) => ident.push_str(n),
|
||||
Token::Word(w) => ident.push_str(&w.to_string()),
|
||||
_ => return parser.expected("stage name identifier", parser.peek_token()),
|
||||
Token::Word(w) => {
|
||||
if matches!(w.keyword, Keyword::NoKeyword) {
|
||||
ident.push_str(w.to_string().as_str());
|
||||
} else {
|
||||
parser.prev_token();
|
||||
break;
|
||||
}
|
||||
}
|
||||
token => {
|
||||
return {
|
||||
println!(
|
||||
"Unexpected token {token:?} while parsing stage name identifier {ident:?}"
|
||||
);
|
||||
parser.expected("stage name identifier", parser.peek_token())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Ident::new(ident))
|
||||
|
|
|
|||
|
|
@ -1669,6 +1669,11 @@ impl<'a> Tokenizer<'a> {
|
|||
_ => self.start_binop(chars, "~~", Token::DoubleTilde),
|
||||
}
|
||||
}
|
||||
Some('/') if self.dialect.supports_path_like_identifiers() => {
|
||||
// regular identifier starting with an "E" or "e"
|
||||
let s = self.tokenize_word("~", chars, prev_keyword)?;
|
||||
Ok(Some(Token::make_word(s, None)))
|
||||
}
|
||||
_ => self.start_binop(chars, "~", Token::Tilde),
|
||||
}
|
||||
}
|
||||
|
|
@ -1969,6 +1974,25 @@ impl<'a> Tokenizer<'a> {
|
|||
s.push_str(&peeking_take_while(chars, |ch| {
|
||||
self.dialect.is_identifier_part(ch)
|
||||
}));
|
||||
|
||||
while !matches!(prev_keyword, Some(Keyword::SELECT))
|
||||
&& self.dialect.supports_path_like_identifiers()
|
||||
&& chars.peek().map(|&ch| ch == '/').unwrap_or(false)
|
||||
&& chars
|
||||
.peekable
|
||||
.clone()
|
||||
.nth(1)
|
||||
.map(|ch| ch.is_alphabetic())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
s.push('/');
|
||||
chars.next(); // consume the '/'
|
||||
|
||||
s.push_str(&peeking_take_while(chars, |ch| {
|
||||
self.dialect.is_identifier_part(ch)
|
||||
}));
|
||||
}
|
||||
|
||||
if !matches!(prev_keyword, Some(Keyword::SELECT))
|
||||
&& self.dialect.supports_hyphenated_identifiers()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue