Skip to content

Commit 54a29e8

Browse files
authored
feat: Parse special keywords as functions (current_user, user, etc) (apache#561)
* feat: Parse special keywors as functions (current_user, user, etc) * explain special field
1 parent b6e36ad commit 54a29e8

File tree

6 files changed

+111
-17
lines changed

6 files changed

+111
-17
lines changed

src/ast/mod.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,20 +2321,29 @@ pub struct Function {
23212321
pub over: Option<WindowSpec>,
23222322
// aggregate functions may specify eg `COUNT(DISTINCT x)`
23232323
pub distinct: bool,
2324+
// Some functions must be called without trailing parentheses, for example Postgres
2325+
// do it for current_catalog, current_schema, etc. This flags is used for formatting.
2326+
pub special: bool,
23242327
}
23252328

23262329
impl fmt::Display for Function {
23272330
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2328-
write!(
2329-
f,
2330-
"{}({}{})",
2331-
self.name,
2332-
if self.distinct { "DISTINCT " } else { "" },
2333-
display_comma_separated(&self.args),
2334-
)?;
2335-
if let Some(o) = &self.over {
2336-
write!(f, " OVER ({})", o)?;
2331+
if self.special {
2332+
write!(f, "{}", self.name)?;
2333+
} else {
2334+
write!(
2335+
f,
2336+
"{}({}{})",
2337+
self.name,
2338+
if self.distinct { "DISTINCT " } else { "" },
2339+
display_comma_separated(&self.args),
2340+
)?;
2341+
2342+
if let Some(o) = &self.over {
2343+
write!(f, " OVER ({})", o)?;
2344+
}
23372345
}
2346+
23382347
Ok(())
23392348
}
23402349
}

src/parser.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,20 @@ impl<'a> Parser<'a> {
421421
self.prev_token();
422422
Ok(Expr::Value(self.parse_value()?))
423423
}
424+
Keyword::CURRENT_CATALOG
425+
| Keyword::CURRENT_USER
426+
| Keyword::SESSION_USER
427+
| Keyword::USER
428+
if dialect_of!(self is PostgreSqlDialect | GenericDialect) =>
429+
{
430+
Ok(Expr::Function(Function {
431+
name: ObjectName(vec![w.to_ident()]),
432+
args: vec![],
433+
over: None,
434+
distinct: false,
435+
special: true,
436+
}))
437+
}
424438
Keyword::CURRENT_TIMESTAMP | Keyword::CURRENT_TIME | Keyword::CURRENT_DATE => {
425439
self.parse_time_functions(ObjectName(vec![w.to_ident()]))
426440
}
@@ -598,6 +612,7 @@ impl<'a> Parser<'a> {
598612
args,
599613
over,
600614
distinct,
615+
special: false,
601616
}))
602617
}
603618

@@ -612,6 +627,7 @@ impl<'a> Parser<'a> {
612627
args,
613628
over: None,
614629
distinct: false,
630+
special: false,
615631
}))
616632
}
617633

tests/sqlparser_common.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ fn parse_select_count_wildcard() {
572572
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Wildcard)],
573573
over: None,
574574
distinct: false,
575+
special: false,
575576
}),
576577
expr_from_projection(only(&select.projection))
577578
);
@@ -590,6 +591,7 @@ fn parse_select_count_distinct() {
590591
}))],
591592
over: None,
592593
distinct: true,
594+
special: false,
593595
}),
594596
expr_from_projection(only(&select.projection))
595597
);
@@ -1414,6 +1416,7 @@ fn parse_select_having() {
14141416
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Wildcard)],
14151417
over: None,
14161418
distinct: false,
1419+
special: false,
14171420
})),
14181421
op: BinaryOperator::Gt,
14191422
right: Box::new(Expr::Value(number("1")))
@@ -1445,7 +1448,8 @@ fn parse_select_qualify() {
14451448
}],
14461449
window_frame: None
14471450
}),
1448-
distinct: false
1451+
distinct: false,
1452+
special: false
14491453
})),
14501454
op: BinaryOperator::Eq,
14511455
right: Box::new(Expr::Value(number("1")))
@@ -2532,6 +2536,7 @@ fn parse_scalar_function_in_projection() {
25322536
))],
25332537
over: None,
25342538
distinct: false,
2539+
special: false,
25352540
}),
25362541
expr_from_projection(only(&select.projection))
25372542
);
@@ -2610,6 +2615,7 @@ fn parse_named_argument_function() {
26102615
],
26112616
over: None,
26122617
distinct: false,
2618+
special: false,
26132619
}),
26142620
expr_from_projection(only(&select.projection))
26152621
);
@@ -2643,6 +2649,7 @@ fn parse_window_functions() {
26432649
window_frame: None,
26442650
}),
26452651
distinct: false,
2652+
special: false,
26462653
}),
26472654
expr_from_projection(&select.projection[0])
26482655
);
@@ -2906,7 +2913,8 @@ fn parse_at_timezone() {
29062913
}]),
29072914
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(zero.clone()))],
29082915
over: None,
2909-
distinct: false
2916+
distinct: false,
2917+
special: false,
29102918
})),
29112919
time_zone: "UTC-06:00".to_string()
29122920
},
@@ -2932,6 +2940,7 @@ fn parse_at_timezone() {
29322940
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(zero,),),],
29332941
over: None,
29342942
distinct: false,
2943+
special: false
29352944
},)),
29362945
time_zone: "UTC-06:00".to_string(),
29372946
},),),
@@ -2941,6 +2950,7 @@ fn parse_at_timezone() {
29412950
],
29422951
over: None,
29432952
distinct: false,
2953+
special: false
29442954
},),
29452955
alias: Ident {
29462956
value: "hour".to_string(),
@@ -2976,6 +2986,7 @@ fn parse_table_function() {
29762986
)))],
29772987
over: None,
29782988
distinct: false,
2989+
special: false,
29792990
});
29802991
assert_eq!(expr, expected_expr);
29812992
assert_eq!(alias, table_alias("a"))
@@ -3148,6 +3159,7 @@ fn parse_delimited_identifiers() {
31483159
args: vec![],
31493160
over: None,
31503161
distinct: false,
3162+
special: false,
31513163
}),
31523164
expr_from_projection(&select.projection[1]),
31533165
);
@@ -5125,6 +5137,7 @@ fn parse_time_functions() {
51255137
args: vec![],
51265138
over: None,
51275139
distinct: false,
5140+
special: false,
51285141
}),
51295142
expr_from_projection(&select.projection[0])
51305143
);
@@ -5140,6 +5153,7 @@ fn parse_time_functions() {
51405153
args: vec![],
51415154
over: None,
51425155
distinct: false,
5156+
special: false,
51435157
}),
51445158
expr_from_projection(&select.projection[0])
51455159
);
@@ -5155,6 +5169,7 @@ fn parse_time_functions() {
51555169
args: vec![],
51565170
over: None,
51575171
distinct: false,
5172+
special: false,
51585173
}),
51595174
expr_from_projection(&select.projection[0])
51605175
);

tests/sqlparser_mysql.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,8 @@ fn parse_insert_with_on_duplicate_update() {
686686
Expr::Identifier(Ident::new("description"))
687687
))],
688688
over: None,
689-
distinct: false
689+
distinct: false,
690+
special: false,
690691
})
691692
},
692693
Assignment {
@@ -697,7 +698,8 @@ fn parse_insert_with_on_duplicate_update() {
697698
Expr::Identifier(Ident::new("perm_create"))
698699
))],
699700
over: None,
700-
distinct: false
701+
distinct: false,
702+
special: false,
701703
})
702704
},
703705
Assignment {
@@ -708,7 +710,8 @@ fn parse_insert_with_on_duplicate_update() {
708710
Expr::Identifier(Ident::new("perm_read"))
709711
))],
710712
over: None,
711-
distinct: false
713+
distinct: false,
714+
special: false,
712715
})
713716
},
714717
Assignment {
@@ -719,7 +722,8 @@ fn parse_insert_with_on_duplicate_update() {
719722
Expr::Identifier(Ident::new("perm_update"))
720723
))],
721724
over: None,
722-
distinct: false
725+
distinct: false,
726+
special: false,
723727
})
724728
},
725729
Assignment {
@@ -730,7 +734,8 @@ fn parse_insert_with_on_duplicate_update() {
730734
Expr::Identifier(Ident::new("perm_delete"))
731735
))],
732736
over: None,
733-
distinct: false
737+
distinct: false,
738+
special: false,
734739
})
735740
},
736741
])),

tests/sqlparser_postgres.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,7 @@ fn test_composite_value() {
14001400
)))],
14011401
over: None,
14021402
distinct: false,
1403+
special: false
14031404
}))))
14041405
}),
14051406
select.projection[0]
@@ -1542,6 +1543,52 @@ fn parse_declare() {
15421543
pg_and_generic().verified_stmt("DECLARE \"SQL_CUR0x7fa44801bc00\" BINARY INSENSITIVE SCROLL CURSOR WITH HOLD FOR SELECT * FROM table_name LIMIT 2222");
15431544
}
15441545

1546+
#[test]
1547+
fn parse_current_functions() {
1548+
let sql = "SELECT CURRENT_CATALOG, CURRENT_USER, SESSION_USER, USER";
1549+
let select = pg_and_generic().verified_only_select(sql);
1550+
assert_eq!(
1551+
&Expr::Function(Function {
1552+
name: ObjectName(vec![Ident::new("CURRENT_CATALOG")]),
1553+
args: vec![],
1554+
over: None,
1555+
distinct: false,
1556+
special: true,
1557+
}),
1558+
expr_from_projection(&select.projection[0])
1559+
);
1560+
assert_eq!(
1561+
&Expr::Function(Function {
1562+
name: ObjectName(vec![Ident::new("CURRENT_USER")]),
1563+
args: vec![],
1564+
over: None,
1565+
distinct: false,
1566+
special: true,
1567+
}),
1568+
expr_from_projection(&select.projection[1])
1569+
);
1570+
assert_eq!(
1571+
&Expr::Function(Function {
1572+
name: ObjectName(vec![Ident::new("SESSION_USER")]),
1573+
args: vec![],
1574+
over: None,
1575+
distinct: false,
1576+
special: true,
1577+
}),
1578+
expr_from_projection(&select.projection[2])
1579+
);
1580+
assert_eq!(
1581+
&Expr::Function(Function {
1582+
name: ObjectName(vec![Ident::new("USER")]),
1583+
args: vec![],
1584+
over: None,
1585+
distinct: false,
1586+
special: true,
1587+
}),
1588+
expr_from_projection(&select.projection[3])
1589+
);
1590+
}
1591+
15451592
#[test]
15461593
fn parse_fetch() {
15471594
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)