diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 4d642919e..11f967876 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -6240,7 +6240,7 @@ impl<'a> Parser<'a> { // appearing alone in parentheses (e.g. `FROM (mytable)`) self.expected("joined table", self.peek_token()) } - } else if dialect_of!(self is BigQueryDialect | GenericDialect) + } else if dialect_of!(self is BigQueryDialect | PostgreSqlDialect | GenericDialect) && self.parse_keyword(Keyword::UNNEST) { self.expect_token(&Token::LParen)?; diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 079e4695a..77e5ba45e 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -3450,3 +3450,30 @@ fn parse_create_table_with_alias() { _ => unreachable!(), } } + +#[test] +fn parse_join_constraint_unnest_alias() { + assert_eq!( + only( + pg().verified_only_select("SELECT * FROM t1 JOIN UNNEST(t1.a) AS f ON c1 = c2") + .from + ) + .joins, + vec![Join { + relation: TableFactor::UNNEST { + alias: table_alias("f"), + array_exprs: vec![Expr::CompoundIdentifier(vec![ + Ident::new("t1"), + Ident::new("a") + ])], + with_offset: false, + with_offset_alias: None + }, + join_operator: JoinOperator::Inner(JoinConstraint::On(Expr::BinaryOp { + left: Box::new(Expr::Identifier("c1".into())), + op: BinaryOperator::Eq, + right: Box::new(Expr::Identifier("c2".into())), + })), + }] + ); +}