From 6b3230d73e81d9cfd3266fd5b170f12aa6edcece Mon Sep 17 00:00:00 2001 From: Yoav Cohen Date: Wed, 15 Apr 2026 11:10:14 -0400 Subject: [PATCH] PostgreSQL: Add support for LATERAL ... WITH ORDINALITY --- src/ast/query.rs | 6 ++++++ src/ast/spans.rs | 1 + src/parser/mod.rs | 2 ++ tests/sqlparser_common.rs | 1 + tests/sqlparser_postgres.rs | 28 ++++++++++++++++++++++++++++ 5 files changed, 38 insertions(+) diff --git a/src/ast/query.rs b/src/ast/query.rs index 49ba86f1f..8e6f654e2 100644 --- a/src/ast/query.rs +++ b/src/ast/query.rs @@ -1522,6 +1522,8 @@ pub enum TableFactor { name: ObjectName, /// Arguments passed to the function. args: Vec, + /// Whether `WITH ORDINALITY` was specified to include ordinality. + with_ordinality: bool, /// Optional alias for the result of the function. alias: Option, }, @@ -2277,6 +2279,7 @@ impl fmt::Display for TableFactor { lateral, name, args, + with_ordinality, alias, } => { if *lateral { @@ -2284,6 +2287,9 @@ impl fmt::Display for TableFactor { } write!(f, "{name}")?; write!(f, "({})", display_comma_separated(args))?; + if *with_ordinality { + write!(f, " WITH ORDINALITY")?; + } if let Some(alias) = alias { write!(f, " {alias}")?; } diff --git a/src/ast/spans.rs b/src/ast/spans.rs index e7a8f94f2..e2a610c02 100644 --- a/src/ast/spans.rs +++ b/src/ast/spans.rs @@ -1990,6 +1990,7 @@ impl Spanned for TableFactor { lateral: _, name, args, + with_ordinality: _, alias, } => union_spans( name.0 diff --git a/src/parser/mod.rs b/src/parser/mod.rs index a5526723b..804d4ca39 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -15885,11 +15885,13 @@ impl<'a> Parser<'a> { let name = self.parse_object_name(false)?; self.expect_token(&Token::LParen)?; let args = self.parse_optional_args()?; + let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]); let alias = self.maybe_parse_table_alias()?; Ok(TableFactor::Function { lateral: true, name, args, + with_ordinality, alias, }) } diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs index c76899f04..567d04bb6 100644 --- a/tests/sqlparser_common.rs +++ b/tests/sqlparser_common.rs @@ -9028,6 +9028,7 @@ fn lateral_function() { vec![Ident::new("customer"), Ident::new("id")], ))), ], + with_ordinality: false, alias: None, }, global: false, diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 07b62dd93..22e265bbe 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -6136,6 +6136,34 @@ fn test_table_function_with_ordinality() { } } +#[test] +fn test_lateral_function_with_ordinality_and_column_aliases() { + let from = pg() + .verified_only_select( + "SELECT * FROM tbl, \ + LATERAL json_array_elements(c1::JSON) \ + WITH ORDINALITY AS t (c1, index)", + ) + .from; + assert_eq!(2, from.len()); + match &from[1].relation { + TableFactor::Function { + lateral: true, + name, + with_ordinality: true, + alias: Some(alias), + .. + } => { + assert_eq!("json_array_elements", name.to_string().as_str()); + assert_eq!("t", alias.name.value.as_str()); + assert_eq!(2, alias.columns.len()); + assert_eq!("c1", alias.columns[0].name.value.as_str()); + assert_eq!("index", alias.columns[1].name.value.as_str()); + } + _ => panic!("Expecting TableFactor::Function with ordinality and alias columns"), + } +} + #[test] fn test_table_unnest_with_ordinality() { let from = pg_and_generic()