mirror of
https://github.com/apache/datafusion-sqlparser-rs.git
synced 2025-10-09 21:42:05 +00:00
Support UNION (ALL) BY NAME syntax (#915)
This commit is contained in:
parent
c45451850c
commit
eb288487a6
4 changed files with 164 additions and 3 deletions
|
@ -110,7 +110,10 @@ impl fmt::Display for SetExpr {
|
|||
} => {
|
||||
write!(f, "{left} {op}")?;
|
||||
match set_quantifier {
|
||||
SetQuantifier::All | SetQuantifier::Distinct => write!(f, " {set_quantifier}")?,
|
||||
SetQuantifier::All
|
||||
| SetQuantifier::Distinct
|
||||
| SetQuantifier::ByName
|
||||
| SetQuantifier::AllByName => write!(f, " {set_quantifier}")?,
|
||||
SetQuantifier::None => write!(f, "{set_quantifier}")?,
|
||||
}
|
||||
write!(f, " {right}")?;
|
||||
|
@ -148,6 +151,8 @@ impl fmt::Display for SetOperator {
|
|||
pub enum SetQuantifier {
|
||||
All,
|
||||
Distinct,
|
||||
ByName,
|
||||
AllByName,
|
||||
None,
|
||||
}
|
||||
|
||||
|
@ -156,6 +161,8 @@ impl fmt::Display for SetQuantifier {
|
|||
match self {
|
||||
SetQuantifier::All => write!(f, "ALL"),
|
||||
SetQuantifier::Distinct => write!(f, "DISTINCT"),
|
||||
SetQuantifier::ByName => write!(f, "BY NAME"),
|
||||
SetQuantifier::AllByName => write!(f, "ALL BY NAME"),
|
||||
SetQuantifier::None => write!(f, ""),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -384,6 +384,7 @@ define_keywords!(
|
|||
MSCK,
|
||||
MULTISET,
|
||||
MUTATION,
|
||||
NAME,
|
||||
NANOSECOND,
|
||||
NANOSECONDS,
|
||||
NATIONAL,
|
||||
|
|
|
@ -5331,8 +5331,14 @@ impl<'a> Parser<'a> {
|
|||
pub fn parse_set_quantifier(&mut self, op: &Option<SetOperator>) -> SetQuantifier {
|
||||
match op {
|
||||
Some(SetOperator::Union) => {
|
||||
if self.parse_keyword(Keyword::ALL) {
|
||||
if self.parse_keywords(&[Keyword::BY, Keyword::NAME]) {
|
||||
SetQuantifier::ByName
|
||||
} else if self.parse_keyword(Keyword::ALL) {
|
||||
if self.parse_keywords(&[Keyword::BY, Keyword::NAME]) {
|
||||
SetQuantifier::AllByName
|
||||
} else {
|
||||
SetQuantifier::All
|
||||
}
|
||||
} else if self.parse_keyword(Keyword::DISTINCT) {
|
||||
SetQuantifier::Distinct
|
||||
} else {
|
||||
|
|
|
@ -129,3 +129,150 @@ fn test_create_table_macro() {
|
|||
};
|
||||
assert_eq!(expected, macro_);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_select_union_by_name() {
|
||||
let ast = duckdb().verified_query("SELECT * FROM capitals UNION BY NAME SELECT * FROM weather");
|
||||
let expected = Box::<SetExpr>::new(SetExpr::SetOperation {
|
||||
op: SetOperator::Union,
|
||||
set_quantifier: SetQuantifier::ByName,
|
||||
left: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
|
||||
distinct: None,
|
||||
top: None,
|
||||
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions {
|
||||
opt_exclude: None,
|
||||
opt_except: None,
|
||||
opt_rename: None,
|
||||
opt_replace: None,
|
||||
})],
|
||||
into: None,
|
||||
from: vec![TableWithJoins {
|
||||
relation: TableFactor::Table {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "capitals".to_string(),
|
||||
quote_style: None,
|
||||
}]),
|
||||
alias: None,
|
||||
args: None,
|
||||
with_hints: vec![],
|
||||
},
|
||||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
selection: None,
|
||||
group_by: vec![],
|
||||
cluster_by: vec![],
|
||||
distribute_by: vec![],
|
||||
sort_by: vec![],
|
||||
having: None,
|
||||
named_window: vec![],
|
||||
qualify: None,
|
||||
}))),
|
||||
right: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
|
||||
distinct: None,
|
||||
top: None,
|
||||
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions {
|
||||
opt_exclude: None,
|
||||
opt_except: None,
|
||||
opt_rename: None,
|
||||
opt_replace: None,
|
||||
})],
|
||||
into: None,
|
||||
from: vec![TableWithJoins {
|
||||
relation: TableFactor::Table {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "weather".to_string(),
|
||||
quote_style: None,
|
||||
}]),
|
||||
alias: None,
|
||||
args: None,
|
||||
with_hints: vec![],
|
||||
},
|
||||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
selection: None,
|
||||
group_by: vec![],
|
||||
cluster_by: vec![],
|
||||
distribute_by: vec![],
|
||||
sort_by: vec![],
|
||||
having: None,
|
||||
named_window: vec![],
|
||||
qualify: None,
|
||||
}))),
|
||||
});
|
||||
|
||||
assert_eq!(ast.body, expected);
|
||||
|
||||
let ast =
|
||||
duckdb().verified_query("SELECT * FROM capitals UNION ALL BY NAME SELECT * FROM weather");
|
||||
let expected = Box::<SetExpr>::new(SetExpr::SetOperation {
|
||||
op: SetOperator::Union,
|
||||
set_quantifier: SetQuantifier::AllByName,
|
||||
left: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
|
||||
distinct: None,
|
||||
top: None,
|
||||
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions {
|
||||
opt_exclude: None,
|
||||
opt_except: None,
|
||||
opt_rename: None,
|
||||
opt_replace: None,
|
||||
})],
|
||||
into: None,
|
||||
from: vec![TableWithJoins {
|
||||
relation: TableFactor::Table {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "capitals".to_string(),
|
||||
quote_style: None,
|
||||
}]),
|
||||
alias: None,
|
||||
args: None,
|
||||
with_hints: vec![],
|
||||
},
|
||||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
selection: None,
|
||||
group_by: vec![],
|
||||
cluster_by: vec![],
|
||||
distribute_by: vec![],
|
||||
sort_by: vec![],
|
||||
having: None,
|
||||
named_window: vec![],
|
||||
qualify: None,
|
||||
}))),
|
||||
right: Box::<SetExpr>::new(SetExpr::Select(Box::new(Select {
|
||||
distinct: None,
|
||||
top: None,
|
||||
projection: vec![SelectItem::Wildcard(WildcardAdditionalOptions {
|
||||
opt_exclude: None,
|
||||
opt_except: None,
|
||||
opt_rename: None,
|
||||
opt_replace: None,
|
||||
})],
|
||||
into: None,
|
||||
from: vec![TableWithJoins {
|
||||
relation: TableFactor::Table {
|
||||
name: ObjectName(vec![Ident {
|
||||
value: "weather".to_string(),
|
||||
quote_style: None,
|
||||
}]),
|
||||
alias: None,
|
||||
args: None,
|
||||
with_hints: vec![],
|
||||
},
|
||||
joins: vec![],
|
||||
}],
|
||||
lateral_views: vec![],
|
||||
selection: None,
|
||||
group_by: vec![],
|
||||
cluster_by: vec![],
|
||||
distribute_by: vec![],
|
||||
sort_by: vec![],
|
||||
having: None,
|
||||
named_window: vec![],
|
||||
qualify: None,
|
||||
}))),
|
||||
});
|
||||
assert_eq!(ast.body, expected);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue