Skip to content

Commit

Permalink
feat: Give joins their own token kind
Browse files Browse the repository at this point in the history
  • Loading branch information
lu-zero committed Jan 27, 2025
1 parent a963b1a commit 7ec2218
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 16 deletions.
9 changes: 7 additions & 2 deletions src/formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ pub(crate) fn format(
formatter.format_newline_reserved_word(token, &mut formatted_query);
formatter.previous_reserved_word = Some(token);
}
TokenKind::Join => {
formatter.format_newline_reserved_word(token, &mut formatted_query);
formatter.previous_reserved_word = Some(token);
}
TokenKind::Reserved => {
formatter.format_with_spaces(token, &mut formatted_query);
formatter.previous_reserved_word = Some(token);
Expand Down Expand Up @@ -210,8 +214,9 @@ impl<'a> Formatter<'a> {
self.add_new_line(query);
self.indentation.increase_top_level(span_len);
query.push_str(&self.equalize_whitespace(&self.format_reserved_word(token.value)));
if !(!["select", "from"].contains(&token.value.to_lowercase().as_str())
&& self.options.inline_first_top_level)
let new_line = ["select", "from"].contains(&token.value.to_lowercase().as_str())
|| !self.options.inline_first_top_level;
if new_line
&& self
.options
.max_inline_top_level
Expand Down
49 changes: 35 additions & 14 deletions src/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub(crate) enum TokenKind {
Number,
Placeholder,
Word,
Join,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -379,6 +380,7 @@ fn get_reserved_word_token<'a>(
alt((
get_top_level_reserved_token(last_reserved_top_level_token),
get_newline_reserved_token(last_reserved_token),
get_join_token(),
get_top_level_reserved_token_no_indent,
get_plain_reserved_token,
))
Expand Down Expand Up @@ -497,16 +499,11 @@ fn get_top_level_reserved_token<'a>(
}
}

fn get_newline_reserved_token<'a>(
last_reserved_token: Option<Token<'a>>,
) -> impl Parser<&'a str, Token<'a>, ContextError> {
fn get_join_token<'a>() -> impl Parser<&'a str, Token<'a>, ContextError> {
move |input: &mut &'a str| {
let uc_input: String = get_uc_words(input, 3);
let mut uc_input = uc_input.as_str();

// We have to break up the alternatives into multiple subsets
// to avoid exceeding the alt() 21 element limit.

// Standard SQL joins
let standard_joins = alt((
terminated("JOIN", end_of_word),
Expand Down Expand Up @@ -544,6 +541,37 @@ fn get_newline_reserved_token<'a>(
terminated("GLOBAL FULL JOIN", end_of_word),
));

// Combine all parsers
let result: PResult<&str> =
alt((standard_joins, specific_joins, special_joins)).parse_next(&mut uc_input);

if let Ok(token) = result {
let final_word = token.split(' ').last().unwrap();
let input_end_pos =
input.to_ascii_uppercase().find(final_word).unwrap() + final_word.len();
let token = input.next_slice(input_end_pos);
let kind = TokenKind::Join;
Ok(Token {
kind,
value: token,
key: None,
})
} else {
Err(ErrMode::from_error_kind(input, ErrorKind::Alt))
}
}
}

fn get_newline_reserved_token<'a>(
last_reserved_token: Option<Token<'a>>,
) -> impl Parser<&'a str, Token<'a>, ContextError> {
move |input: &mut &'a str| {
let uc_input: String = get_uc_words(input, 3);
let mut uc_input = uc_input.as_str();

// We have to break up the alternatives into multiple subsets
// to avoid exceeding the alt() 21 element limit.

// Legacy and logical operators
let operators = alt((
terminated("CROSS APPLY", end_of_word),
Expand All @@ -565,14 +593,7 @@ fn get_newline_reserved_token<'a>(
));

// Combine all parsers
let result: PResult<&str> = alt((
standard_joins,
specific_joins,
special_joins,
operators,
alter_table_actions,
))
.parse_next(&mut uc_input);
let result: PResult<&str> = alt((operators, alter_table_actions)).parse_next(&mut uc_input);

if let Ok(token) = result {
let final_word = token.split(' ').last().unwrap();
Expand Down

0 comments on commit 7ec2218

Please sign in to comment.