mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-09-06 14:10:32 +00:00
Parse table-valued functions and MSSQL-specific WITH hints
1) Table-valued functions (`FROM possibly_qualified.fn(arg1, ...)`) is not part of ANSI SQL, but is supported in Postgres and MSSQL at least: - "38.5.7. SQL Functions as Table Sources" <https://www.postgresql.org/docs/current/xfunc-sql.html#XFUNC-SQL-TABLE-FUNCTIONS> - `user_defined_function` in "FROM (Transact-SQL)" <https://docs.microsoft.com/en-us/sql/t-sql/queries/from-transact-sql?view=sql-server-2017> I've considered renaming TableFactor::Table to something else (Object?), now that it can be a TVF, but couldn't come up with a satisfactory name. 2) "WITH hints" is MSSQL-specific syntax <https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-2017> Note that MSSQL supports the following ways of specifying hints, which are parsed with varying degrees of accuracy: - `FROM tab (NOLOCK)` -- deprecated syntax, parsed as a function with a `NOLOCK` argument - `FROM tab C (NOLOCK)` -- deprecated syntax, rejected ATM - `FROM TAB C WITH (NOLOCK)` -- OK
This commit is contained in:
parent
e5e3d71354
commit
364f62f333
3 changed files with 87 additions and 18 deletions
|
@ -242,13 +242,7 @@ impl Parser {
|
|||
|
||||
pub fn parse_function(&mut self, name: SQLObjectName) -> Result<ASTNode, ParserError> {
|
||||
self.expect_token(&Token::LParen)?;
|
||||
let args = if self.consume_token(&Token::RParen) {
|
||||
vec![]
|
||||
} else {
|
||||
let args = self.parse_expr_list()?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
args
|
||||
};
|
||||
let args = self.parse_optional_args()?;
|
||||
let over = if self.parse_keyword("OVER") {
|
||||
// TBD: support window names (`OVER mywin`) in place of inline specification
|
||||
self.expect_token(&Token::LParen)?;
|
||||
|
@ -1430,8 +1424,30 @@ impl Parser {
|
|||
Ok(TableFactor::Derived { subquery, alias })
|
||||
} else {
|
||||
let name = self.parse_object_name()?;
|
||||
// Postgres, MSSQL: table-valued functions:
|
||||
let args = if self.consume_token(&Token::LParen) {
|
||||
Some(self.parse_optional_args()?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let alias = self.parse_optional_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
|
||||
Ok(TableFactor::Table { name, alias })
|
||||
// MSSQL-specific table hints:
|
||||
let mut with_hints = vec![];
|
||||
if self.parse_keyword("WITH") {
|
||||
if self.consume_token(&Token::LParen) {
|
||||
with_hints = self.parse_expr_list()?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
} else {
|
||||
// rewind, as WITH may belong to the next statement's CTE
|
||||
self.prev_token();
|
||||
}
|
||||
};
|
||||
Ok(TableFactor::Table {
|
||||
name,
|
||||
alias,
|
||||
args,
|
||||
with_hints,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1576,6 +1592,16 @@ impl Parser {
|
|||
Ok(expr_list)
|
||||
}
|
||||
|
||||
pub fn parse_optional_args(&mut self) -> Result<Vec<ASTNode>, ParserError> {
|
||||
if self.consume_token(&Token::RParen) {
|
||||
Ok(vec![])
|
||||
} else {
|
||||
let args = self.parse_expr_list()?;
|
||||
self.expect_token(&Token::RParen)?;
|
||||
Ok(args)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a comma-delimited list of projections after SELECT
|
||||
pub fn parse_select_list(&mut self) -> Result<Vec<SQLSelectItem>, ParserError> {
|
||||
let mut projections: Vec<SQLSelectItem> = vec![];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue