Skip to content

Commit 9108bff

Browse files
authored
Add support of table function WITH ORDINALITY modifier for Postgre Parser (#1337)
1 parent 285f492 commit 9108bff

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
},
@@ -948,6 +952,7 @@ pub enum TableFactor {
948952
array_exprs: Vec<Expr>,
949953
with_offset: bool,
950954
with_offset_alias: Option<Ident>,
955+
with_ordinality: bool,
951956
},
952957
/// The `JSON_TABLE` table-valued function.
953958
/// Part of the SQL standard, but implemented only by MySQL, Oracle, and DB2.
@@ -1293,6 +1298,7 @@ impl fmt::Display for TableFactor {
12931298
with_hints,
12941299
version,
12951300
partitions,
1301+
with_ordinality,
12961302
} => {
12971303
write!(f, "{name}")?;
12981304
if !partitions.is_empty() {
@@ -1301,6 +1307,9 @@ impl fmt::Display for TableFactor {
13011307
if let Some(args) = args {
13021308
write!(f, "({})", display_comma_separated(args))?;
13031309
}
1310+
if *with_ordinality {
1311+
write!(f, " WITH ORDINALITY")?;
1312+
}
13041313
if let Some(alias) = alias {
13051314
write!(f, " AS {alias}")?;
13061315
}
@@ -1354,9 +1363,14 @@ impl fmt::Display for TableFactor {
13541363
array_exprs,
13551364
with_offset,
13561365
with_offset_alias,
1366+
with_ordinality,
13571367
} => {
13581368
write!(f, "UNNEST({})", display_comma_separated(array_exprs))?;
13591369

1370+
if *with_ordinality {
1371+
write!(f, " WITH ORDINALITY")?;
1372+
}
1373+
13601374
if let Some(alias) = alias {
13611375
write!(f, " AS {alias}")?;
13621376
}

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
@@ -9209,6 +9209,7 @@ impl<'a> Parser<'a> {
92099209
let array_exprs = self.parse_comma_separated(Parser::parse_expr)?;
92109210
self.expect_token(&Token::RParen)?;
92119211

9212+
let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]);
92129213
let alias = match self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS) {
92139214
Ok(Some(alias)) => Some(alias),
92149215
Ok(None) => None,
@@ -9235,6 +9236,7 @@ impl<'a> Parser<'a> {
92359236
array_exprs,
92369237
with_offset,
92379238
with_offset_alias,
9239+
with_ordinality,
92389240
})
92399241
} else if self.parse_keyword_with_tokens(Keyword::JSON_TABLE, &[Token::LParen]) {
92409242
let json_expr = self.parse_expr()?;
@@ -9273,6 +9275,8 @@ impl<'a> Parser<'a> {
92739275
None
92749276
};
92759277

9278+
let with_ordinality = self.parse_keywords(&[Keyword::WITH, Keyword::ORDINALITY]);
9279+
92769280
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
92779281

92789282
// MSSQL-specific table hints:
@@ -9294,6 +9298,7 @@ impl<'a> Parser<'a> {
92949298
with_hints,
92959299
version,
92969300
partitions,
9301+
with_ordinality,
92979302
};
92989303

92999304
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)