Skip to content

Commit d6fbc21

Browse files
authored
Parse Snowflake COLLATE after double-colon casts (#20)
1 parent 1f22ac0 commit d6fbc21

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

src/parser/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4099,13 +4099,21 @@ impl<'a> Parser<'a> {
40994099
),
41004100
}
41014101
} else if Token::DoubleColon == *tok {
4102-
Ok(Expr::Cast {
4102+
let cast = Expr::Cast {
41034103
kind: CastKind::DoubleColon,
41044104
expr: Box::new(expr),
41054105
data_type: self.parse_data_type()?,
41064106
array: false,
41074107
format: None,
4108-
})
4108+
};
4109+
if dialect_of!(self is SnowflakeDialect) && self.parse_keyword(Keyword::COLLATE) {
4110+
Ok(Expr::Collate {
4111+
expr: Box::new(cast),
4112+
collation: self.parse_object_name(false)?,
4113+
})
4114+
} else {
4115+
Ok(cast)
4116+
}
41094117
} else if Token::ExclamationMark == *tok && self.dialect.supports_factorial_operator() {
41104118
Ok(Expr::UnaryOp {
41114119
op: UnaryOperator::PGPostfixFactorial,

tests/sqlparser_snowflake.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5105,6 +5105,18 @@ fn test_timestamp_ntz_with_precision() {
51055105
}
51065106
}
51075107

5108+
#[test]
5109+
fn test_collate_after_double_colon_cast() {
5110+
let select = snowflake().verified_only_select("SELECT 'ñ'::VARCHAR COLLATE 'es'");
5111+
match expr_from_projection(only(&select.projection)) {
5112+
Expr::Collate { expr, collation } => {
5113+
assert_eq!(collation.to_string(), "'es'");
5114+
assert!(matches!(expr.as_ref(), Expr::Cast { .. }));
5115+
}
5116+
expr => panic!("Expected COLLATE expression, got {expr:?}"),
5117+
}
5118+
}
5119+
51085120
#[test]
51095121
fn test_drop_constraints() {
51105122
snowflake().verified_stmt("ALTER TABLE tbl DROP PRIMARY KEY");

0 commit comments

Comments
 (0)