diff --git a/src/ast/query.rs b/src/ast/query.rs index 49ba86f1f..36e858a92 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -2527,6 +2527,8 @@ pub struct TableAlias { pub name: Ident, /// Optional column aliases declared in parentheses after the table alias. pub columns: Vec, + /// Optional PartiQL index alias declared with `AT`. + pub at: Option, } impl fmt::Display for TableAlias { @@ -2535,6 +2537,9 @@ impl fmt::Display for TableAlias { if !self.columns.is_empty() { write!(f, " ({})", display_comma_separated(&self.columns))?; } + if let Some(at) = &self.at { + write!(f, " AT {at}")?; + } Ok(()) } } diff --git a/src/ast/spans.rs b/src/ast/spans.rs index e7a8f94f2..8b775a118 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -2178,8 +2178,13 @@ impl Spanned for TableAlias { explicit: _, name, columns, + at, } = self; - union_spans(core::iter::once(name.span).chain(columns.iter().map(Spanned::span))) + union_spans( + core::iter::once(name.span) + .chain(columns.iter().map(Spanned::span)) + .chain(at.iter().map(|at| at.span)), + ) } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a5526723b..7589480d6 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -12809,10 +12809,16 @@ impl<'a> Parser<'a> { match self.parse_optional_alias_inner(None, validator)? { Some(name) => { let columns = self.parse_table_alias_column_defs()?; + let at = if self.dialect.supports_partiql() && self.parse_keyword(Keyword::AT) { + Some(self.parse_identifier()?) + } else { + None + }; Ok(Some(TableAlias { explicit, name, columns, + at, })) } None => Ok(None), @@ -14461,6 +14467,7 @@ impl<'a> Parser<'a> { explicit: false, name, columns: vec![], + at: None, }, query, from: None, @@ -14505,6 +14512,7 @@ impl<'a> Parser<'a> { explicit: false, name, columns, + at: None, }, query, from: None, diff --git a/src/test_utils.rs b/src/test_utils.rs index 9ba5960e8..669ea1ecd 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -374,6 +374,7 @@ pub fn table_alias(explicit: bool, name: impl Into) -> Option { + assert_eq!( + name, + &ObjectName::from(vec![Ident::new("b"), Ident::new("val")]) + ); + assert_eq!(alias.as_ref().map(|a| &a.name), Some(&Ident::new("val"))); + assert_eq!( + alias.as_ref().and_then(|a| a.at.as_ref()), + Some(&Ident::new("index")) + ); + } + _ => panic!("expected table factor"), + } +}