feat: Add WITH OFFSET Alias (#528)

* feat: Add WITH OFFSET Alias

* update: fix with_offset_alias type
This commit is contained in:
sivchari 2022-06-30 02:29:44 +09:00 committed by GitHub
parent 17c238bda7
commit 68768530cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 2 deletions

View file

@ -367,6 +367,7 @@ pub enum TableFactor {
alias: Option<TableAlias>,
array_expr: Box<Expr>,
with_offset: bool,
with_offset_alias: Option<Ident>,
},
/// Represents a parenthesized table factor. The SQL spec only allows a
/// join expression (`(foo <JOIN> bar [ <JOIN> baz ... ])`) to be nested,
@ -423,6 +424,7 @@ impl fmt::Display for TableFactor {
alias,
array_expr,
with_offset,
with_offset_alias,
} => {
write!(f, "UNNEST({})", array_expr)?;
if let Some(alias) = alias {
@ -431,6 +433,9 @@ impl fmt::Display for TableFactor {
if *with_offset {
write!(f, " WITH OFFSET")?;
}
if let Some(alias) = with_offset_alias {
write!(f, " AS {}", alias)?;
}
Ok(())
}
TableFactor::NestedJoin(table_reference) => write!(f, "({})", table_reference),

View file

@ -3842,10 +3842,18 @@ impl<'a> Parser<'a> {
Err(_) => false,
};
let with_offset_alias =
match self.parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS) {
Ok(Some(alias)) => Some(alias),
Ok(None) => None,
Err(e) => return Err(e),
};
Ok(TableFactor::UNNEST {
alias,
array_expr: Box::new(expr),
with_offset,
with_offset_alias,
})
} else {
let name = self.parse_object_name()?;

View file

@ -2837,11 +2837,22 @@ fn parse_table_function() {
#[test]
fn parse_unnest() {
fn chk(alias: bool, with_offset: bool, dialects: &TestedDialects, want: Vec<TableWithJoins>) {
fn chk(
alias: bool,
with_offset: bool,
with_offset_alias: bool,
dialects: &TestedDialects,
want: Vec<TableWithJoins>,
) {
let sql = &format!(
"SELECT * FROM UNNEST(expr){}{}",
"SELECT * FROM UNNEST(expr){}{}{}",
if alias { " AS numbers" } else { "" },
if with_offset { " WITH OFFSET" } else { "" },
if with_offset_alias {
" AS with_offset_alias"
} else {
""
},
);
let select = dialects.verified_only_select(sql);
assert_eq!(select.from, want);
@ -2853,6 +2864,7 @@ fn parse_unnest() {
chk(
true,
true,
false,
&dialects,
vec![TableWithJoins {
relation: TableFactor::UNNEST {
@ -2862,12 +2874,14 @@ fn parse_unnest() {
}),
array_expr: Box::new(Expr::Identifier(Ident::new("expr"))),
with_offset: true,
with_offset_alias: None,
},
joins: vec![],
}],
);
// 2. neither Alias nor WITH OFFSET clause.
chk(
false,
false,
false,
&dialects,
@ -2876,6 +2890,7 @@ fn parse_unnest() {
alias: None,
array_expr: Box::new(Expr::Identifier(Ident::new("expr"))),
with_offset: false,
with_offset_alias: None,
},
joins: vec![],
}],
@ -2884,12 +2899,14 @@ fn parse_unnest() {
chk(
false,
true,
false,
&dialects,
vec![TableWithJoins {
relation: TableFactor::UNNEST {
alias: None,
array_expr: Box::new(Expr::Identifier(Ident::new("expr"))),
with_offset: true,
with_offset_alias: None,
},
joins: vec![],
}],
@ -2898,6 +2915,7 @@ fn parse_unnest() {
chk(
true,
false,
false,
&dialects,
vec![TableWithJoins {
relation: TableFactor::UNNEST {
@ -2907,6 +2925,26 @@ fn parse_unnest() {
}),
array_expr: Box::new(Expr::Identifier(Ident::new("expr"))),
with_offset: false,
with_offset_alias: None,
},
joins: vec![],
}],
);
// 5. WITH OFFSET and WITH OFFSET Alias
chk(
true,
false,
true,
&dialects,
vec![TableWithJoins {
relation: TableFactor::UNNEST {
alias: Some(TableAlias {
name: Ident::new("numbers"),
columns: vec![],
}),
array_expr: Box::new(Expr::Identifier(Ident::new("expr"))),
with_offset: false,
with_offset_alias: Some(Ident::new("with_offset_alias")),
},
joins: vec![],
}],