Skip to content

Commit 7ccce5a

Browse files
committed
drop function
1 parent 650c53d commit 7ccce5a

File tree

3 files changed

+180
-13
lines changed

3 files changed

+180
-13
lines changed

src/ast/mod.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,14 @@ pub enum Statement {
12471247
/// deleted along with the dropped table
12481248
purge: bool,
12491249
},
1250+
/// DROP Function
1251+
DropFunction {
1252+
if_exists: bool,
1253+
/// One or more function to drop
1254+
func_desc: Vec<DropFunctionDesc>,
1255+
cascade: bool,
1256+
restrict: bool,
1257+
},
12501258
/// DECLARE - Declaring Cursor Variables
12511259
///
12521260
/// Note: this is a PostgreSQL-specific statement,
@@ -1411,7 +1419,7 @@ pub enum Statement {
14111419
or_replace: bool,
14121420
temporary: bool,
14131421
name: ObjectName,
1414-
args: Option<Vec<CreateFunctionArg>>,
1422+
args: Option<Vec<OperateFunctionArg>>,
14151423
return_type: Option<DataType>,
14161424
/// Optional parameters.
14171425
params: CreateFunctionBody,
@@ -2263,6 +2271,19 @@ impl fmt::Display for Statement {
22632271
if *restrict { " RESTRICT" } else { "" },
22642272
if *purge { " PURGE" } else { "" }
22652273
),
2274+
Statement::DropFunction {
2275+
if_exists,
2276+
func_desc,
2277+
cascade,
2278+
restrict,
2279+
} => write!(
2280+
f,
2281+
"DROP FUNCTION{} {}{}{}",
2282+
if *if_exists { " IF EXISTS" } else { "" },
2283+
display_comma_separated(func_desc),
2284+
if *cascade { " CASCADE" } else { "" },
2285+
if *restrict { " RESTRICT" } else { "" }
2286+
),
22662287
Statement::Discard { object_type } => {
22672288
write!(f, "DISCARD {object_type}", object_type = object_type)?;
22682289
Ok(())
@@ -3691,17 +3712,35 @@ impl fmt::Display for ContextModifier {
36913712
}
36923713
}
36933714

3694-
/// Function argument in CREATE FUNCTION.
3715+
/// Function describe in DROP FUNCTION.
3716+
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
3717+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3718+
pub struct DropFunctionDesc {
3719+
pub name: ObjectName,
3720+
pub args: Option<Vec<OperateFunctionArg>>,
3721+
}
3722+
3723+
impl fmt::Display for DropFunctionDesc {
3724+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3725+
write!(f, "{}", self.name)?;
3726+
if let Some(args) = &self.args {
3727+
write!(f, "({})", display_comma_separated(args))?;
3728+
}
3729+
Ok(())
3730+
}
3731+
}
3732+
3733+
/// Function argument in CREATE OR DROP FUNCTION.
36953734
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
36963735
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3697-
pub struct CreateFunctionArg {
3736+
pub struct OperateFunctionArg {
36983737
pub mode: Option<ArgMode>,
36993738
pub name: Option<Ident>,
37003739
pub data_type: DataType,
37013740
pub default_expr: Option<Expr>,
37023741
}
37033742

3704-
impl CreateFunctionArg {
3743+
impl OperateFunctionArg {
37053744
/// Returns an unnamed argument.
37063745
pub fn unnamed(data_type: DataType) -> Self {
37073746
Self {
@@ -3723,7 +3762,7 @@ impl CreateFunctionArg {
37233762
}
37243763
}
37253764

3726-
impl fmt::Display for CreateFunctionArg {
3765+
impl fmt::Display for OperateFunctionArg {
37273766
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
37283767
if let Some(mode) = &self.mode {
37293768
write!(f, "{} ", mode)?;

src/parser.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,7 +2328,7 @@ impl<'a> Parser<'a> {
23282328
} else if dialect_of!(self is PostgreSqlDialect) {
23292329
let name = self.parse_object_name()?;
23302330
self.expect_token(&Token::LParen)?;
2331-
let args = self.parse_comma_separated(Parser::parse_create_function_arg)?;
2331+
let args = self.parse_comma_separated(Parser::parse_function_arg)?;
23322332
self.expect_token(&Token::RParen)?;
23332333

23342334
let return_type = if self.parse_keyword(Keyword::RETURNS) {
@@ -2353,7 +2353,7 @@ impl<'a> Parser<'a> {
23532353
}
23542354
}
23552355

2356-
fn parse_create_function_arg(&mut self) -> Result<CreateFunctionArg, ParserError> {
2356+
fn parse_function_arg(&mut self) -> Result<OperateFunctionArg, ParserError> {
23572357
let mode = if self.parse_keyword(Keyword::IN) {
23582358
Some(ArgMode::In)
23592359
} else if self.parse_keyword(Keyword::OUT) {
@@ -2379,7 +2379,7 @@ impl<'a> Parser<'a> {
23792379
} else {
23802380
None
23812381
};
2382-
Ok(CreateFunctionArg {
2382+
Ok(OperateFunctionArg {
23832383
mode,
23842384
name,
23852385
data_type,
@@ -2752,9 +2752,11 @@ impl<'a> Parser<'a> {
27522752
ObjectType::Schema
27532753
} else if self.parse_keyword(Keyword::SEQUENCE) {
27542754
ObjectType::Sequence
2755+
} else if self.parse_keyword(Keyword::FUNCTION) {
2756+
return self.parse_drop_function();
27552757
} else {
27562758
return self.expected(
2757-
"TABLE, VIEW, INDEX, ROLE, SCHEMA, or SEQUENCE after DROP",
2759+
"TABLE, VIEW, INDEX, ROLE, SCHEMA, FUNCTION or SEQUENCE after DROP",
27582760
self.peek_token(),
27592761
);
27602762
};
@@ -2781,6 +2783,39 @@ impl<'a> Parser<'a> {
27812783
})
27822784
}
27832785

2786+
/// DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
2787+
/// [ CASCADE | RESTRICT ]
2788+
fn parse_drop_function(&mut self) -> Result<Statement, ParserError> {
2789+
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
2790+
let func_desc = self.parse_comma_separated(Parser::parse_drop_function_desc)?;
2791+
let cascade = self.parse_keyword(Keyword::CASCADE);
2792+
let restrict = self.parse_keyword(Keyword::RESTRICT);
2793+
Ok(Statement::DropFunction {
2794+
if_exists,
2795+
func_desc,
2796+
cascade,
2797+
restrict,
2798+
})
2799+
}
2800+
2801+
fn parse_drop_function_desc(&mut self) -> Result<DropFunctionDesc, ParserError> {
2802+
let name = self.parse_object_name()?;
2803+
2804+
let args = if self.consume_token(&Token::LParen) {
2805+
if self.consume_token(&Token::RParen) {
2806+
None
2807+
} else {
2808+
let args = self.parse_comma_separated(Parser::parse_function_arg)?;
2809+
self.expect_token(&Token::RParen)?;
2810+
Some(args)
2811+
}
2812+
} else {
2813+
None
2814+
};
2815+
2816+
Ok(DropFunctionDesc { name, args })
2817+
}
2818+
27842819
/// DECLARE name [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
27852820
// CURSOR [ { WITH | WITHOUT } HOLD ] FOR query
27862821
pub fn parse_declare(&mut self) -> Result<Statement, ParserError> {

tests/sqlparser_postgres.rs

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,8 +2250,8 @@ fn parse_create_function() {
22502250
temporary: false,
22512251
name: ObjectName(vec![Ident::new("add")]),
22522252
args: Some(vec![
2253-
CreateFunctionArg::unnamed(DataType::Integer(None)),
2254-
CreateFunctionArg::unnamed(DataType::Integer(None)),
2253+
OperateFunctionArg::unnamed(DataType::Integer(None)),
2254+
OperateFunctionArg::unnamed(DataType::Integer(None)),
22552255
]),
22562256
return_type: Some(DataType::Integer(None)),
22572257
params: CreateFunctionBody {
@@ -2271,8 +2271,8 @@ fn parse_create_function() {
22712271
temporary: false,
22722272
name: ObjectName(vec![Ident::new("add")]),
22732273
args: Some(vec![
2274-
CreateFunctionArg::with_name("a", DataType::Integer(None)),
2275-
CreateFunctionArg {
2274+
OperateFunctionArg::with_name("a", DataType::Integer(None)),
2275+
OperateFunctionArg {
22762276
mode: Some(ArgMode::In),
22772277
name: Some("b".into()),
22782278
data_type: DataType::Integer(None),
@@ -2293,3 +2293,96 @@ fn parse_create_function() {
22932293
}
22942294
);
22952295
}
2296+
2297+
#[test]
2298+
fn parse_drop_function() {
2299+
let sql = "DROP FUNCTION IF EXISTS test_func";
2300+
assert_eq!(
2301+
pg().verified_stmt(sql),
2302+
Statement::DropFunction {
2303+
if_exists: true,
2304+
func_desc: vec![DropFunctionDesc {
2305+
name: ObjectName(vec![Ident {
2306+
value: "test_func".to_string(),
2307+
quote_style: None
2308+
}]),
2309+
args: None
2310+
}],
2311+
cascade: false,
2312+
restrict: false
2313+
}
2314+
);
2315+
2316+
let sql = "DROP FUNCTION IF EXISTS test_func(a INTEGER, IN b INTEGER = 1)";
2317+
assert_eq!(
2318+
pg().verified_stmt(sql),
2319+
Statement::DropFunction {
2320+
if_exists: true,
2321+
func_desc: vec![DropFunctionDesc {
2322+
name: ObjectName(vec![Ident {
2323+
value: "test_func".to_string(),
2324+
quote_style: None
2325+
}]),
2326+
args: Some(vec![
2327+
OperateFunctionArg::with_name("a", DataType::Integer(None)),
2328+
OperateFunctionArg {
2329+
mode: Some(ArgMode::In),
2330+
name: Some("b".into()),
2331+
data_type: DataType::Integer(None),
2332+
default_expr: Some(Expr::Value(Value::Number("1".parse().unwrap(), false))),
2333+
}
2334+
]),
2335+
}],
2336+
cascade: false,
2337+
restrict: false
2338+
}
2339+
);
2340+
2341+
let sql = "DROP FUNCTION IF EXISTS test_func1(a INTEGER, IN b INTEGER = 1), test_func2(a VARCHAR, IN b INTEGER = 1)";
2342+
assert_eq!(
2343+
pg().verified_stmt(sql),
2344+
Statement::DropFunction {
2345+
if_exists: true,
2346+
func_desc: vec![
2347+
DropFunctionDesc {
2348+
name: ObjectName(vec![Ident {
2349+
value: "test_func1".to_string(),
2350+
quote_style: None
2351+
}]),
2352+
args: Some(vec![
2353+
OperateFunctionArg::with_name("a", DataType::Integer(None)),
2354+
OperateFunctionArg {
2355+
mode: Some(ArgMode::In),
2356+
name: Some("b".into()),
2357+
data_type: DataType::Integer(None),
2358+
default_expr: Some(Expr::Value(Value::Number(
2359+
"1".parse().unwrap(),
2360+
false
2361+
))),
2362+
}
2363+
]),
2364+
},
2365+
DropFunctionDesc {
2366+
name: ObjectName(vec![Ident {
2367+
value: "test_func2".to_string(),
2368+
quote_style: None
2369+
}]),
2370+
args: Some(vec![
2371+
OperateFunctionArg::with_name("a", DataType::Varchar(None)),
2372+
OperateFunctionArg {
2373+
mode: Some(ArgMode::In),
2374+
name: Some("b".into()),
2375+
data_type: DataType::Integer(None),
2376+
default_expr: Some(Expr::Value(Value::Number(
2377+
"1".parse().unwrap(),
2378+
false
2379+
))),
2380+
}
2381+
]),
2382+
}
2383+
],
2384+
cascade: false,
2385+
restrict: false
2386+
}
2387+
);
2388+
}

0 commit comments

Comments
 (0)