Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2527,6 +2527,8 @@ pub struct TableAlias {
pub name: Ident,
/// Optional column aliases declared in parentheses after the table alias.
pub columns: Vec<TableAliasColumnDef>,
/// Optional PartiQL index alias declared with `AT`.
pub at: Option<Ident>,
Comment on lines +2530 to +2531
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a link to the doc defining the syntax? (maybe an example syntax would also be helpful like we have on the explicit field)

}

impl fmt::Display for TableAlias {
Expand All @@ -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(())
}
}
Expand Down
7 changes: 6 additions & 1 deletion src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
)
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -14461,6 +14467,7 @@ impl<'a> Parser<'a> {
explicit: false,
name,
columns: vec![],
at: None,
},
query,
from: None,
Expand Down Expand Up @@ -14505,6 +14512,7 @@ impl<'a> Parser<'a> {
explicit: false,
name,
columns,
at: None,
},
query,
from: None,
Expand Down
1 change: 1 addition & 0 deletions src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ pub fn table_alias(explicit: bool, name: impl Into<String>) -> Option<TableAlias
explicit,
name: Ident::new(name),
columns: vec![],
at: None,
})
}

Expand Down
4 changes: 4 additions & 0 deletions tests/sqlparser_common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ fn parse_select_with_table_alias() {
TableAliasColumnDef::from_name("B"),
TableAliasColumnDef::from_name("C"),
],
at: None,
}),
args: None,
with_hints: vec![],
Expand Down Expand Up @@ -7858,6 +7859,7 @@ fn parse_recursive_cte() {
span: Span::empty(),
},
columns: vec![TableAliasColumnDef::from_name("val")],
at: None,
},
query: Box::new(cte_query),
from: None,
Expand Down Expand Up @@ -11343,6 +11345,7 @@ fn parse_pivot_table() {
TableAliasColumnDef::from_name("c"),
TableAliasColumnDef::from_name("d"),
],
at: None,
})
}
);
Expand Down Expand Up @@ -11481,6 +11484,7 @@ fn parse_unpivot_table() {
.into_iter()
.map(TableAliasColumnDef::from_name)
.collect(),
at: None,
}),
};
pretty_assertions::assert_eq!(verified_only_select(sql).from[0].relation, base_unpivot);
Expand Down
3 changes: 2 additions & 1 deletion tests/sqlparser_mssql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ fn parse_mssql_delimited_identifiers() {
&Some(TableAlias {
explicit: false,
name: Ident::with_quote('[', "WHERE"),
columns: vec![]
columns: vec![],
at: None,
})
);
}
Expand Down
24 changes: 24 additions & 0 deletions tests/sqlparser_redshift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,27 @@ fn test_null_treatment_inside_and_outside_window_function() {
redshift().verified_stmt("SELECT FIRST_VALUE(1 IGNORE NULLS) OVER () FROM (SELECT 1) t");
redshift().verified_stmt("SELECT FIRST_VALUE(1) IGNORE NULLS OVER () FROM (SELECT 1) t");
}

#[test]
fn test_partiql_from_alias_with_at_index() {
redshift().verified_stmt("SELECT * FROM lineitem AS l (a, b, c) AT idx");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the test can we switch to all_dialect_where(|d| d.supports_partiql()) so that future dialects are covered without duplicating tests?


let sql =
"SELECT index, val FROM (SELECT array('AAA', 'BBB') AS val) AS b, b.val AS val AT index";
let select = redshift().verified_only_select(sql);

match &select.from[1].relation {
TableFactor::Table { name, alias, .. } => {
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"),
}
}
Loading