Skip to content

Commit ac97a7e

Browse files
committed
Support single table name with Parenthesis
1 parent 172ba42 commit ac97a7e

File tree

2 files changed

+72
-44
lines changed

2 files changed

+72
-44
lines changed

src/parser.rs

+65-42
Original file line numberDiff line numberDiff line change
@@ -1748,6 +1748,40 @@ impl Parser {
17481748
Ok(TableWithJoins { relation, joins })
17491749
}
17501750

1751+
pub fn parse_table_factor_table(&mut self) -> Result<TableFactor, ParserError> {
1752+
let name = self.parse_object_name()?;
1753+
// Postgres, MSSQL: table-valued functions:
1754+
let args = if self.consume_token(&Token::LParen) {
1755+
self.parse_optional_args()?
1756+
} else {
1757+
vec![]
1758+
};
1759+
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
1760+
// MSSQL-specific table hints:
1761+
let mut with_hints = vec![];
1762+
if self.parse_keyword("WITH") {
1763+
if self.consume_token(&Token::LParen) {
1764+
with_hints = self.parse_comma_separated(Parser::parse_expr)?;
1765+
self.expect_token(&Token::RParen)?;
1766+
} else {
1767+
// rewind, as WITH may belong to the next statement's CTE
1768+
self.prev_token();
1769+
}
1770+
};
1771+
Ok(TableFactor::Table {
1772+
name,
1773+
alias,
1774+
args,
1775+
with_hints,
1776+
})
1777+
}
1778+
1779+
pub fn parse_table_inside_parenthesis(&mut self) -> Result<TableFactor, ParserError> {
1780+
let table = self.parse_table_factor_table()?;
1781+
self.expect_token(&Token::RParen)?;
1782+
Ok(table)
1783+
}
1784+
17511785
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
17521786
pub fn parse_table_factor(&mut self) -> Result<TableFactor, ParserError> {
17531787
if self.parse_keyword("LATERAL") {
@@ -1757,6 +1791,7 @@ impl Parser {
17571791
}
17581792
return self.parse_derived_table_factor(Lateral);
17591793
}
1794+
17601795

17611796
if self.consume_token(&Token::LParen) {
17621797
let index = self.index;
@@ -1767,10 +1802,12 @@ impl Parser {
17671802
// Here's an example that demonstrates the complexity:
17681803
// /-------------------------------------------------------\
17691804
// | /-----------------------------------\ |
1770-
// SELECT * FROM ( ( ( (SELECT 1) UNION (SELECT 2) ) AS t1 NATURAL JOIN t2 ) )
1771-
// ^ ^ ^ ^
1772-
// | | | |
1773-
// | | | |
1805+
// SELECT * FROM ( ( ( (SELECT 1) UNION (SELECT 2) ) AS t1 NATURAL JOIN (t2) ) )
1806+
// ^ ^ ^ ^ ^
1807+
// | | | | |
1808+
// | | | | /----------------------------------------------|
1809+
// | | | | |
1810+
// | | | | (5) some db's (snowflake) allow bare table inside parenthesis
17741811
// | | | (4) belongs to a SetExpr::Query inside the subquery
17751812
// | | (3) starts a derived table (subquery)
17761813
// | (2) starts a nested join
@@ -1788,53 +1825,39 @@ impl Parser {
17881825
// token following the paren can't start a query (e.g. `foo`
17891826
// in `FROM (foo NATURAL JOIN bar)`, or when the '(' we've
17901827
// consumed is followed by another '(' that starts a
1791-
// derived table, like (3), or another nested join (2).
1792-
//
1828+
// derived table, like (3), another nested join (2), and
1829+
// in some db's even just the table name (5).
17931830
// Ignore the error and back up to where we were before.
17941831
// Either we'll be able to parse a valid nested join, or
17951832
// we won't, and we'll return that error instead.
1796-
self.index = index;
1797-
let table_and_joins = self.parse_table_and_joins()?;
1798-
match table_and_joins.relation {
1799-
TableFactor::NestedJoin { .. } => (),
1800-
_ => {
1801-
if table_and_joins.joins.is_empty() {
1802-
// The SQL spec prohibits derived tables and bare
1803-
// tables from appearing alone in parentheses.
1804-
self.expected("joined table", self.peek_token())?
1833+
self.index = index;
1834+
//try parse bare table statement
1835+
match self.parse_table_inside_parenthesis() {
1836+
Ok(res) => Ok(res),
1837+
Err(_) => {
1838+
//try again to parse join statement
1839+
self.index = index;
1840+
let table_and_joins = self.parse_table_and_joins()?;
1841+
match table_and_joins.relation {
1842+
TableFactor::NestedJoin { .. } => (),
1843+
_ => {
1844+
if table_and_joins.joins.is_empty() {
1845+
// The SQL spec prohibits derived
1846+
// tables from appearing alone in parentheses.
1847+
// bare tables in parentheses handle above as
1848+
// it supported by some database (snowflake).
1849+
self.expected("joined table", self.peek_token())?
1850+
}
1851+
}
18051852
}
1853+
self.expect_token(&Token::RParen)?;
1854+
Ok(TableFactor::NestedJoin(Box::new(table_and_joins)))
18061855
}
18071856
}
1808-
self.expect_token(&Token::RParen)?;
1809-
Ok(TableFactor::NestedJoin(Box::new(table_and_joins)))
18101857
}
18111858
}
18121859
} else {
1813-
let name = self.parse_object_name()?;
1814-
// Postgres, MSSQL: table-valued functions:
1815-
let args = if self.consume_token(&Token::LParen) {
1816-
self.parse_optional_args()?
1817-
} else {
1818-
vec![]
1819-
};
1820-
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
1821-
// MSSQL-specific table hints:
1822-
let mut with_hints = vec![];
1823-
if self.parse_keyword("WITH") {
1824-
if self.consume_token(&Token::LParen) {
1825-
with_hints = self.parse_comma_separated(Parser::parse_expr)?;
1826-
self.expect_token(&Token::RParen)?;
1827-
} else {
1828-
// rewind, as WITH may belong to the next statement's CTE
1829-
self.prev_token();
1830-
}
1831-
};
1832-
Ok(TableFactor::Table {
1833-
name,
1834-
alias,
1835-
args,
1836-
with_hints,
1837-
})
1860+
self.parse_table_factor_table()
18381861
}
18391862
}
18401863

tests/sqlparser_common.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -1806,11 +1806,16 @@ fn parse_join_nesting() {
18061806
vec![join(nest!(nest!(nest!(table("b"), table("c")))))]
18071807
);
18081808

1809-
let res = parse_sql_statements("SELECT * FROM (a NATURAL JOIN (b))");
1809+
let res = parse_sql_statements("SELECT * FROM (a b))");
18101810
assert_eq!(
1811-
ParserError::ParserError("Expected joined table, found: )".to_string()),
1811+
ParserError::ParserError("Expected end of statement, found: )".to_string()),
18121812
res.unwrap_err()
18131813
);
1814+
1815+
one_statement_parses_to("SELECT * FROM (a)","SELECT * FROM a" );
1816+
1817+
one_statement_parses_to("SELECT * FROM (a NATURAL JOIN (b))" , "SELECT * FROM (a NATURAL JOIN b)");
1818+
18141819
}
18151820

18161821
#[test]

0 commit comments

Comments
 (0)