From e9a17d91e29f3c54e56a872376a9ca20674a4a94 Mon Sep 17 00:00:00 2001 From: sivchari Date: Sun, 26 Jun 2022 01:26:35 +0900 Subject: [PATCH 1/2] feat: Add WITH OFFSET Alias --- src/ast/query.rs | 5 +++++ src/parser.rs | 8 +++++++ tests/sqlparser_common.rs | 45 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/ast/query.rs b/src/ast/query.rs index 6212469f4..4f1e20937 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -367,6 +367,7 @@ pub enum TableFactor { alias: Option, array_expr: Box, with_offset: bool, + with_offset_alias: Option, }, /// Represents a parenthesized table factor. The SQL spec only allows a /// join expression (`(foo bar [ 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), diff --git a/src/parser.rs b/src/parser.rs index 43daf797b..3ca257c75 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3839,10 +3839,18 @@ impl<'a> Parser<'a> { Err(_) => false, }; + let with_offset_alias = + match self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_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()?; diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index 8d13b689d..b7fd4cde3 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2837,11 +2837,22 @@ fn parse_table_function() { #[test] fn parse_unnest() { - fn chk(alias: bool, with_offset: bool, dialects: &TestedDialects, want: Vec) { + fn chk( + alias: bool, + with_offset: bool, + with_offset_alias: bool, + dialects: &TestedDialects, + want: Vec, + ) { 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,29 @@ 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(TableAlias { + name: Ident::new("with_offset_alias"), + columns: vec![], + }), }, joins: vec![], }], From 508bbe9e715b06e14d5d7c8025df9b0a8a588d79 Mon Sep 17 00:00:00 2001 From: sivchari Date: Sun, 26 Jun 2022 18:33:46 +0900 Subject: [PATCH 2/2] update: fix with_offset_alias type --- src/ast/query.rs | 2 +- src/parser.rs | 2 +- tests/sqlparser_common.rs | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ast/query.rs b/src/ast/query.rs index 4f1e20937..1a785e309 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -367,7 +367,7 @@ pub enum TableFactor { alias: Option, array_expr: Box, with_offset: bool, - with_offset_alias: Option, + with_offset_alias: Option, }, /// Represents a parenthesized table factor. The SQL spec only allows a /// join expression (`(foo bar [ baz ... ])`) to be nested, diff --git a/src/parser.rs b/src/parser.rs index 3ca257c75..e67ad07f6 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3840,7 +3840,7 @@ impl<'a> Parser<'a> { }; let with_offset_alias = - match self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS) { + match self.parse_optional_alias(keywords::RESERVED_FOR_COLUMN_ALIAS) { Ok(Some(alias)) => Some(alias), Ok(None) => None, Err(e) => return Err(e), diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index b7fd4cde3..bb2c4d018 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -2944,10 +2944,7 @@ fn parse_unnest() { }), array_expr: Box::new(Expr::Identifier(Ident::new("expr"))), with_offset: false, - with_offset_alias: Some(TableAlias { - name: Ident::new("with_offset_alias"), - columns: vec![], - }), + with_offset_alias: Some(Ident::new("with_offset_alias")), }, joins: vec![], }],