Skip to content

Commit 827d639

Browse files
maxjustusshssoichiro
authored andcommitted
1 parent fe382a4 commit 827d639

File tree

2 files changed

+80
-13
lines changed

2 files changed

+80
-13
lines changed

src/lib.rs

+28
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,34 @@ mod tests {
320320
assert_eq!(format(input, &QueryParams::None, &options), expected);
321321
}
322322

323+
#[test]
324+
fn it_formats_select_query_with_non_standard_join() {
325+
let input = indoc!(
326+
"
327+
SELECT customer_id.from, COUNT(order_id) AS total FROM customers
328+
INNER ANY JOIN orders ON customers.customer_id = orders.customer_id
329+
LEFT
330+
SEMI JOIN foo ON foo.id = customers.id
331+
PASTE
332+
JOIN bar
333+
;"
334+
);
335+
let options = FormatOptions::default();
336+
let expected = indoc!(
337+
"
338+
SELECT
339+
customer_id.from,
340+
COUNT(order_id) AS total
341+
FROM
342+
customers
343+
INNER ANY JOIN orders ON customers.customer_id = orders.customer_id
344+
LEFT SEMI JOIN foo ON foo.id = customers.id
345+
PASTE JOIN bar;"
346+
);
347+
348+
assert_eq!(format(input, &QueryParams::None, &options), expected);
349+
}
350+
323351
#[test]
324352
fn it_formats_select_query_with_different_comments() {
325353
let input = indoc!(

src/tokenizer.rs

+52-13
Original file line numberDiff line numberDiff line change
@@ -580,24 +580,63 @@ fn get_newline_reserved_token<'a>(
580580
last_reserved_token: Option<Token<'a>>,
581581
) -> impl FnMut(&'a str) -> IResult<&'a str, Token<'a>> {
582582
move |input: &'a str| {
583-
let uc_input = get_uc_words(input, 3);
584-
let result: IResult<&str, &str> = alt((
585-
terminated(tag("AND"), end_of_word),
586-
terminated(tag("CROSS APPLY"), end_of_word),
587-
terminated(tag("CROSS JOIN"), end_of_word),
588-
terminated(tag("ELSE"), end_of_word),
589-
terminated(tag("INNER JOIN"), end_of_word),
583+
let uc_input: String = get_uc_words(input, 3);
584+
585+
// We have to break up the alternatives into multiple subsets
586+
// to avoid exceeding the alt() 21 element limit.
587+
588+
// Standard SQL joins
589+
let standard_joins = alt((
590590
terminated(tag("JOIN"), end_of_word),
591+
terminated(tag("INNER JOIN"), end_of_word),
591592
terminated(tag("LEFT JOIN"), end_of_word),
592-
terminated(tag("LEFT OUTER JOIN"), end_of_word),
593-
terminated(tag("OR"), end_of_word),
594-
terminated(tag("OUTER APPLY"), end_of_word),
595-
terminated(tag("OUTER JOIN"), end_of_word),
596593
terminated(tag("RIGHT JOIN"), end_of_word),
594+
terminated(tag("FULL JOIN"), end_of_word),
595+
terminated(tag("CROSS JOIN"), end_of_word),
596+
terminated(tag("LEFT OUTER JOIN"), end_of_word),
597597
terminated(tag("RIGHT OUTER JOIN"), end_of_word),
598-
terminated(tag("WHEN"), end_of_word),
598+
terminated(tag("FULL OUTER JOIN"), end_of_word),
599+
));
600+
601+
// Warehouse-specific ANY/SEMI/ANTI joins
602+
let specific_joins = alt((
603+
terminated(tag("INNER ANY JOIN"), end_of_word),
604+
terminated(tag("LEFT ANY JOIN"), end_of_word),
605+
terminated(tag("RIGHT ANY JOIN"), end_of_word),
606+
terminated(tag("ANY JOIN"), end_of_word),
607+
terminated(tag("SEMI JOIN"), end_of_word),
608+
terminated(tag("LEFT SEMI JOIN"), end_of_word),
609+
terminated(tag("RIGHT SEMI JOIN"), end_of_word),
610+
terminated(tag("LEFT ANTI JOIN"), end_of_word),
611+
terminated(tag("RIGHT ANTI JOIN"), end_of_word),
612+
));
613+
614+
// Special joins and GLOBAL variants
615+
let special_joins = alt((
616+
terminated(tag("ASOF JOIN"), end_of_word),
617+
terminated(tag("LEFT ASOF JOIN"), end_of_word),
618+
terminated(tag("PASTE JOIN"), end_of_word),
619+
terminated(tag("GLOBAL INNER JOIN"), end_of_word),
620+
terminated(tag("GLOBAL LEFT JOIN"), end_of_word),
621+
terminated(tag("GLOBAL RIGHT JOIN"), end_of_word),
622+
terminated(tag("GLOBAL FULL JOIN"), end_of_word),
623+
));
624+
625+
// Legacy and logical operators
626+
let operators = alt((
627+
terminated(tag("CROSS APPLY"), end_of_word),
628+
terminated(tag("OUTER APPLY"), end_of_word),
629+
terminated(tag("AND"), end_of_word),
630+
terminated(tag("OR"), end_of_word),
599631
terminated(tag("XOR"), end_of_word),
600-
))(&uc_input);
632+
terminated(tag("WHEN"), end_of_word),
633+
terminated(tag("ELSE"), end_of_word),
634+
));
635+
636+
// Combine all parsers
637+
let result: IResult<&str, &str> =
638+
alt((standard_joins, specific_joins, special_joins, operators))(&uc_input);
639+
601640
if let Ok((_, token)) = result {
602641
let final_word = token.split(' ').last().unwrap();
603642
let input_end_pos =

0 commit comments

Comments
 (0)