mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-03 13:58:15 +00:00
add support for CALL statements (#1063)
This commit is contained in:
parent
8d97330d42
commit
1933f194e7
3 changed files with 89 additions and 11 deletions
|
@ -1437,6 +1437,7 @@ pub enum Statement {
|
||||||
file_format: Option<FileFormat>,
|
file_format: Option<FileFormat>,
|
||||||
source: Box<Query>,
|
source: Box<Query>,
|
||||||
},
|
},
|
||||||
|
Call(Function),
|
||||||
Copy {
|
Copy {
|
||||||
/// The source of 'COPY TO', or the target of 'COPY FROM'
|
/// The source of 'COPY TO', or the target of 'COPY FROM'
|
||||||
source: CopySource,
|
source: CopySource,
|
||||||
|
@ -1715,7 +1716,9 @@ pub enum Statement {
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific statement,
|
/// Note: this is a PostgreSQL-specific statement,
|
||||||
/// but may also compatible with other SQL.
|
/// but may also compatible with other SQL.
|
||||||
Discard { object_type: DiscardObject },
|
Discard {
|
||||||
|
object_type: DiscardObject,
|
||||||
|
},
|
||||||
/// SET `[ SESSION | LOCAL ]` ROLE role_name. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4].
|
/// SET `[ SESSION | LOCAL ]` ROLE role_name. Examples: [ANSI][1], [Postgresql][2], [MySQL][3], and [Oracle][4].
|
||||||
///
|
///
|
||||||
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
|
/// [1]: https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#set-role-statement
|
||||||
|
@ -1747,7 +1750,10 @@ pub enum Statement {
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific statements
|
/// Note: this is a PostgreSQL-specific statements
|
||||||
/// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
|
/// `SET TIME ZONE <value>` is an alias for `SET timezone TO <value>` in PostgreSQL
|
||||||
SetTimeZone { local: bool, value: Expr },
|
SetTimeZone {
|
||||||
|
local: bool,
|
||||||
|
value: Expr,
|
||||||
|
},
|
||||||
/// SET NAMES 'charset_name' [COLLATE 'collation_name']
|
/// SET NAMES 'charset_name' [COLLATE 'collation_name']
|
||||||
///
|
///
|
||||||
/// Note: this is a MySQL-specific statement.
|
/// Note: this is a MySQL-specific statement.
|
||||||
|
@ -1762,13 +1768,17 @@ pub enum Statement {
|
||||||
/// SHOW FUNCTIONS
|
/// SHOW FUNCTIONS
|
||||||
///
|
///
|
||||||
/// Note: this is a Presto-specific statement.
|
/// Note: this is a Presto-specific statement.
|
||||||
ShowFunctions { filter: Option<ShowStatementFilter> },
|
ShowFunctions {
|
||||||
|
filter: Option<ShowStatementFilter>,
|
||||||
|
},
|
||||||
/// ```sql
|
/// ```sql
|
||||||
/// SHOW <variable>
|
/// SHOW <variable>
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific statement.
|
/// Note: this is a PostgreSQL-specific statement.
|
||||||
ShowVariable { variable: Vec<Ident> },
|
ShowVariable {
|
||||||
|
variable: Vec<Ident>,
|
||||||
|
},
|
||||||
/// SHOW VARIABLES
|
/// SHOW VARIABLES
|
||||||
///
|
///
|
||||||
/// Note: this is a MySQL-specific statement.
|
/// Note: this is a MySQL-specific statement.
|
||||||
|
@ -1806,11 +1816,15 @@ pub enum Statement {
|
||||||
/// SHOW COLLATION
|
/// SHOW COLLATION
|
||||||
///
|
///
|
||||||
/// Note: this is a MySQL-specific statement.
|
/// Note: this is a MySQL-specific statement.
|
||||||
ShowCollation { filter: Option<ShowStatementFilter> },
|
ShowCollation {
|
||||||
|
filter: Option<ShowStatementFilter>,
|
||||||
|
},
|
||||||
/// USE
|
/// USE
|
||||||
///
|
///
|
||||||
/// Note: This is a MySQL-specific statement.
|
/// Note: This is a MySQL-specific statement.
|
||||||
Use { db_name: Ident },
|
Use {
|
||||||
|
db_name: Ident,
|
||||||
|
},
|
||||||
/// `START [ TRANSACTION | WORK ] | START TRANSACTION } ...`
|
/// `START [ TRANSACTION | WORK ] | START TRANSACTION } ...`
|
||||||
/// If `begin` is false.
|
/// If `begin` is false.
|
||||||
///
|
///
|
||||||
|
@ -1838,7 +1852,9 @@ pub enum Statement {
|
||||||
if_exists: bool,
|
if_exists: bool,
|
||||||
},
|
},
|
||||||
/// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
|
/// `COMMIT [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ]`
|
||||||
Commit { chain: bool },
|
Commit {
|
||||||
|
chain: bool,
|
||||||
|
},
|
||||||
/// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]`
|
/// `ROLLBACK [ TRANSACTION | WORK ] [ AND [ NO ] CHAIN ] [ TO [ SAVEPOINT ] savepoint_name ]`
|
||||||
Rollback {
|
Rollback {
|
||||||
chain: bool,
|
chain: bool,
|
||||||
|
@ -1934,11 +1950,17 @@ pub enum Statement {
|
||||||
/// `DEALLOCATE [ PREPARE ] { name | ALL }`
|
/// `DEALLOCATE [ PREPARE ] { name | ALL }`
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific statement.
|
/// Note: this is a PostgreSQL-specific statement.
|
||||||
Deallocate { name: Ident, prepare: bool },
|
Deallocate {
|
||||||
|
name: Ident,
|
||||||
|
prepare: bool,
|
||||||
|
},
|
||||||
/// `EXECUTE name [ ( parameter [, ...] ) ]`
|
/// `EXECUTE name [ ( parameter [, ...] ) ]`
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific statement.
|
/// Note: this is a PostgreSQL-specific statement.
|
||||||
Execute { name: Ident, parameters: Vec<Expr> },
|
Execute {
|
||||||
|
name: Ident,
|
||||||
|
parameters: Vec<Expr>,
|
||||||
|
},
|
||||||
/// `PREPARE name [ ( data_type [, ...] ) ] AS statement`
|
/// `PREPARE name [ ( data_type [, ...] ) ] AS statement`
|
||||||
///
|
///
|
||||||
/// Note: this is a PostgreSQL-specific statement.
|
/// Note: this is a PostgreSQL-specific statement.
|
||||||
|
@ -1979,9 +2001,13 @@ pub enum Statement {
|
||||||
format: Option<AnalyzeFormat>,
|
format: Option<AnalyzeFormat>,
|
||||||
},
|
},
|
||||||
/// SAVEPOINT -- define a new savepoint within the current transaction
|
/// SAVEPOINT -- define a new savepoint within the current transaction
|
||||||
Savepoint { name: Ident },
|
Savepoint {
|
||||||
|
name: Ident,
|
||||||
|
},
|
||||||
/// RELEASE \[ SAVEPOINT \] savepoint_name
|
/// RELEASE \[ SAVEPOINT \] savepoint_name
|
||||||
ReleaseSavepoint { name: Ident },
|
ReleaseSavepoint {
|
||||||
|
name: Ident,
|
||||||
|
},
|
||||||
// MERGE INTO statement, based on Snowflake. See <https://docs.snowflake.com/en/sql-reference/sql/merge.html>
|
// MERGE INTO statement, based on Snowflake. See <https://docs.snowflake.com/en/sql-reference/sql/merge.html>
|
||||||
Merge {
|
Merge {
|
||||||
// optional INTO keyword
|
// optional INTO keyword
|
||||||
|
@ -2303,6 +2329,8 @@ impl fmt::Display for Statement {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Statement::Call(function) => write!(f, "CALL {function}"),
|
||||||
|
|
||||||
Statement::Copy {
|
Statement::Copy {
|
||||||
source,
|
source,
|
||||||
to,
|
to,
|
||||||
|
|
|
@ -493,6 +493,7 @@ impl<'a> Parser<'a> {
|
||||||
Keyword::UNCACHE => Ok(self.parse_uncache_table()?),
|
Keyword::UNCACHE => Ok(self.parse_uncache_table()?),
|
||||||
Keyword::UPDATE => Ok(self.parse_update()?),
|
Keyword::UPDATE => Ok(self.parse_update()?),
|
||||||
Keyword::ALTER => Ok(self.parse_alter()?),
|
Keyword::ALTER => Ok(self.parse_alter()?),
|
||||||
|
Keyword::CALL => Ok(self.parse_call()?),
|
||||||
Keyword::COPY => Ok(self.parse_copy()?),
|
Keyword::COPY => Ok(self.parse_copy()?),
|
||||||
Keyword::CLOSE => Ok(self.parse_close()?),
|
Keyword::CLOSE => Ok(self.parse_close()?),
|
||||||
Keyword::SET => Ok(self.parse_set()?),
|
Keyword::SET => Ok(self.parse_set()?),
|
||||||
|
@ -4773,6 +4774,32 @@ impl<'a> Parser<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a `CALL procedure_name(arg1, arg2, ...)`
|
||||||
|
/// or `CALL procedure_name` statement
|
||||||
|
pub fn parse_call(&mut self) -> Result<Statement, ParserError> {
|
||||||
|
let object_name = self.parse_object_name()?;
|
||||||
|
if self.peek_token().token == Token::LParen {
|
||||||
|
match self.parse_function(object_name)? {
|
||||||
|
Expr::Function(f) => Ok(Statement::Call(f)),
|
||||||
|
other => parser_err!(
|
||||||
|
format!("Expected a simple procedure call but found: {other}"),
|
||||||
|
self.peek_token().location
|
||||||
|
),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(Statement::Call(Function {
|
||||||
|
name: object_name,
|
||||||
|
args: vec![],
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
filter: None,
|
||||||
|
null_treatment: None,
|
||||||
|
special: true,
|
||||||
|
order_by: vec![],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a copy statement
|
/// Parse a copy statement
|
||||||
pub fn parse_copy(&mut self) -> Result<Statement, ParserError> {
|
pub fn parse_copy(&mut self) -> Result<Statement, ParserError> {
|
||||||
let source;
|
let source;
|
||||||
|
|
|
@ -7949,6 +7949,29 @@ fn parse_create_type() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn parse_call() {
|
||||||
|
all_dialects().verified_stmt("CALL my_procedure()");
|
||||||
|
all_dialects().verified_stmt("CALL my_procedure(1, 'a')");
|
||||||
|
pg_and_generic().verified_stmt("CALL my_procedure(1, 'a', $1)");
|
||||||
|
all_dialects().verified_stmt("CALL my_procedure");
|
||||||
|
assert_eq!(
|
||||||
|
verified_stmt("CALL my_procedure('a')"),
|
||||||
|
Statement::Call(Function {
|
||||||
|
args: vec![FunctionArg::Unnamed(FunctionArgExpr::Expr(Expr::Value(
|
||||||
|
Value::SingleQuotedString("a".to_string())
|
||||||
|
))),],
|
||||||
|
name: ObjectName(vec![Ident::new("my_procedure")]),
|
||||||
|
filter: None,
|
||||||
|
null_treatment: None,
|
||||||
|
over: None,
|
||||||
|
distinct: false,
|
||||||
|
special: false,
|
||||||
|
order_by: vec![]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn parse_create_table_collate() {
|
fn parse_create_table_collate() {
|
||||||
pg_and_generic().verified_stmt("CREATE TABLE tbl (foo INT, bar TEXT COLLATE \"de_DE\")");
|
pg_and_generic().verified_stmt("CREATE TABLE tbl (foo INT, bar TEXT COLLATE \"de_DE\")");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue