mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-08-04 06:18:17 +00:00
Add lateral derived support
This commit is contained in:
parent
fe10fac0ad
commit
2d00ea7187
3 changed files with 63 additions and 3 deletions
|
@ -209,6 +209,7 @@ pub enum TableFactor {
|
|||
with_hints: Vec<ASTNode>,
|
||||
},
|
||||
Derived {
|
||||
lateral: bool,
|
||||
subquery: Box<SQLQuery>,
|
||||
alias: Option<SQLIdent>,
|
||||
},
|
||||
|
@ -235,8 +236,16 @@ impl ToString for TableFactor {
|
|||
}
|
||||
s
|
||||
}
|
||||
TableFactor::Derived { subquery, alias } => {
|
||||
let mut s = format!("({})", subquery.to_string());
|
||||
TableFactor::Derived {
|
||||
lateral,
|
||||
subquery,
|
||||
alias,
|
||||
} => {
|
||||
let mut s = String::new();
|
||||
if *lateral {
|
||||
s += "LATERAL ";
|
||||
}
|
||||
s += &format!("({})", subquery.to_string());
|
||||
if let Some(alias) = alias {
|
||||
s += &format!(" AS {}", alias);
|
||||
}
|
||||
|
|
|
@ -1464,11 +1464,18 @@ impl Parser {
|
|||
|
||||
/// A table name or a parenthesized subquery, followed by optional `[AS] alias`
|
||||
pub fn parse_table_factor(&mut self) -> Result<TableFactor, ParserError> {
|
||||
let lateral = self.parse_keyword("LATERAL");
|
||||
if self.consume_token(&Token::LParen) {
|
||||
let subquery = Box::new(self.parse_query()?);
|
||||
self.expect_token(&Token::RParen)?;
|
||||
let alias = self.parse_optional_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
|
||||
Ok(TableFactor::Derived { subquery, alias })
|
||||
Ok(TableFactor::Derived {
|
||||
lateral,
|
||||
subquery,
|
||||
alias,
|
||||
})
|
||||
} else if lateral {
|
||||
self.expected("subquery after LATERAL", self.peek_token())
|
||||
} else {
|
||||
let name = self.parse_object_name()?;
|
||||
// Postgres, MSSQL: table-valued functions:
|
||||
|
|
|
@ -1569,6 +1569,50 @@ fn parse_fetch_variations() {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lateral_derived() {
|
||||
fn chk(lateral_in: bool) {
|
||||
let lateral_str = if lateral_in { "LATERAL " } else { "" };
|
||||
let sql = format!(
|
||||
"SELECT * FROM customer LEFT JOIN {}\
|
||||
(SELECT * FROM order WHERE order.customer = customer.id LIMIT 3) AS order ON true",
|
||||
lateral_str
|
||||
);
|
||||
let select = verified_only_select(&sql);
|
||||
assert_eq!(select.joins.len(), 1);
|
||||
assert_eq!(
|
||||
select.joins[0].join_operator,
|
||||
JoinOperator::LeftOuter(JoinConstraint::On(ASTNode::SQLValue(Value::Boolean(true))))
|
||||
);
|
||||
if let TableFactor::Derived {
|
||||
lateral,
|
||||
ref subquery,
|
||||
ref alias,
|
||||
} = select.joins[0].relation
|
||||
{
|
||||
assert_eq!(lateral_in, lateral);
|
||||
assert_eq!(Some("order".to_string()), *alias);
|
||||
assert_eq!(
|
||||
subquery.to_string(),
|
||||
"SELECT * FROM order WHERE order.customer = customer.id LIMIT 3"
|
||||
);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
chk(false);
|
||||
chk(true);
|
||||
|
||||
let sql = "SELECT * FROM customer LEFT JOIN LATERAL generate_series(1, customer.id)";
|
||||
let res = parse_sql_statements(sql);
|
||||
assert_eq!(
|
||||
ParserError::ParserError(
|
||||
"Expected subquery after LATERAL, found: generate_series".to_string()
|
||||
),
|
||||
res.unwrap_err()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "Parse results with GenericSqlDialect are different from PostgreSqlDialect"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue