Skip to content

Commit b89e5ac

Browse files
git-hulkayman-sigma
authored andcommitted
Add support of table function WITH ORDINALITY modifier for Postgre Parser (apache#1337)
1 parent 9c6ec54 commit b89e5ac

16 files changed

+129
-4
lines changed

src/ast/query.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,10 @@ pub enum TableFactor {
913913
/// Optional version qualifier to facilitate table time-travel, as
914914
/// supported by BigQuery and MSSQL.
915915
version: Option<TableVersion>,
916+
// Optional table function modifier to generate the ordinality for column.
917+
/// For example, `SELECT * FROM generate_series(1, 10) WITH ORDINALITY AS t(a, b);`
918+
/// [WITH ORDINALITY](https://www.postgresql.org/docs/current/functions-srf.html), supported by Postgres.
919+
with_ordinality: bool,
916920
/// [Partition selection](https://dev.mysql.com/doc/refman/8.0/en/partitioning-selection.html), supported by MySQL.
917921
partitions: Vec<Ident>,
918922
},
@@ -953,6 +957,7 @@ pub enum TableFactor {
953957
array_exprs: Vec<Expr>,
954958
with_offset: bool,
955959
with_offset_alias: Option<Ident>,
960+
with_ordinality: bool,
956961
},
957962
/// The `JSON_TABLE` table-valued function.
958963
/// Part of the SQL standard, but implemented only by MySQL, Oracle, and DB2.
@@ -1298,6 +1303,7 @@ impl fmt::Display for TableFactor {
12981303
with_hints,
12991304
version,
13001305
partitions,
1306+
with_ordinality,
13011307
} => {
13021308
write!(f, "{name}")?;
13031309
if !partitions.is_empty() {
@@ -1306,6 +1312,9 @@ impl fmt::Display for TableFactor {
13061312
if let Some(args) = args {
13071313
write!(f, "({})", display_comma_separated(args))?;
13081314
}
1315+
if *with_ordinality {
1316+
write!(f, " WITH ORDINALITY")?;
1317+
}
13091318
if let Some(alias) = alias {
13101319
write!(f, " AS {alias}")?;
13111320
}
@@ -1366,9 +1375,14 @@ impl fmt::Display for TableFactor {
13661375
array_exprs,
13671376
with_offset,
13681377
with_offset_alias,
1378+
with_ordinality,
13691379
} => {
13701380
write!(f, "UNNEST({})", display_comma_separated(array_exprs))?;
13711381

1382+
if *with_ordinality {
1383+
write!(f, " WITH ORDINALITY")?;
1384+
}
1385+
13721386
if let Some(alias) = alias {
13731387
write!(f, " AS {alias}")?;
13741388
}

src/keywords.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,7 @@ define_keywords!(
518518
OR,
519519
ORC,
520520
ORDER,
521+
ORDINALITY,
521522
OUT,
522523
OUTER,
523524
OUTPUTFORMAT,

src/parser/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9224,6 +9224,7 @@ impl<'a> Parser<'a> {
92249224
let array_exprs = self.parse_comma_separated(Parser::parse_expr)?;
92259225
self.expect_token(&Token::RParen)?;
92269226

9227+
let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]);
92279228
let alias = match self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS) {
92289229
Ok(Some(alias)) => Some(alias),
92299230
Ok(None) => None,
@@ -9250,6 +9251,7 @@ impl<'a> Parser<'a> {
92509251
array_exprs,
92519252
with_offset,
92529253
with_offset_alias,
9254+
with_ordinality,
92539255
})
92549256
} else if self.parse_keyword_with_tokens(Keyword::JSON_TABLE, &[Token::LParen]) {
92559257
let json_expr = self.parse_expr()?;
@@ -9293,6 +9295,8 @@ impl<'a> Parser<'a> {
92939295
None
92949296
};
92959297

9298+
let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]);
9299+
92969300
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
92979301

92989302
// MSSQL-specific table hints:
@@ -9314,6 +9318,7 @@ impl<'a> Parser<'a> {
93149318
with_hints,
93159319
version,
93169320
partitions,
9321+
with_ordinality,
93179322
};
93189323

93199324
while let Some(kw) = self.parse_one_of_keywords(&[Keyword::PIVOT, Keyword::UNPIVOT]) {

src/test_utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ pub fn table(name: impl Into<String>) -> TableFactor {
309309
with_hints: vec![],
310310
version: None,
311311
partitions: vec![],
312+
with_ordinality: false,
312313
}
313314
}
314315

@@ -323,6 +324,7 @@ pub fn table_with_alias(name: impl Into<String>, alias: impl Into<String>) -> Ta
323324
with_hints: vec![],
324325
version: None,
325326
partitions: vec![],
327+
with_ordinality: false,
326328
}
327329
}
328330

tests/sqlparser_bigquery.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ fn parse_delete_statement() {
224224
with_hints: vec![],
225225
version: None,
226226
partitions: vec![],
227+
with_ordinality: false,
227228
},
228229
from[0].relation
229230
);
@@ -1353,6 +1354,7 @@ fn parse_table_identifiers() {
13531354
with_hints: vec![],
13541355
version: None,
13551356
partitions: vec![],
1357+
with_ordinality: false,
13561358
},
13571359
joins: vec![]
13581360
},]
@@ -1525,6 +1527,7 @@ fn parse_table_time_travel() {
15251527
Value::SingleQuotedString(version)
15261528
))),
15271529
partitions: vec![],
1530+
with_ordinality: false,
15281531
},
15291532
joins: vec![]
15301533
},]
@@ -1551,7 +1554,8 @@ fn parse_join_constraint_unnest_alias() {
15511554
Ident::new("a")
15521555
])],
15531556
with_offset: false,
1554-
with_offset_alias: None
1557+
with_offset_alias: None,
1558+
with_ordinality: false,
15551559
},
15561560
join_operator: JoinOperator::Inner(JoinConstraint::On(Expr::BinaryOp {
15571561
left: Box::new(Expr::Identifier("c1".into())),
@@ -1620,6 +1624,7 @@ fn parse_merge() {
16201624
with_hints: Default::default(),
16211625
version: Default::default(),
16221626
partitions: Default::default(),
1627+
with_ordinality: false,
16231628
},
16241629
table
16251630
);
@@ -1634,6 +1639,7 @@ fn parse_merge() {
16341639
with_hints: Default::default(),
16351640
version: Default::default(),
16361641
partitions: Default::default(),
1642+
with_ordinality: false,
16371643
},
16381644
source
16391645
);

tests/sqlparser_clickhouse.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fn parse_map_access_expr() {
5959
with_hints: vec![],
6060
version: None,
6161
partitions: vec![],
62+
with_ordinality: false,
6263
},
6364
joins: vec![],
6465
}],
@@ -162,6 +163,7 @@ fn parse_delimited_identifiers() {
162163
args,
163164
with_hints,
164165
version,
166+
with_ordinality: _,
165167
partitions: _,
166168
} => {
167169
assert_eq!(vec![Ident::with_quote('"', "a table")], name.0);

0 commit comments

Comments
 (0)