mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-27 07:59:11 +00:00
Fix placeholder spans (#1979)
This commit is contained in:
parent
f5f51eb6f1
commit
6932f4ad65
2 changed files with 42 additions and 6 deletions
|
@ -2525,4 +2525,27 @@ pub mod tests {
|
|||
"CASE 1 WHEN 2 THEN 3 ELSE 4 END"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_placeholder_span() {
|
||||
let sql = "\nSELECT\n :fooBar";
|
||||
let r = Parser::parse_sql(&GenericDialect, sql).unwrap();
|
||||
assert_eq!(1, r.len());
|
||||
match &r[0] {
|
||||
Statement::Query(q) => {
|
||||
let col = &q.body.as_select().unwrap().projection[0];
|
||||
match col {
|
||||
SelectItem::UnnamedExpr(Expr::Value(ValueWithSpan {
|
||||
value: Value::Placeholder(s),
|
||||
span,
|
||||
})) => {
|
||||
assert_eq!(":fooBar", s);
|
||||
assert_eq!(&Span::new((3, 3).into(), (3, 10).into()), span);
|
||||
}
|
||||
_ => panic!("expected unnamed expression; got {col:?}"),
|
||||
}
|
||||
}
|
||||
stmt => panic!("expected query; got {stmt:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9636,16 +9636,21 @@ impl<'a> Parser<'a> {
|
|||
Token::HexStringLiteral(ref s) => ok_value(Value::HexStringLiteral(s.to_string())),
|
||||
Token::Placeholder(ref s) => ok_value(Value::Placeholder(s.to_string())),
|
||||
tok @ Token::Colon | tok @ Token::AtSign => {
|
||||
// Not calling self.parse_identifier(false)? because only in placeholder we want to check numbers as idfentifies
|
||||
// This because snowflake allows numbers as placeholders
|
||||
let next_token = self.next_token();
|
||||
// 1. Not calling self.parse_identifier(false)?
|
||||
// because only in placeholder we want to check
|
||||
// numbers as idfentifies. This because snowflake
|
||||
// allows numbers as placeholders
|
||||
// 2. Not calling self.next_token() to enforce `tok`
|
||||
// be followed immediately by a word/number, ie.
|
||||
// without any whitespace in between
|
||||
let next_token = self.next_token_no_skip().unwrap_or(&EOF_TOKEN).clone();
|
||||
let ident = match next_token.token {
|
||||
Token::Word(w) => Ok(w.into_ident(next_token.span)),
|
||||
Token::Number(w, false) => Ok(Ident::new(w)),
|
||||
Token::Number(w, false) => Ok(Ident::with_span(next_token.span, w)),
|
||||
_ => self.expected("placeholder", next_token),
|
||||
}?;
|
||||
let placeholder = tok.to_string() + &ident.value;
|
||||
ok_value(Value::Placeholder(placeholder))
|
||||
Ok(Value::Placeholder(tok.to_string() + &ident.value)
|
||||
.with_span(Span::new(span.start, ident.span.end)))
|
||||
}
|
||||
unexpected => self.expected(
|
||||
"a value",
|
||||
|
@ -17600,4 +17605,12 @@ mod tests {
|
|||
canonical,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_placeholder_invalid_whitespace() {
|
||||
for w in [" ", "/*invalid*/"] {
|
||||
let sql = format!("\nSELECT\n :{w}fooBar");
|
||||
assert!(Parser::parse_sql(&GenericDialect, &sql).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue