mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-31 03:07:20 +00:00
Support DROP PROCEDURE
statement (#1324)
Co-authored-by: Andrew Lamb <andrew@nerdnetworks.org>
This commit is contained in:
parent
bbee052890
commit
9f60eb1571
3 changed files with 151 additions and 1 deletions
|
@ -2215,6 +2215,16 @@ pub enum Statement {
|
|||
option: Option<ReferentialAction>,
|
||||
},
|
||||
/// ```sql
|
||||
/// DROP PROCEDURE
|
||||
/// ```
|
||||
DropProcedure {
|
||||
if_exists: bool,
|
||||
/// One or more function to drop
|
||||
proc_desc: Vec<DropFunctionDesc>,
|
||||
/// `CASCADE` or `RESTRICT`
|
||||
option: Option<ReferentialAction>,
|
||||
},
|
||||
/// ```sql
|
||||
/// DROP SECRET
|
||||
/// ```
|
||||
DropSecret {
|
||||
|
@ -3644,6 +3654,22 @@ impl fmt::Display for Statement {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
Statement::DropProcedure {
|
||||
if_exists,
|
||||
proc_desc,
|
||||
option,
|
||||
} => {
|
||||
write!(
|
||||
f,
|
||||
"DROP PROCEDURE{} {}",
|
||||
if *if_exists { " IF EXISTS" } else { "" },
|
||||
display_comma_separated(proc_desc),
|
||||
)?;
|
||||
if let Some(op) = option {
|
||||
write!(f, " {op}")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Statement::DropSecret {
|
||||
if_exists,
|
||||
temporary,
|
||||
|
|
|
@ -4524,11 +4524,13 @@ impl<'a> Parser<'a> {
|
|||
ObjectType::Stage
|
||||
} else if self.parse_keyword(Keyword::FUNCTION) {
|
||||
return self.parse_drop_function();
|
||||
} else if self.parse_keyword(Keyword::PROCEDURE) {
|
||||
return self.parse_drop_procedure();
|
||||
} else if self.parse_keyword(Keyword::SECRET) {
|
||||
return self.parse_drop_secret(temporary, persistent);
|
||||
} else {
|
||||
return self.expected(
|
||||
"TABLE, VIEW, INDEX, ROLE, SCHEMA, FUNCTION, STAGE or SEQUENCE after DROP",
|
||||
"TABLE, VIEW, INDEX, ROLE, SCHEMA, FUNCTION, PROCEDURE, STAGE or SEQUENCE after DROP",
|
||||
self.peek_token(),
|
||||
);
|
||||
};
|
||||
|
@ -4580,6 +4582,26 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
/// ```sql
|
||||
/// DROP PROCEDURE [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...]
|
||||
/// [ CASCADE | RESTRICT ]
|
||||
/// ```
|
||||
fn parse_drop_procedure(&mut self) -> Result<Statement, ParserError> {
|
||||
let if_exists = self.parse_keywords(&[Keyword::IF, Keyword::EXISTS]);
|
||||
let proc_desc = self.parse_comma_separated(Parser::parse_drop_function_desc)?;
|
||||
let option = match self.parse_one_of_keywords(&[Keyword::CASCADE, Keyword::RESTRICT]) {
|
||||
Some(Keyword::CASCADE) => Some(ReferentialAction::Cascade),
|
||||
Some(Keyword::RESTRICT) => Some(ReferentialAction::Restrict),
|
||||
Some(_) => unreachable!(), // parse_one_of_keywords does not return other keywords
|
||||
None => None,
|
||||
};
|
||||
Ok(Statement::DropProcedure {
|
||||
if_exists,
|
||||
proc_desc,
|
||||
option,
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_drop_function_desc(&mut self) -> Result<DropFunctionDesc, ParserError> {
|
||||
let name = self.parse_object_name(false)?;
|
||||
|
||||
|
|
|
@ -3629,6 +3629,108 @@ fn parse_drop_function() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_drop_procedure() {
|
||||
let sql = "DROP PROCEDURE IF EXISTS test_proc";
|
||||
assert_eq!(
|
||||
pg().verified_stmt(sql),
|
||||
Statement::DropProcedure {
|
||||
if_exists: true,
|
||||
proc_desc: vec![DropFunctionDesc {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "test_proc".to_string(),
|
||||
quote_style: None
|
||||
}]),
|
||||
args: None
|
||||
}],
|
||||
option: None
|
||||
}
|
||||
);
|
||||
|
||||
let sql = "DROP PROCEDURE IF EXISTS test_proc(a INTEGER, IN b INTEGER = 1)";
|
||||
assert_eq!(
|
||||
pg().verified_stmt(sql),
|
||||
Statement::DropProcedure {
|
||||
if_exists: true,
|
||||
proc_desc: vec![DropFunctionDesc {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "test_proc".to_string(),
|
||||
quote_style: None
|
||||
}]),
|
||||
args: Some(vec![
|
||||
OperateFunctionArg::with_name("a", DataType::Integer(None)),
|
||||
OperateFunctionArg {
|
||||
mode: Some(ArgMode::In),
|
||||
name: Some("b".into()),
|
||||
data_type: DataType::Integer(None),
|
||||
default_expr: Some(Expr::Value(Value::Number("1".parse().unwrap(), false))),
|
||||
}
|
||||
]),
|
||||
}],
|
||||
option: None
|
||||
}
|
||||
);
|
||||
|
||||
let sql = "DROP PROCEDURE IF EXISTS test_proc1(a INTEGER, IN b INTEGER = 1), test_proc2(a VARCHAR, IN b INTEGER = 1)";
|
||||
assert_eq!(
|
||||
pg().verified_stmt(sql),
|
||||
Statement::DropProcedure {
|
||||
if_exists: true,
|
||||
proc_desc: vec![
|
||||
DropFunctionDesc {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "test_proc1".to_string(),
|
||||
quote_style: None
|
||||
}]),
|
||||
args: Some(vec![
|
||||
OperateFunctionArg::with_name("a", DataType::Integer(None)),
|
||||
OperateFunctionArg {
|
||||
mode: Some(ArgMode::In),
|
||||
name: Some("b".into()),
|
||||
data_type: DataType::Integer(None),
|
||||
default_expr: Some(Expr::Value(Value::Number(
|
||||
"1".parse().unwrap(),
|
||||
false
|
||||
))),
|
||||
}
|
||||
]),
|
||||
},
|
||||
DropFunctionDesc {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "test_proc2".to_string(),
|
||||
quote_style: None
|
||||
}]),
|
||||
args: Some(vec![
|
||||
OperateFunctionArg::with_name("a", DataType::Varchar(None)),
|
||||
OperateFunctionArg {
|
||||
mode: Some(ArgMode::In),
|
||||
name: Some("b".into()),
|
||||
data_type: DataType::Integer(None),
|
||||
default_expr: Some(Expr::Value(Value::Number(
|
||||
"1".parse().unwrap(),
|
||||
false
|
||||
))),
|
||||
}
|
||||
]),
|
||||
}
|
||||
],
|
||||
option: None
|
||||
}
|
||||
);
|
||||
|
||||
let res = pg().parse_sql_statements("DROP PROCEDURE testproc DROP");
|
||||
assert_eq!(
|
||||
ParserError::ParserError("Expected: end of statement, found: DROP".to_string()),
|
||||
res.unwrap_err()
|
||||
);
|
||||
|
||||
let res = pg().parse_sql_statements("DROP PROCEDURE testproc SET NULL");
|
||||
assert_eq!(
|
||||
ParserError::ParserError("Expected: end of statement, found: SET".to_string()),
|
||||
res.unwrap_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_dollar_quoted_string() {
|
||||
let sql = "SELECT $$hello$$, $tag_name$world$tag_name$, $$Foo$Bar$$, $$Foo$Bar$$col_name, $$$$, $tag_name$$tag_name$";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue