This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-2490-25565b207ad1bdf4eccb0362b13bb35354191e8a in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git
commit 86fb33d493829a984451e54aa1b4a6758fa3c996 Author: Ben Herzberg <[email protected]> AuthorDate: Thu Sep 10 19:04:02 2026 +0000 Postgres: Fix parsing of COLLATE after :: cast (#2490) --- src/parser/mod.rs | 7 +++++++ tests/sqlparser_postgres.rs | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 2171548f..c23b2705 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -4202,6 +4202,13 @@ impl<'a> Parser<'a> { self.expected_ref("OF after MEMBER", self.peek_token_ref()) } } + // Reached when the dialect assigns `COLLATE` a lower precedence than `::`, e.g. + // Postgres's `expr::type COLLATE collation`. + // See <https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-PRECEDENCE> + Keyword::COLLATE => Ok(Expr::Collate { + expr: Box::new(expr), + collation: self.parse_object_name(false)?, + }), // Can only happen if `get_next_precedence` got out of sync with this function _ => parser_err!( format!("No infix parser for token {:?}", tok.token), diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index dfd883eb..8f390b5e 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -519,6 +519,19 @@ fn parse_cast_in_default_expr() { pg().verified_stmt("CREATE TABLE t (c TEXT DEFAULT (foo())::TEXT NOT NULL)"); } +/// `::` binds tighter than `COLLATE`, so `expr::type COLLATE collation` collates the cast result. +/// See <https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-PRECEDENCE> +#[test] +fn parse_collate_after_cast() { + match pg().verified_expr(r#"contact_name::TEXT COLLATE "POSIX""#) { + Expr::Collate { expr, collation } => { + assert!(matches!(*expr, Expr::Cast { .. })); + assert_eq!(collation.to_string(), "\"POSIX\""); + } + other => panic!("Expected Expr::Collate, got: {other:?}"), + } +} + #[test] fn parse_create_table_from_pg_dump() { let sql = "CREATE TABLE public.customer ( --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
