Skip to content

Commit 380f526

Browse files
authored
Fix parsing of EXTRACT to allow keywords after the FROM (#344)
1 parent c276b0d commit 380f526

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
### Fixes
1414
- Fix parsing of `EXTRACT` datetime parts `YEAR`, `TIMEZONE_HOUR`, and `TIMEZONE_MINUTE`
1515
- Fix logical plan to eval plan conversion for `EvalOrderBySortSpec` with arguments `DESC` and `NULLS LAST`
16+
- Fix parsing of `EXTRACT` to allow keywords after the `FROM`
1617

1718
## [0.3.0] - 2023-04-11
1819
### Changed

partiql-parser/src/preprocessor.rs

+57-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ mod built_ins {
9696
#[rustfmt::skip]
9797
patterns: vec![
9898
// e.g., extract(day from x) => extract("day":true, "from": x)
99-
vec![Id(re), Syn(Token::True), Kw(Token::From), AnyOne(true), AnyStar(false)]
99+
// Note the `true` passed to Any* as we need to support type-related keywords after `FROM`
100+
// such as `TIME WITH TIME ZONE`
101+
vec![Id(re), Syn(Token::True), Kw(Token::From), AnyOne(true), AnyStar(true)]
100102
],
101103
}
102104
}
@@ -907,6 +909,60 @@ mod tests {
907909
preprocess(r#"extract(second from a)"#)?,
908910
lex(r#"extract(second:True, "from" : a)"#)?
909911
);
912+
assert_eq!(
913+
preprocess(r#"extract(hour from TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?,
914+
lex(r#"extract(hour:True, "from" : TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?
915+
);
916+
assert_eq!(
917+
preprocess(r#"extract(minute from TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?,
918+
lex(r#"extract(minute:True, "from" : TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?
919+
);
920+
assert_eq!(
921+
preprocess(r#"extract(second from TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?,
922+
lex(r#"extract(second:True, "from" : TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?
923+
);
924+
assert_eq!(
925+
preprocess(r#"extract(timezone_hour from TIME WITH TIME ZONE '01:23:45.678-06:30')"#)?,
926+
lex(
927+
r#"extract(timezone_hour:True, "from" : TIME WITH TIME ZONE '01:23:45.678-06:30')"#
928+
)?
929+
);
930+
assert_eq!(
931+
preprocess(
932+
r#"extract(timezone_minute from TIME WITH TIME ZONE '01:23:45.678-06:30')"#
933+
)?,
934+
lex(
935+
r#"extract(timezone_minute:True, "from" : TIME WITH TIME ZONE '01:23:45.678-06:30')"#
936+
)?
937+
);
938+
assert_eq!(
939+
preprocess(r#"extract(hour from TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#)?,
940+
lex(r#"extract(hour:True, "from" : TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#)?
941+
);
942+
assert_eq!(
943+
preprocess(r#"extract(minute from TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#)?,
944+
lex(r#"extract(minute:True, "from" : TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#)?
945+
);
946+
assert_eq!(
947+
preprocess(r#"extract(second from TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#)?,
948+
lex(r#"extract(second:True, "from" : TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#)?
949+
);
950+
assert_eq!(
951+
preprocess(
952+
r#"extract(timezone_hour from TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#
953+
)?,
954+
lex(
955+
r#"extract(timezone_hour:True, "from" : TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#
956+
)?
957+
);
958+
assert_eq!(
959+
preprocess(
960+
r#"extract(timezone_minute from TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#
961+
)?,
962+
lex(
963+
r#"extract(timezone_minute:True, "from" : TIME (2) WITH TIME ZONE '01:23:45.678-06:30')"#
964+
)?
965+
);
910966

911967
assert_eq!(preprocess(r#"count(a)"#)?, lex(r#"count(a)"#)?);
912968
assert_eq!(

0 commit comments

Comments
 (0)