Skip to content

Commit 9f60eb1

Browse files
Support DROP PROCEDURE statement (#1324)
Co-authored-by: Andrew Lamb <[email protected]>
1 parent bbee052 commit 9f60eb1

File tree

3 files changed

+151
-1
lines changed

3 files changed

+151
-1
lines changed

src/ast/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2215,6 +2215,16 @@ pub enum Statement {
22152215
option: Option<ReferentialAction>,
22162216
},
22172217
/// ```sql
2218+
/// DROP PROCEDURE
2219+
/// ```
2220+
DropProcedure {
2221+
if_exists: bool,
2222+
/// One or more function to drop
2223+
proc_desc: Vec<DropFunctionDesc>,
2224+
/// `CASCADE` or `RESTRICT`
2225+
option: Option<ReferentialAction>,
2226+
},
2227+
/// ```sql
22182228
/// DROP SECRET
22192229
/// ```
22202230
DropSecret {
@@ -3644,6 +3654,22 @@ impl fmt::Display for Statement {
36443654
}
36453655
Ok(())
36463656
}
3657+
Statement::DropProcedure {
3658+
if_exists,
3659+
proc_desc,
3660+
option,
3661+
} => {
3662+
write!(
3663+
f,
3664+
"DROP PROCEDURE{} {}",
3665+
if *if_exists { " IF EXISTS" } else { "" },
3666+
display_comma_separated(proc_desc),
3667+
)?;
3668+
if let Some(op) = option {
3669+
write!(f, " {op}")?;
3670+
}
3671+
Ok(())
3672+
}
36473673
Statement::DropSecret {
36483674
if_exists,
36493675
temporary,

src/parser/mod.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4524,11 +4524,13 @@ impl<'a> Parser<'a> {
45244524
ObjectType::Stage
45254525
} else if self.parse_keyword(Keyword::FUNCTION) {
45264526
return self.parse_drop_function();
4527+
} else if self.parse_keyword(Keyword::PROCEDURE) {
4528+
return self.parse_drop_procedure();
45274529
} else if self.parse_keyword(Keyword::SECRET) {
45284530
return self.parse_drop_secret(temporary, persistent);
45294531
} else {
45304532
return self.expected(
4531-
"TABLE, VIEW, INDEX, ROLE, SCHEMA, FUNCTION, STAGE or SEQUENCE after DROP",
4533+
"TABLE, VIEW, INDEX, ROLE, SCHEMA, FUNCTION, PROCEDURE, STAGE or SEQUENCE after DROP",
45324534
self.peek_token(),
45334535
);
45344536
};
@@ -4580,6 +4582,26 @@ impl<'a> Parser<'a> {
45804582
})
45814583
}
45824584

4585+
/// ```sql
4586+
/// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
4587+
/// [ CASCADE | RESTRICT ]
4588+
/// ```
4589+
fn parse_drop_procedure(&mut self) -> Result<Statement, ParserError> {
4590+
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
4591+
let proc_desc = self.parse_comma_separated(Parser::parse_drop_function_desc)?;
4592+
let option = match self.parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT]) {
4593+
Some(Keyword::CASCADE) => Some(ReferentialAction::Cascade),
4594+
Some(Keyword::RESTRICT) => Some(ReferentialAction::Restrict),
4595+
Some(_) => unreachable!(), // parse_one_of_keywords does not return other keywords
4596+
None => None,
4597+
};
4598+
Ok(Statement::DropProcedure {
4599+
if_exists,
4600+
proc_desc,
4601+
option,
4602+
})
4603+
}
4604+
45834605
fn parse_drop_function_desc(&mut self) -> Result<DropFunctionDesc, ParserError> {
45844606
let name = self.parse_object_name(false)?;
45854607

tests/sqlparser_postgres.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3629,6 +3629,108 @@ fn parse_drop_function() {
36293629
);
36303630
}
36313631

3632+
#[test]
3633+
fn parse_drop_procedure() {
3634+
let sql = "DROP PROCEDURE IF EXISTS test_proc";
3635+
assert_eq!(
3636+
pg().verified_stmt(sql),
3637+
Statement::DropProcedure {
3638+
if_exists: true,
3639+
proc_desc: vec![DropFunctionDesc {
3640+
name: ObjectName(vec![Ident {
3641+
value: "test_proc".to_string(),
3642+
quote_style: None
3643+
}]),
3644+
args: None
3645+
}],
3646+
option: None
3647+
}
3648+
);
3649+
3650+
let sql = "DROP PROCEDURE IF EXISTS test_proc(a INTEGER, IN b INTEGER = 1)";
3651+
assert_eq!(
3652+
pg().verified_stmt(sql),
3653+
Statement::DropProcedure {
3654+
if_exists: true,
3655+
proc_desc: vec![DropFunctionDesc {
3656+
name: ObjectName(vec![Ident {
3657+
value: "test_proc".to_string(),
3658+
quote_style: None
3659+
}]),
3660+
args: Some(vec![
3661+
OperateFunctionArg::with_name("a", DataType::Integer(None)),
3662+
OperateFunctionArg {
3663+
mode: Some(ArgMode::In),
3664+
name: Some("b".into()),
3665+
data_type: DataType::Integer(None),
3666+
default_expr: Some(Expr::Value(Value::Number("1".parse().unwrap(), false))),
3667+
}
3668+
]),
3669+
}],
3670+
option: None
3671+
}
3672+
);
3673+
3674+
let sql = "DROP PROCEDURE IF EXISTS test_proc1(a INTEGER, IN b INTEGER = 1), test_proc2(a VARCHAR, IN b INTEGER = 1)";
3675+
assert_eq!(
3676+
pg().verified_stmt(sql),
3677+
Statement::DropProcedure {
3678+
if_exists: true,
3679+
proc_desc: vec![
3680+
DropFunctionDesc {
3681+
name: ObjectName(vec![Ident {
3682+
value: "test_proc1".to_string(),
3683+
quote_style: None
3684+
}]),
3685+
args: Some(vec![
3686+
OperateFunctionArg::with_name("a", DataType::Integer(None)),
3687+
OperateFunctionArg {
3688+
mode: Some(ArgMode::In),
3689+
name: Some("b".into()),
3690+
data_type: DataType::Integer(None),
3691+
default_expr: Some(Expr::Value(Value::Number(
3692+
"1".parse().unwrap(),
3693+
false
3694+
))),
3695+
}
3696+
]),
3697+
},
3698+
DropFunctionDesc {
3699+
name: ObjectName(vec![Ident {
3700+
value: "test_proc2".to_string(),
3701+
quote_style: None
3702+
}]),
3703+
args: Some(vec![
3704+
OperateFunctionArg::with_name("a", DataType::Varchar(None)),
3705+
OperateFunctionArg {
3706+
mode: Some(ArgMode::In),
3707+
name: Some("b".into()),
3708+
data_type: DataType::Integer(None),
3709+
default_expr: Some(Expr::Value(Value::Number(
3710+
"1".parse().unwrap(),
3711+
false
3712+
))),
3713+
}
3714+
]),
3715+
}
3716+
],
3717+
option: None
3718+
}
3719+
);
3720+
3721+
let res = pg().parse_sql_statements("DROP PROCEDURE testproc DROP");
3722+
assert_eq!(
3723+
ParserError::ParserError("Expected: end of statement, found: DROP".to_string()),
3724+
res.unwrap_err()
3725+
);
3726+
3727+
let res = pg().parse_sql_statements("DROP PROCEDURE testproc SET NULL");
3728+
assert_eq!(
3729+
ParserError::ParserError("Expected: end of statement, found: SET".to_string()),
3730+
res.unwrap_err()
3731+
);
3732+
}
3733+
36323734
#[test]
36333735
fn parse_dollar_quoted_string() {
36343736
let sql = "SELECT $$hello$$, $tag_name$world$tag_name$, $$Foo$Bar$$, $$Foo$Bar$$col_name, $$$$, $tag_name$$tag_name$";

0 commit comments

Comments
 (0)