Skip to content

Commit d20763c

Browse files
authored
Support more conditionally top level tokens (shssoichiro#99)
1 parent 227688f commit d20763c

File tree

3 files changed

+97
-18
lines changed

3 files changed

+97
-18
lines changed

src/formatter.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ impl<'a> Formatter<'a> {
233233
self.add_new_line(query);
234234
}
235235
query.push_str(&self.equalize_whitespace(&self.format_reserved_word(token.value)));
236-
if newline_after {
236+
if newline_after && token.alias != "CREATE" {
237237
self.indentation.increase_top_level(span_info);
238238
self.add_new_line(query);
239239
} else {

src/lib.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,25 @@ mod tests {
838838
assert_eq!(format(input, &QueryParams::None, &options), expected);
839839
}
840840

841+
#[test]
842+
fn it_formats_full_delete_query() {
843+
let input =
844+
"DELETE FROM Customers USING Phonebook WHERE CustomerName='Alfred' AND Phone=5002132;";
845+
let options = FormatOptions::default();
846+
let expected = indoc!(
847+
"
848+
DELETE FROM
849+
Customers
850+
USING
851+
Phonebook
852+
WHERE
853+
CustomerName = 'Alfred'
854+
AND Phone = 5002132;"
855+
);
856+
857+
assert_eq!(format(input, &QueryParams::None, &options), expected);
858+
}
859+
841860
#[test]
842861
fn it_formats_simple_drop_query() {
843862
let input = "DROP TABLE IF EXISTS admin_role;";

src/tokenizer.rs

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ pub(crate) struct Token<'a> {
6969
pub value: &'a str,
7070
// Only used for placeholder--there is a reason this isn't on the enum
7171
pub key: Option<PlaceholderKind<'a>>,
72+
/// Used to group the behaviour of variants of tokens
73+
pub alias: &'a str,
7274
}
7375

7476
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -166,6 +168,7 @@ fn get_type_specifier_token<'i>(
166168
kind: TokenKind::TypeSpecifier,
167169
value: token,
168170
key: None,
171+
alias: token,
169172
})
170173
}
171174
}
@@ -176,6 +179,7 @@ fn get_whitespace_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
176179
kind: TokenKind::Whitespace,
177180
value: token,
178181
key: None,
182+
alias: token,
179183
})
180184
}
181185

@@ -192,6 +196,7 @@ fn get_comment_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
192196
kind,
193197
value: token,
194198
key: None,
199+
alias: token,
195200
})
196201
}
197202

@@ -250,6 +255,7 @@ fn get_string_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
250255
kind: TokenKind::String,
251256
value: token,
252257
key: None,
258+
alias: token,
253259
})
254260
}
255261

@@ -269,6 +275,7 @@ fn get_placeholder_string_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
269275
kind: TokenKind::String,
270276
value: token,
271277
key: None,
278+
alias: token,
272279
})
273280
}
274281

@@ -279,6 +286,7 @@ fn get_open_paren_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
279286
kind: TokenKind::OpenParen,
280287
value: token,
281288
key: None,
289+
alias: token,
282290
})
283291
}
284292

@@ -289,6 +297,7 @@ fn get_close_paren_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
289297
kind: TokenKind::CloseParen,
290298
value: token,
291299
key: None,
300+
alias: token,
292301
})
293302
}
294303

@@ -332,6 +341,7 @@ fn get_indexed_placeholder_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
332341
} else {
333342
None
334343
},
344+
alias: token,
335345
})
336346
}
337347

@@ -350,6 +360,7 @@ fn get_ident_named_placeholder_token<'i>(input: &mut &'i str) -> Result<Token<'i
350360
kind: TokenKind::Placeholder,
351361
value: token,
352362
key: Some(PlaceholderKind::Named(index)),
363+
alias: token,
353364
}
354365
})
355366
}
@@ -365,6 +376,7 @@ fn get_string_named_placeholder_token<'i>(input: &mut &'i str) -> Result<Token<'
365376
kind: TokenKind::Placeholder,
366377
value: token,
367378
key: Some(PlaceholderKind::Named(index)),
379+
alias: token,
368380
}
369381
})
370382
}
@@ -381,6 +393,7 @@ fn get_number_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
381393
kind: TokenKind::Number,
382394
value: token,
383395
key: None,
396+
alias: token,
384397
})
385398
}
386399

@@ -464,6 +477,24 @@ fn get_top_level_reserved_token<'a>(
464477
))
465478
.parse_next(&mut uc_input),
466479

480+
'C' => terminated(
481+
(
482+
"CREATE ",
483+
opt(alt((
484+
"UNLOGGED ",
485+
(
486+
alt(("GLOBAL ", "LOCAL ")),
487+
opt(alt(("TEMPORARY ", "TEMP "))),
488+
)
489+
.take(),
490+
))),
491+
"TABLE",
492+
)
493+
.take(),
494+
end_of_word,
495+
)
496+
.parse_next(&mut uc_input),
497+
467498
'D' => terminated("DELETE FROM", end_of_word).parse_next(&mut uc_input),
468499

469500
'E' => terminated("EXCEPT", end_of_word).parse_next(&mut uc_input),
@@ -490,7 +521,11 @@ fn get_top_level_reserved_token<'a>(
490521

491522
'L' => terminated("LIMIT", end_of_word).parse_next(&mut uc_input),
492523

493-
'M' => terminated("MODIFY", end_of_word).parse_next(&mut uc_input),
524+
'M' => alt((
525+
terminated("MODIFY", end_of_word),
526+
terminated("MERGE INTO", end_of_word),
527+
))
528+
.parse_next(&mut uc_input),
494529

495530
'O' => alt((
496531
terminated("ORDER BY", end_of_word),
@@ -512,7 +547,11 @@ fn get_top_level_reserved_token<'a>(
512547
))
513548
.parse_next(&mut uc_input),
514549

515-
'U' => terminated("UPDATE", end_of_word).parse_next(&mut uc_input),
550+
'U' => alt((
551+
terminated("UPDATE", end_of_word),
552+
terminated("USING", end_of_word),
553+
))
554+
.parse_next(&mut uc_input),
516555

517556
'V' => terminated("VALUES", end_of_word).parse_next(&mut uc_input),
518557

@@ -529,27 +568,35 @@ fn get_top_level_reserved_token<'a>(
529568
if let Ok(token) = result {
530569
let token = finalize(input, token);
531570

532-
let kind = match token {
533-
"EXCEPT"
534-
if last_reserved_top_level_token.is_some()
535-
&& last_reserved_top_level_token.as_ref().unwrap().value == "SELECT" =>
536-
// If the query state doesn't allow EXCEPT, treat it as a regular word
571+
let kind = match (
572+
token,
573+
last_reserved_top_level_token.as_ref().map(|v| v.alias),
574+
) {
575+
("EXCEPT", Some("SELECT")) =>
576+
// If the query state doesn't allow EXCEPT, treat it as a reserved word
537577
{
538-
TokenKind::Word
578+
TokenKind::Reserved
539579
}
540-
"SET"
541-
if last_reserved_top_level_token.is_some()
542-
&& last_reserved_top_level_token.as_ref().unwrap().value == "UPDATE" =>
543-
{
544-
TokenKind::ReservedNewlineAfter
580+
("SET", Some("UPDATE")) => TokenKind::ReservedNewlineAfter,
581+
("USING", v) if v != Some("MERGE INTO") && v != Some("DELETE FROM") => {
582+
TokenKind::Reserved
545583
}
546584
_ => TokenKind::ReservedTopLevel,
547585
};
548586

587+
let alias = if token.starts_with("CREATE") {
588+
"CREATE"
589+
} else if token.starts_with("SELECT") {
590+
"SELECT"
591+
} else {
592+
token
593+
};
594+
549595
Ok(Token {
550596
kind,
551597
value: token,
552598
key: None,
599+
alias,
553600
})
554601
} else {
555602
Err(ParserError::from_input(input))
@@ -613,6 +660,7 @@ fn get_join_token<'a>() -> impl Parser<&'a str, Token<'a>, ContextError> {
613660
kind,
614661
value: token,
615662
key: None,
663+
alias: token,
616664
})
617665
} else {
618666
Err(ParserError::from_input(input))
@@ -633,10 +681,12 @@ fn get_newline_after_reserved_token<'a>() -> impl Parser<&'a str, Token<'a>, Con
633681
let result: Result<&str> = on_conflict.parse_next(&mut uc_input);
634682

635683
if let Ok(token) = result {
684+
let value = finalize(input, token);
636685
Ok(Token {
637686
kind: TokenKind::ReservedNewlineAfter,
638-
value: finalize(input, token),
687+
value,
639688
key: None,
689+
alias: value,
640690
})
641691
} else {
642692
Err(ParserError::from_input(input))
@@ -692,6 +742,7 @@ fn get_newline_reserved_token<'a>(
692742
kind,
693743
value: token,
694744
key: None,
745+
alias: token,
695746
})
696747
} else {
697748
Err(ParserError::from_input(input))
@@ -716,10 +767,12 @@ fn get_top_level_reserved_token_no_indent<'i>(input: &mut &'i str) -> Result<Tok
716767
))
717768
.parse_next(&mut uc_input);
718769
if let Ok(token) = result {
770+
let value = finalize(input, token);
719771
Ok(Token {
720772
kind: TokenKind::ReservedTopLevelNoIndent,
721-
value: finalize(input, token),
773+
value,
722774
key: None,
775+
alias: value,
723776
})
724777
} else {
725778
Err(ParserError::from_input(input))
@@ -1080,6 +1133,7 @@ fn get_plain_reserved_one_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
10801133
terminated("TRUNCATE", end_of_word),
10811134
terminated("TYPE", end_of_word),
10821135
terminated("TYPES", end_of_word),
1136+
terminated("TBLPROPERTIES", end_of_word),
10831137
))
10841138
.parse_next(&mut uc_input),
10851139

@@ -1090,7 +1144,6 @@ fn get_plain_reserved_one_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
10901144
terminated("UNSIGNED", end_of_word),
10911145
terminated("USAGE", end_of_word),
10921146
terminated("USE", end_of_word),
1093-
terminated("USING", end_of_word),
10941147
))
10951148
.parse_next(&mut uc_input),
10961149

@@ -1118,6 +1171,7 @@ fn get_plain_reserved_one_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
11181171
kind: TokenKind::Reserved,
11191172
value: token,
11201173
key: None,
1174+
alias: token,
11211175
})
11221176
} else {
11231177
Err(ParserError::from_input(input))
@@ -1134,13 +1188,16 @@ fn get_plain_reserved_two_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
11341188
terminated("ON DELETE", end_of_word),
11351189
terminated("ON UPDATE", end_of_word),
11361190
terminated("DISTINCT FROM", end_of_word),
1191+
terminated("PARTITIONED BY", end_of_word),
11371192
))
11381193
.parse_next(&mut uc_input);
11391194
if let Ok(token) = result {
1195+
let value = finalize(input, token);
11401196
Ok(Token {
11411197
kind: TokenKind::Reserved,
1142-
value: finalize(input, token),
1198+
value,
11431199
key: None,
1200+
alias: value,
11441201
})
11451202
} else {
11461203
Err(ParserError::from_input(input))
@@ -1154,6 +1211,7 @@ fn get_word_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
11541211
kind: TokenKind::Word,
11551212
value: token,
11561213
key: None,
1214+
alias: token,
11571215
})
11581216
}
11591217

@@ -1168,6 +1226,7 @@ fn get_operator_token<'i>(input: &mut &'i str) -> Result<Token<'i>> {
11681226
kind: TokenKind::Operator,
11691227
value: token,
11701228
key: None,
1229+
alias: token,
11711230
})
11721231
.parse_next(input)
11731232
}
@@ -1179,6 +1238,7 @@ fn get_any_other_char<'i>(input: &mut &'i str) -> Result<Token<'i>> {
11791238
kind: TokenKind::Operator,
11801239
value: token,
11811240
key: None,
1241+
alias: token,
11821242
})
11831243
}
11841244

0 commit comments

Comments
 (0)