mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-15 00:09:02 +00:00
Add support for Recursive CTEs (#278)
i.e. `WITH RECURSIVE ... AS ( ... ) SELECT` - see https://jakewheat.github.io/sql-overview/sql-2016-foundation-grammar.html#with-clause Fixes #277
This commit is contained in:
parent
54be3912a9
commit
9f772f03b0
5 changed files with 73 additions and 19 deletions
|
@ -2389,7 +2389,7 @@ fn parse_ctes() {
|
|||
|
||||
fn assert_ctes_in_select(expected: &[&str], sel: &Query) {
|
||||
for (i, exp) in expected.iter().enumerate() {
|
||||
let Cte { alias, query } = &sel.ctes[i];
|
||||
let Cte { alias, query } = &sel.with.as_ref().unwrap().cte_tables[i];
|
||||
assert_eq!(*exp, query.to_string());
|
||||
assert_eq!(
|
||||
if i == 0 {
|
||||
|
@ -2432,7 +2432,7 @@ fn parse_ctes() {
|
|||
// CTE in a CTE...
|
||||
let sql = &format!("WITH outer_cte AS ({}) SELECT * FROM outer_cte", with);
|
||||
let select = verified_query(sql);
|
||||
assert_ctes_in_select(&cte_sqls, &only(&select.ctes).query);
|
||||
assert_ctes_in_select(&cte_sqls, &only(&select.with.unwrap().cte_tables).query);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -2441,10 +2441,47 @@ fn parse_cte_renamed_columns() {
|
|||
let query = all_dialects().verified_query(sql);
|
||||
assert_eq!(
|
||||
vec![Ident::new("col1"), Ident::new("col2")],
|
||||
query.ctes.first().unwrap().alias.columns
|
||||
query
|
||||
.with
|
||||
.unwrap()
|
||||
.cte_tables
|
||||
.first()
|
||||
.unwrap()
|
||||
.alias
|
||||
.columns
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_recursive_cte() {
|
||||
let cte_query = "SELECT 1 UNION ALL SELECT val + 1 FROM nums WHERE val < 10".to_owned();
|
||||
let sql = &format!(
|
||||
"WITH RECURSIVE nums (val) AS ({}) SELECT * FROM nums",
|
||||
cte_query
|
||||
);
|
||||
|
||||
let cte_query = verified_query(&cte_query);
|
||||
let query = verified_query(sql);
|
||||
|
||||
let with = query.with.as_ref().unwrap();
|
||||
assert!(with.recursive);
|
||||
assert_eq!(with.cte_tables.len(), 1);
|
||||
let expected = Cte {
|
||||
alias: TableAlias {
|
||||
name: Ident {
|
||||
value: "nums".to_string(),
|
||||
quote_style: None,
|
||||
},
|
||||
columns: vec![Ident {
|
||||
value: "val".to_string(),
|
||||
quote_style: None,
|
||||
}],
|
||||
},
|
||||
query: cte_query,
|
||||
};
|
||||
assert_eq!(with.cte_tables.first().unwrap(), &expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_derived_tables() {
|
||||
let sql = "SELECT a.x, b.y FROM (SELECT x FROM foo) AS a CROSS JOIN (SELECT y FROM bar) AS b";
|
||||
|
@ -3266,8 +3303,8 @@ fn parse_drop_index() {
|
|||
fn all_keywords_sorted() {
|
||||
// assert!(ALL_KEYWORDS.is_sorted())
|
||||
let mut copy = Vec::from(ALL_KEYWORDS);
|
||||
copy.sort();
|
||||
assert!(copy == ALL_KEYWORDS)
|
||||
copy.sort_unstable();
|
||||
assert_eq!(copy, ALL_KEYWORDS)
|
||||
}
|
||||
|
||||
fn parse_sql_statements(sql: &str) -> Result<Vec<Statement>, ParserError> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue