Skip to content

Commit 1933f19

Browse files
authored
add support for CALL statements (#1063)
1 parent 8d97330 commit 1933f19

File tree

3 files changed

+89
-11
lines changed

3 files changed

+89
-11
lines changed

src/ast/mod.rs

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,7 @@ pub enum Statement {
14371437
file_format: Option<FileFormat>,
14381438
source: Box<Query>,
14391439
},
1440+
Call(Function),
14401441
Copy {
14411442
/// The source of 'COPY TO', or the target of 'COPY FROM'
14421443
source: CopySource,
@@ -1715,7 +1716,9 @@ pub enum Statement {
17151716
///
17161717
/// Note: this is a PostgreSQL-specific statement,
17171718
/// but may also compatible with other SQL.
1718-
Discard { object_type: DiscardObject },
1719+
Discard {
1720+
object_type: DiscardObject,
1721+
},
17191722
/// SET `[ SESSION | LOCAL ]` ROLE role_name. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4].
17201723
///
17211724
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
@@ -1747,7 +1750,10 @@ pub enum Statement {
17471750
///
17481751
/// Note: this is a PostgreSQL-specific statements
17491752
/// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
1750-
SetTimeZone { local: bool, value: Expr },
1753+
SetTimeZone {
1754+
local: bool,
1755+
value: Expr,
1756+
},
17511757
/// SET NAMES 'charset_name' [COLLATE 'collation_name']
17521758
///
17531759
/// Note: this is a MySQL-specific statement.
@@ -1762,13 +1768,17 @@ pub enum Statement {
17621768
/// SHOW FUNCTIONS
17631769
///
17641770
/// Note: this is a Presto-specific statement.
1765-
ShowFunctions { filter: Option<ShowStatementFilter> },
1771+
ShowFunctions {
1772+
filter: Option<ShowStatementFilter>,
1773+
},
17661774
/// ```sql
17671775
/// SHOW <variable>
17681776
/// ```
17691777
///
17701778
/// Note: this is a PostgreSQL-specific statement.
1771-
ShowVariable { variable: Vec<Ident> },
1779+
ShowVariable {
1780+
variable: Vec<Ident>,
1781+
},
17721782
/// SHOW VARIABLES
17731783
///
17741784
/// Note: this is a MySQL-specific statement.
@@ -1806,11 +1816,15 @@ pub enum Statement {
18061816
/// SHOW COLLATION
18071817
///
18081818
/// Note: this is a MySQL-specific statement.
1809-
ShowCollation { filter: Option<ShowStatementFilter> },
1819+
ShowCollation {
1820+
filter: Option<ShowStatementFilter>,
1821+
},
18101822
/// USE
18111823
///
18121824
/// Note: This is a MySQL-specific statement.
1813-
Use { db_name: Ident },
1825+
Use {
1826+
db_name: Ident,
1827+
},
18141828
/// `START [ TRANSACTION | WORK ] | START TRANSACTION } ...`
18151829
/// If `begin` is false.
18161830
///
@@ -1838,7 +1852,9 @@ pub enum Statement {
18381852
if_exists: bool,
18391853
},
18401854
/// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
1841-
Commit { chain: bool },
1855+
Commit {
1856+
chain: bool,
1857+
},
18421858
/// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]`
18431859
Rollback {
18441860
chain: bool,
@@ -1934,11 +1950,17 @@ pub enum Statement {
19341950
/// `DEALLOCATE [ PREPARE ] { name | ALL }`
19351951
///
19361952
/// Note: this is a PostgreSQL-specific statement.
1937-
Deallocate { name: Ident, prepare: bool },
1953+
Deallocate {
1954+
name: Ident,
1955+
prepare: bool,
1956+
},
19381957
/// `EXECUTE name [ ( parameter [, ...] ) ]`
19391958
///
19401959
/// Note: this is a PostgreSQL-specific statement.
1941-
Execute { name: Ident, parameters: Vec<Expr> },
1960+
Execute {
1961+
name: Ident,
1962+
parameters: Vec<Expr>,
1963+
},
19421964
/// `PREPARE name [ ( data_type [, ...] ) ] AS statement`
19431965
///
19441966
/// Note: this is a PostgreSQL-specific statement.
@@ -1979,9 +2001,13 @@ pub enum Statement {
19792001
format: Option<AnalyzeFormat>,
19802002
},
19812003
/// SAVEPOINT -- define a new savepoint within the current transaction
1982-
Savepoint { name: Ident },
2004+
Savepoint {
2005+
name: Ident,
2006+
},
19832007
/// RELEASE \[ SAVEPOINT \] savepoint_name
1984-
ReleaseSavepoint { name: Ident },
2008+
ReleaseSavepoint {
2009+
name: Ident,
2010+
},
19852011
// MERGE INTO statement, based on Snowflake. See <https://docs.snowflake.com/en/sql-reference/sql/merge.html>
19862012
Merge {
19872013
// optional INTO keyword
@@ -2303,6 +2329,8 @@ impl fmt::Display for Statement {
23032329
Ok(())
23042330
}
23052331

2332+
Statement::Call(function) => write!(f, "CALL {function}"),
2333+
23062334
Statement::Copy {
23072335
source,
23082336
to,

src/parser/mod.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ impl<'a> Parser<'a> {
493493
Keyword::UNCACHE => Ok(self.parse_uncache_table()?),
494494
Keyword::UPDATE => Ok(self.parse_update()?),
495495
Keyword::ALTER => Ok(self.parse_alter()?),
496+
Keyword::CALL => Ok(self.parse_call()?),
496497
Keyword::COPY => Ok(self.parse_copy()?),
497498
Keyword::CLOSE => Ok(self.parse_close()?),
498499
Keyword::SET => Ok(self.parse_set()?),
@@ -4773,6 +4774,32 @@ impl<'a> Parser<'a> {
47734774
})
47744775
}
47754776

4777+
/// Parse a `CALL procedure_name(arg1, arg2, ...)`
4778+
/// or `CALL procedure_name` statement
4779+
pub fn parse_call(&mut self) -> Result<Statement, ParserError> {
4780+
let object_name = self.parse_object_name()?;
4781+
if self.peek_token().token == Token::LParen {
4782+
match self.parse_function(object_name)? {
4783+
Expr::Function(f) => Ok(Statement::Call(f)),
4784+
other => parser_err!(
4785+
format!("Expected a simple procedure call but found: {other}"),
4786+
self.peek_token().location
4787+
),
4788+
}
4789+
} else {
4790+
Ok(Statement::Call(Function {
4791+
name: object_name,
4792+
args: vec![],
4793+
over: None,
4794+
distinct: false,
4795+
filter: None,
4796+
null_treatment: None,
4797+
special: true,
4798+
order_by: vec![],
4799+
}))
4800+
}
4801+
}
4802+
47764803
/// Parse a copy statement
47774804
pub fn parse_copy(&mut self) -> Result<Statement, ParserError> {
47784805
let source;

tests/sqlparser_common.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7949,6 +7949,29 @@ fn parse_create_type() {
79497949
);
79507950
}
79517951

7952+
#[test]
7953+
fn parse_call() {
7954+
all_dialects().verified_stmt("CALL my_procedure()");
7955+
all_dialects().verified_stmt("CALL my_procedure(1, 'a')");
7956+
pg_and_generic().verified_stmt("CALL my_procedure(1, 'a', $1)");
7957+
all_dialects().verified_stmt("CALL my_procedure");
7958+
assert_eq!(
7959+
verified_stmt("CALL my_procedure('a')"),
7960+
Statement::Call(Function {
7961+
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
7962+
Value::SingleQuotedString("a".to_string())
7963+
))),],
7964+
name: ObjectName(vec![Ident::new("my_procedure")]),
7965+
filter: None,
7966+
null_treatment: None,
7967+
over: None,
7968+
distinct: false,
7969+
special: false,
7970+
order_by: vec![]
7971+
})
7972+
);
7973+
}
7974+
79527975
#[test]
79537976
fn parse_create_table_collate() {
79547977
pg_and_generic().verified_stmt("CREATE TABLE tbl (foo INT, bar TEXT COLLATE \"de_DE\")");

0 commit comments

Comments
 (0)