Skip to content

Commit b58cb88

Browse files
committed
Add support of table function WITH ORDINALITY modifier for Postgre Parser
This closes #1336
1 parent 17e5c0c commit b58cb88

16 files changed

+127
-2
lines changed

src/ast/query.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,10 @@ pub enum TableFactor {
905905
/// Optional version qualifier to facilitate table time-travel, as
906906
/// supported by BigQuery and MSSQL.
907907
version: Option<TableVersion>,
908+
// Optional table function modifier to generate the ordinality for column.
909+
/// For example, `SELECT * FROM generate_series(1, 10) WITH ORDINALITY AS t(a, b);`
910+
/// [WITH ORDINALITY](https://www.postgresql.org/docs/current/functions-srf.html), supported by Postgres.
911+
with_ordinality: bool,
908912
/// [Partition selection](https://dev.mysql.com/doc/refman/8.0/en/partitioning-selection.html), supported by MySQL.
909913
partitions: Vec<Ident>,
910914
},
@@ -1285,6 +1289,7 @@ impl fmt::Display for TableFactor {
12851289
with_hints,
12861290
version,
12871291
partitions,
1292+
with_ordinality,
12881293
} => {
12891294
write!(f, "{name}")?;
12901295
if !partitions.is_empty() {
@@ -1293,6 +1298,9 @@ impl fmt::Display for TableFactor {
12931298
if let Some(args) = args {
12941299
write!(f, "({})", display_comma_separated(args))?;
12951300
}
1301+
if *with_ordinality {
1302+
write!(f, " WITH ORDINALITY")?;
1303+
}
12961304
if let Some(alias) = alias {
12971305
write!(f, " AS {alias}")?;
12981306
}

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: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9216,6 +9216,18 @@ impl<'a> Parser<'a> {
92169216
None
92179217
};
92189218

9219+
let mut with_ordinality = false;
9220+
if dialect_of!(self is PostgreSqlDialect|GenericDialect)
9221+
&& self.parse_keyword(Keyword::WITH)
9222+
{
9223+
if self.parse_keyword(Keyword::ORDINALITY) {
9224+
with_ordinality = true;
9225+
} else {
9226+
// rewind, as WITH may belong to the next statement's CTE or hints
9227+
self.prev_token();
9228+
}
9229+
}
9230+
92199231
let alias = self.parse_optional_table_alias(keywords::RESERVED_FOR_TABLE_ALIAS)?;
92209232

92219233
// MSSQL-specific table hints:
@@ -9237,6 +9249,7 @@ impl<'a> Parser<'a> {
92379249
with_hints,
92389250
version,
92399251
partitions,
9252+
with_ordinality,
92409253
};
92419254

92429255
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: 5 additions & 0 deletions
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
},]
@@ -1620,6 +1623,7 @@ fn parse_merge() {
16201623
with_hints: Default::default(),
16211624
version: Default::default(),
16221625
partitions: Default::default(),
1626+
with_ordinality: false,
16231627
},
16241628
table
16251629
);
@@ -1634,6 +1638,7 @@ fn parse_merge() {
16341638
with_hints: Default::default(),
16351639
version: Default::default(),
16361640
partitions: Default::default(),
1641+
with_ordinality: false,
16371642
},
16381643
source
16391644
);

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)