use sql_dialect_fmt_lexer::{tokenize, tokenize_for_dialect, Dialect, SyntaxKind::*};
type LexPair<'a> = (sql_dialect_fmt_lexer::SyntaxKind, &'a str);
fn non_trivia_for(input: &str, dialect: Dialect) -> Vec<LexPair<'_>> {
let lexed = tokenize_for_dialect(input, dialect);
let joined: String = lexed.tokens.iter().map(|t| t.text).collect();
assert_eq!(
joined, input,
"lex must round-trip for {input:?} @ {dialect:?}"
);
lexed
.tokens
.into_iter()
.filter(|t| !t.kind.is_trivia())
.map(|t| (t.kind, t.text))
.collect()
}
#[test]
fn backtick_identifier_is_quoted_ident_under_databricks() {
assert_eq!(
non_trivia_for("`col`", Dialect::Databricks),
vec![(QUOTED_IDENT, "`col`")]
);
let lexed = tokenize_for_dialect("`col`", Dialect::Databricks);
assert!(lexed.errors.is_empty(), "{:?}", lexed.errors);
}
#[test]
fn backtick_identifier_in_select_under_databricks() {
assert_eq!(
non_trivia_for("SELECT `a b`, `c` FROM `my tbl`", Dialect::Databricks),
vec![
(IDENT, "SELECT"),
(QUOTED_IDENT, "`a b`"),
(COMMA, ","),
(QUOTED_IDENT, "`c`"),
(IDENT, "FROM"),
(QUOTED_IDENT, "`my tbl`"),
]
);
}
#[test]
fn doubled_backtick_escape_under_databricks() {
assert_eq!(
non_trivia_for("`a``b`", Dialect::Databricks),
vec![(QUOTED_IDENT, "`a``b`")]
);
assert_eq!(
non_trivia_for("`x` `y`", Dialect::Databricks),
vec![(QUOTED_IDENT, "`x`"), (QUOTED_IDENT, "`y`")]
);
}
#[test]
fn unterminated_backtick_identifier_records_error_but_stays_lossless() {
let lexed = tokenize_for_dialect("`oops", Dialect::Databricks);
let joined: String = lexed.tokens.iter().map(|t| t.text).collect();
assert_eq!(joined, "`oops");
assert_eq!(lexed.tokens.len(), 1);
assert_eq!(lexed.tokens[0].kind, QUOTED_IDENT);
assert!(
!lexed.errors.is_empty(),
"should record an unterminated error"
);
}
#[test]
fn snowflake_backtick_behavior_is_unchanged() {
let expected = vec![(ERROR, "`"), (IDENT, "col"), (ERROR, "`")];
assert_eq!(non_trivia_for("`col`", Dialect::Snowflake), expected);
let default_pairs: Vec<LexPair<'_>> = tokenize("`col`")
.tokens
.into_iter()
.filter(|t| !t.kind.is_trivia())
.map(|t| (t.kind, t.text))
.collect();
assert_eq!(default_pairs, expected);
let lexed = tokenize("`col`");
assert!(
!lexed.errors.is_empty(),
"Snowflake should still flag a backtick as an error"
);
}