Skip to content

Commit a4628ce

Browse files
committed
feat: Parse special keywors as functions (current_user, user, etc)
1 parent 2fdd894 commit a4628ce

7 files changed

Lines changed: 112 additions & 17 deletions

File tree

src/ast/mod.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,20 +2184,27 @@ pub struct Function {
21842184
pub over: Option<WindowSpec>,
21852185
// aggregate functions may specify eg `COUNT(DISTINCT x)`
21862186
pub distinct: bool,
2187+
pub special: bool,
21872188
}
21882189

21892190
impl fmt::Display for Function {
21902191
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2191-
write!(
2192-
f,
2193-
"{}({}{})",
2194-
self.name,
2195-
if self.distinct { "DISTINCT " } else { "" },
2196-
display_comma_separated(&self.args),
2197-
)?;
2198-
if let Some(o) = &self.over {
2199-
write!(f, " OVER ({})", o)?;
2192+
if self.special {
2193+
write!(f, "{}", self.name)?;
2194+
} else {
2195+
write!(
2196+
f,
2197+
"{}({}{})",
2198+
self.name,
2199+
if self.distinct { "DISTINCT " } else { "" },
2200+
display_comma_separated(&self.args),
2201+
)?;
2202+
2203+
if let Some(o) = &self.over {
2204+
write!(f, " OVER ({})", o)?;
2205+
}
22002206
}
2207+
22012208
Ok(())
22022209
}
22032210
}

src/ast/value.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl fmt::Display for Value {
9393
assert!(last_field.is_none());
9494
write!(
9595
f,
96-
"INTERVAL '{}' SECOND ({}, {})",
96+
"INTERVAL {} SECOND ({}, {})",
9797
value, leading_precision, fractional_seconds_precision
9898
)
9999
}

src/parser.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,20 @@ impl<'a> Parser<'a> {
420420
self.prev_token();
421421
Ok(Expr::Value(self.parse_value()?))
422422
}
423+
Keyword::CURRENT_CATALOG
424+
| Keyword::CURRENT_USER
425+
| Keyword::SESSION_USER
426+
| Keyword::USER
427+
if dialect_of!(self is PostgreSqlDialect | GenericDialect) =>
428+
{
429+
Ok(Expr::Function(Function {
430+
name: ObjectName(vec![w.to_ident()]),
431+
args: vec![],
432+
over: None,
433+
distinct: false,
434+
special: true,
435+
}))
436+
}
423437
Keyword::CURRENT_TIMESTAMP | Keyword::CURRENT_TIME | Keyword::CURRENT_DATE => {
424438
self.parse_time_functions(ObjectName(vec![w.to_ident()]))
425439
}
@@ -592,6 +606,7 @@ impl<'a> Parser<'a> {
592606
args,
593607
over,
594608
distinct,
609+
special: false,
595610
}))
596611
}
597612

@@ -606,6 +621,7 @@ impl<'a> Parser<'a> {
606621
args,
607622
over: None,
608623
distinct: false,
624+
special: false,
609625
}))
610626
}
611627

@@ -3374,10 +3390,16 @@ impl<'a> Parser<'a> {
33743390
}
33753391

33763392
if let Some(Keyword::TRANSACTION) = modifier {
3393+
let snapshot = if self.parse_keyword(Keyword::SNAPSHOT) {
3394+
Some(self.parse_value()?)
3395+
} else {
3396+
None
3397+
};
3398+
33773399
return Ok(Statement::SetTransaction {
33783400
modes: self.parse_transaction_modes()?,
33793401
global,
3380-
snapshot: None,
3402+
snapshot,
33813403
characteristics_as: false,
33823404
});
33833405
}

tests/sqlparser_common.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,7 @@ fn parse_select_count_wildcard() {
507507
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Wildcard)],
508508
over: None,
509509
distinct: false,
510+
special: false,
510511
}),
511512
expr_from_projection(only(&select.projection))
512513
);
@@ -525,6 +526,7 @@ fn parse_select_count_distinct() {
525526
}))],
526527
over: None,
527528
distinct: true,
529+
special: false,
528530
}),
529531
expr_from_projection(only(&select.projection))
530532
);
@@ -1329,6 +1331,7 @@ fn parse_select_having() {
13291331
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Wildcard)],
13301332
over: None,
13311333
distinct: false,
1334+
special: false,
13321335
})),
13331336
op: BinaryOperator::Gt,
13341337
right: Box::new(Expr::Value(number("1")))
@@ -2318,6 +2321,7 @@ fn parse_scalar_function_in_projection() {
23182321
))],
23192322
over: None,
23202323
distinct: false,
2324+
special: false,
23212325
}),
23222326
expr_from_projection(only(&select.projection))
23232327
);
@@ -2396,6 +2400,7 @@ fn parse_named_argument_function() {
23962400
],
23972401
over: None,
23982402
distinct: false,
2403+
special: false,
23992404
}),
24002405
expr_from_projection(only(&select.projection))
24012406
);
@@ -2429,6 +2434,7 @@ fn parse_window_functions() {
24292434
window_frame: None,
24302435
}),
24312436
distinct: false,
2437+
special: false,
24322438
}),
24332439
expr_from_projection(&select.projection[0])
24342440
);
@@ -2537,6 +2543,7 @@ fn parse_expr_interval() {
25372543
))],
25382544
over: None,
25392545
distinct: false,
2546+
special: false,
25402547
});
25412548

25422549
assert_eq!(
@@ -2568,6 +2575,7 @@ fn parse_expr_interval() {
25682575
))],
25692576
over: None,
25702577
distinct: false,
2578+
special: false,
25712579
});
25722580
assert_eq!(
25732581
&Expr::Value(Value::Interval {
@@ -2722,6 +2730,7 @@ fn parse_table_function() {
27222730
)))],
27232731
over: None,
27242732
distinct: false,
2733+
special: false,
27252734
});
27262735
assert_eq!(expr, expected_expr);
27272736
assert_eq!(alias, table_alias("a"))
@@ -2778,6 +2787,7 @@ fn parse_delimited_identifiers() {
27782787
args: vec![],
27792788
over: None,
27802789
distinct: false,
2790+
special: false,
27812791
}),
27822792
expr_from_projection(&select.projection[1]),
27832793
);
@@ -4680,6 +4690,7 @@ fn parse_time_functions() {
46804690
args: vec![],
46814691
over: None,
46824692
distinct: false,
4693+
special: false,
46834694
}),
46844695
expr_from_projection(&select.projection[0])
46854696
);
@@ -4695,6 +4706,7 @@ fn parse_time_functions() {
46954706
args: vec![],
46964707
over: None,
46974708
distinct: false,
4709+
special: false,
46984710
}),
46994711
expr_from_projection(&select.projection[0])
47004712
);
@@ -4710,6 +4722,7 @@ fn parse_time_functions() {
47104722
args: vec![],
47114723
over: None,
47124724
distinct: false,
4725+
special: false,
47134726
}),
47144727
expr_from_projection(&select.projection[0])
47154728
);

tests/sqlparser_mysql.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,8 @@ fn parse_insert_with_on_duplicate_update() {
692692
Expr::Identifier(Ident::new("description"))
693693
))],
694694
over: None,
695-
distinct: false
695+
distinct: false,
696+
special: false,
696697
})
697698
},
698699
Assignment {
@@ -703,7 +704,8 @@ fn parse_insert_with_on_duplicate_update() {
703704
Expr::Identifier(Ident::new("perm_create"))
704705
))],
705706
over: None,
706-
distinct: false
707+
distinct: false,
708+
special: false,
707709
})
708710
},
709711
Assignment {
@@ -714,7 +716,8 @@ fn parse_insert_with_on_duplicate_update() {
714716
Expr::Identifier(Ident::new("perm_read"))
715717
))],
716718
over: None,
717-
distinct: false
719+
distinct: false,
720+
special: false,
718721
})
719722
},
720723
Assignment {
@@ -725,7 +728,8 @@ fn parse_insert_with_on_duplicate_update() {
725728
Expr::Identifier(Ident::new("perm_update"))
726729
))],
727730
over: None,
728-
distinct: false
731+
distinct: false,
732+
special: false,
729733
})
730734
},
731735
Assignment {
@@ -736,7 +740,8 @@ fn parse_insert_with_on_duplicate_update() {
736740
Expr::Identifier(Ident::new("perm_delete"))
737741
))],
738742
over: None,
739-
distinct: false
743+
distinct: false,
744+
special: false,
740745
})
741746
},
742747
])),

tests/sqlparser_postgres.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,52 @@ fn parse_escaped_literal_string() {
13351335
);
13361336
}
13371337

1338+
#[test]
1339+
fn parse_current_functions() {
1340+
let sql = "SELECT CURRENT_CATALOG, CURRENT_USER, SESSION_USER, USER";
1341+
let select = pg_and_generic().verified_only_select(sql);
1342+
assert_eq!(
1343+
&Expr::Function(Function {
1344+
name: ObjectName(vec![Ident::new("CURRENT_CATALOG")]),
1345+
args: vec![],
1346+
over: None,
1347+
distinct: false,
1348+
special: true,
1349+
}),
1350+
expr_from_projection(&select.projection[0])
1351+
);
1352+
assert_eq!(
1353+
&Expr::Function(Function {
1354+
name: ObjectName(vec![Ident::new("CURRENT_USER")]),
1355+
args: vec![],
1356+
over: None,
1357+
distinct: false,
1358+
special: true,
1359+
}),
1360+
expr_from_projection(&select.projection[1])
1361+
);
1362+
assert_eq!(
1363+
&Expr::Function(Function {
1364+
name: ObjectName(vec![Ident::new("SESSION_USER")]),
1365+
args: vec![],
1366+
over: None,
1367+
distinct: false,
1368+
special: true,
1369+
}),
1370+
expr_from_projection(&select.projection[2])
1371+
);
1372+
assert_eq!(
1373+
&Expr::Function(Function {
1374+
name: ObjectName(vec![Ident::new("USER")]),
1375+
args: vec![],
1376+
over: None,
1377+
distinct: false,
1378+
special: true,
1379+
}),
1380+
expr_from_projection(&select.projection[3])
1381+
);
1382+
}
1383+
13381384
#[test]
13391385
fn parse_fetch() {
13401386
pg_and_generic().verified_stmt("FETCH 2048 IN \"SQL_CUR0x7fa44801bc00\"");

tests/sqpparser_clickhouse.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ fn parse_map_access_expr() {
5151
],
5252
over: None,
5353
distinct: false,
54+
special: false,
5455
})],
5556
})],
5657
into: None,
@@ -85,7 +86,8 @@ fn parse_map_access_expr() {
8586
))),
8687
],
8788
over: None,
88-
distinct: false
89+
distinct: false,
90+
special: false,
8991
})]
9092
}),
9193
op: BinaryOperator::NotEq,

0 commit comments

Comments
 (0)