Skip to content

Commit b9a400c

Browse files
authored
Merge branch 'main' into feature/2078-add-pgsql-reset-support
2 parents f69ff11 + 308a723 commit b9a400c

File tree

7 files changed

+73
-35
lines changed

7 files changed

+73
-35
lines changed

src/ast/data_type.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ pub enum DataType {
375375
/// Databricks timestamp without time zone. See [1].
376376
///
377377
/// [1]: https://docs.databricks.com/aws/en/sql/language-manual/data-types/timestamp-ntz-type
378-
TimestampNtz,
378+
TimestampNtz(Option<u64>),
379379
/// Interval type.
380380
Interval {
381381
/// [PostgreSQL] fields specification like `INTERVAL YEAR TO MONTH`.
@@ -676,7 +676,9 @@ impl fmt::Display for DataType {
676676
DataType::Timestamp(precision, timezone_info) => {
677677
format_datetime_precision_and_tz(f, "TIMESTAMP", precision, timezone_info)
678678
}
679-
DataType::TimestampNtz => write!(f, "TIMESTAMP_NTZ"),
679+
DataType::TimestampNtz(precision) => {
680+
format_type_with_optional_length(f, "TIMESTAMP_NTZ", precision, false)
681+
}
680682
DataType::Datetime64(precision, timezone) => {
681683
format_clickhouse_datetime_precision_and_timezone(
682684
f,

src/ast/operator.rs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,35 @@ use super::display_separated;
3333
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
3434
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
3535
pub enum UnaryOperator {
36+
/// `@-@` Length or circumference (PostgreSQL/Redshift geometric operator)
37+
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
38+
AtDashAt,
39+
/// Unary logical not operator: e.g. `! false` (Hive-specific)
40+
BangNot,
41+
/// Bitwise Not, e.g. `~9`
42+
BitwiseNot,
43+
/// `@@` Center (PostgreSQL/Redshift geometric operator)
44+
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
45+
DoubleAt,
46+
/// `#` Number of points in path or polygon (PostgreSQL/Redshift geometric operator)
47+
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
48+
Hash,
3649
/// Plus, e.g. `+9`
3750
Plus,
3851
/// Minus, e.g. `-9`
3952
Minus,
4053
/// Not, e.g. `NOT(true)`
4154
Not,
42-
/// Bitwise Not, e.g. `~9` (PostgreSQL-specific)
43-
PGBitwiseNot,
44-
/// Square root, e.g. `|/9` (PostgreSQL-specific)
45-
PGSquareRoot,
55+
/// Absolute value, e.g. `@ -9` (PostgreSQL-specific)
56+
PGAbs,
4657
/// Cube root, e.g. `||/27` (PostgreSQL-specific)
4758
PGCubeRoot,
4859
/// Factorial, e.g. `9!` (PostgreSQL-specific)
4960
PGPostfixFactorial,
5061
/// Factorial, e.g. `!!9` (PostgreSQL-specific)
5162
PGPrefixFactorial,
52-
/// Absolute value, e.g. `@ -9` (PostgreSQL-specific)
53-
PGAbs,
54-
/// Unary logical not operator: e.g. `! false` (Hive-specific)
55-
BangNot,
56-
/// `#` Number of points in path or polygon (PostgreSQL/Redshift geometric operator)
57-
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
58-
Hash,
59-
/// `@-@` Length or circumference (PostgreSQL/Redshift geometric operator)
60-
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
61-
AtDashAt,
62-
/// `@@` Center (PostgreSQL/Redshift geometric operator)
63-
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
64-
DoubleAt,
63+
/// Square root, e.g. `|/9` (PostgreSQL-specific)
64+
PGSquareRoot,
6565
/// `?-` Is horizontal? (PostgreSQL/Redshift geometric operator)
6666
/// see <https://www.postgresql.org/docs/9.5/functions-geometry.html>
6767
QuestionDash,
@@ -73,19 +73,19 @@ pub enum UnaryOperator {
7373
impl fmt::Display for UnaryOperator {
7474
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
7575
f.write_str(match self {
76-
UnaryOperator::Plus => "+",
76+
UnaryOperator::AtDashAt => "@-@",
77+
UnaryOperator::BangNot => "!",
78+
UnaryOperator::BitwiseNot => "~",
79+
UnaryOperator::DoubleAt => "@@",
80+
UnaryOperator::Hash => "#",
7781
UnaryOperator::Minus => "-",
7882
UnaryOperator::Not => "NOT",
79-
UnaryOperator::PGBitwiseNot => "~",
80-
UnaryOperator::PGSquareRoot => "|/",
83+
UnaryOperator::PGAbs => "@",
8184
UnaryOperator::PGCubeRoot => "||/",
8285
UnaryOperator::PGPostfixFactorial => "!",
8386
UnaryOperator::PGPrefixFactorial => "!!",
84-
UnaryOperator::PGAbs => "@",
85-
UnaryOperator::BangNot => "!",
86-
UnaryOperator::Hash => "#",
87-
UnaryOperator::AtDashAt => "@-@",
88-
UnaryOperator::DoubleAt => "@@",
87+
UnaryOperator::PGSquareRoot => "|/",
88+
UnaryOperator::Plus => "+",
8989
UnaryOperator::QuestionDash => "?-",
9090
UnaryOperator::QuestionPipe => "?|",
9191
})

src/parser/mod.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,15 +1634,13 @@ impl<'a> Parser<'a> {
16341634
| tok @ Token::PGSquareRoot
16351635
| tok @ Token::PGCubeRoot
16361636
| tok @ Token::AtSign
1637-
| tok @ Token::Tilde
16381637
if dialect_is!(dialect is PostgreSqlDialect) =>
16391638
{
16401639
let op = match tok {
16411640
Token::DoubleExclamationMark => UnaryOperator::PGPrefixFactorial,
16421641
Token::PGSquareRoot => UnaryOperator::PGSquareRoot,
16431642
Token::PGCubeRoot => UnaryOperator::PGCubeRoot,
16441643
Token::AtSign => UnaryOperator::PGAbs,
1645-
Token::Tilde => UnaryOperator::PGBitwiseNot,
16461644
_ => unreachable!(),
16471645
};
16481646
Ok(Expr::UnaryOp {
@@ -1652,6 +1650,10 @@ impl<'a> Parser<'a> {
16521650
),
16531651
})
16541652
}
1653+
Token::Tilde => Ok(Expr::UnaryOp {
1654+
op: UnaryOperator::BitwiseNot,
1655+
expr: Box::new(self.parse_subexpr(self.dialect.prec_value(Precedence::PlusMinus))?),
1656+
}),
16551657
tok @ Token::Sharp
16561658
| tok @ Token::AtDashAt
16571659
| tok @ Token::AtAt
@@ -10543,7 +10545,9 @@ impl<'a> Parser<'a> {
1054310545
self.parse_optional_precision()?,
1054410546
TimezoneInfo::Tz,
1054510547
)),
10546-
Keyword::TIMESTAMP_NTZ => Ok(DataType::TimestampNtz),
10548+
Keyword::TIMESTAMP_NTZ => {
10549+
Ok(DataType::TimestampNtz(self.parse_optional_precision()?))
10550+
}
1054710551
Keyword::TIME => {
1054810552
let precision = self.parse_optional_precision()?;
1054910553
let tz = if self.parse_keyword(Keyword::WITH) {

tests/sqlparser_common.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17614,6 +17614,25 @@ fn test_parse_alter_user() {
1761417614
verified_stmt("ALTER USER u1 SET DEFAULT_SECONDARY_ROLES=('ALL'), PASSWORD='secret', WORKLOAD_IDENTITY=(TYPE=AWS, ARN='arn:aws:iam::123456789:r1/')");
1761517615
}
1761617616

17617+
#[test]
17618+
fn parse_generic_unary_ops() {
17619+
let unary_ops = &[
17620+
("~", UnaryOperator::BitwiseNot),
17621+
("-", UnaryOperator::Minus),
17622+
("+", UnaryOperator::Plus),
17623+
];
17624+
for (str_op, op) in unary_ops {
17625+
let select = verified_only_select(&format!("SELECT {}expr", &str_op));
17626+
assert_eq!(
17627+
UnnamedExpr(UnaryOp {
17628+
op: *op,
17629+
expr: Box::new(Identifier(Ident::new("expr"))),
17630+
}),
17631+
select.projection[0]
17632+
);
17633+
}
17634+
}
17635+
1761717636
#[test]
1761817637
fn parse_reset_statement() {
1761917638
match verified_stmt("RESET some_parameter") {

tests/sqlparser_databricks.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ fn data_type_timestamp_ntz() {
328328
assert_eq!(
329329
databricks().verified_expr("TIMESTAMP_NTZ '2025-03-29T18:52:00'"),
330330
Expr::TypedString(TypedString {
331-
data_type: DataType::TimestampNtz,
331+
data_type: DataType::TimestampNtz(None),
332332
value: ValueWithSpan {
333333
value: Value::SingleQuotedString("2025-03-29T18:52:00".to_owned()),
334334
span: Span::empty(),
@@ -345,7 +345,7 @@ fn data_type_timestamp_ntz() {
345345
expr: Box::new(Expr::Nested(Box::new(Expr::Identifier(
346346
"created_at".into()
347347
)))),
348-
data_type: DataType::TimestampNtz,
348+
data_type: DataType::TimestampNtz(None),
349349
format: None
350350
}
351351
);
@@ -357,7 +357,7 @@ fn data_type_timestamp_ntz() {
357357
columns,
358358
vec![ColumnDef {
359359
name: "x".into(),
360-
data_type: DataType::TimestampNtz,
360+
data_type: DataType::TimestampNtz(None),
361361
options: vec![],
362362
}]
363363
);

tests/sqlparser_postgres.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,13 +2144,11 @@ fn parse_ampersand_arobase() {
21442144
#[test]
21452145
fn parse_pg_unary_ops() {
21462146
let pg_unary_ops = &[
2147-
("~", UnaryOperator::PGBitwiseNot),
21482147
("|/", UnaryOperator::PGSquareRoot),
21492148
("||/", UnaryOperator::PGCubeRoot),
21502149
("!!", UnaryOperator::PGPrefixFactorial),
21512150
("@", UnaryOperator::PGAbs),
21522151
];
2153-
21542152
for (str_op, op) in pg_unary_ops {
21552153
let select = pg().verified_only_select(&format!("SELECT {}a", &str_op));
21562154
assert_eq!(

tests/sqlparser_snowflake.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4638,6 +4638,21 @@ fn test_create_database() {
46384638
assert!(err.contains("Expected"), "Unexpected error: {err}");
46394639
}
46404640

4641+
#[test]
4642+
fn test_timestamp_ntz_with_precision() {
4643+
snowflake().verified_stmt("SELECT CAST('2024-01-01 01:00:00' AS TIMESTAMP_NTZ(1))");
4644+
snowflake().verified_stmt("SELECT CAST('2024-01-01 01:00:00' AS TIMESTAMP_NTZ(9))");
4645+
4646+
let select =
4647+
snowflake().verified_only_select("SELECT CAST('2024-01-01 01:00:00' AS TIMESTAMP_NTZ(9))");
4648+
match expr_from_projection(only(&select.projection)) {
4649+
Expr::Cast { data_type, .. } => {
4650+
assert_eq!(*data_type, DataType::TimestampNtz(Some(9)));
4651+
}
4652+
_ => unreachable!(),
4653+
}
4654+
}
4655+
46414656
#[test]
46424657
fn test_drop_constraints() {
46434658
snowflake().verified_stmt("ALTER TABLE tbl DROP PRIMARY KEY");

0 commit comments

Comments
 (0)