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-2493-667e81d7f5a682536725e9d9a64a6e62118cd21d
in repository https://gitbox.apache.org/repos/asf/datafusion-sqlparser-rs.git

commit ae67547ffc99f942fd929010ddfd6b724d5801e7
Author: Ben Herzberg <[email protected]>
AuthorDate: Thu Sep 24 11:13:46 2026 +0000

    Postgres: Support TRIM FROM syntax (#2493)
    
    Co-authored-by: Luca Cappelletti <[email protected]>
---
 src/parser/mod.rs           | 17 ++++++++++++++++-
 tests/sqlparser_common.rs   | 11 +++++++++++
 tests/sqlparser_postgres.rs |  5 +++++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index d48f00e44..bc64f63b7 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -3101,6 +3101,21 @@ impl<'a> Parser<'a> {
                 trim_where = Some(self.parse_trim_where()?);
             }
         }
+        if self.dialect.supports_comma_separated_trim() && 
self.parse_keyword(Keyword::FROM) {
+            let expr = self.parse_expr()?;
+            let trim_characters = if self.consume_token(&Token::Comma) {
+                Some(self.parse_comma_separated(Parser::parse_expr)?)
+            } else {
+                None
+            };
+            self.expect_token(&Token::RParen)?;
+            return Ok(Expr::Trim {
+                expr: Box::new(expr),
+                trim_where,
+                trim_what: None,
+                trim_characters,
+            });
+        }
         let expr = self.parse_expr()?;
         if self.parse_keyword(Keyword::FROM) {
             let trim_what = Box::new(expr);
@@ -3118,7 +3133,7 @@ impl<'a> Parser<'a> {
             self.expect_token(&Token::RParen)?;
             Ok(Expr::Trim {
                 expr: Box::new(expr),
-                trim_where: None,
+                trim_where,
                 trim_what: None,
                 trim_characters: Some(characters),
             })
diff --git a/tests/sqlparser_common.rs b/tests/sqlparser_common.rs
index 7dbcc91e5..78473dbdd 100644
--- a/tests/sqlparser_common.rs
+++ b/tests/sqlparser_common.rs
@@ -8528,6 +8528,11 @@ fn parse_trim() {
         expr_from_projection(only(&select.projection))
     );
 
+    dialects.one_statement_parses_to(
+        "SELECT TRIM(BOTH FROM 'yxTomxx', 'xyz')",
+        "SELECT TRIM(BOTH 'yxTomxx', 'xyz')",
+    );
+
     // dialects without comma-style TRIM syntax should fail
     let unsupported_dialects = all_dialects_where(|d| 
!d.supports_comma_separated_trim());
     assert_eq!(
@@ -8536,6 +8541,12 @@ fn parse_trim() {
             .parse_sql_statements("SELECT TRIM('xyz', 'a')")
             .unwrap_err()
     );
+    assert_eq!(
+        ParserError::ParserError("Expected: ), found: 'xyz'".to_owned()),
+        unsupported_dialects
+            .parse_sql_statements("SELECT TRIM(FROM 'xyz')")
+            .unwrap_err()
+    );
 }
 
 #[test]
diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs
index 1f4377219..23e20c718 100644
--- a/tests/sqlparser_postgres.rs
+++ b/tests/sqlparser_postgres.rs
@@ -9948,6 +9948,11 @@ fn parse_non_reserved_keywords_as_table_alias() {
     }
 }
 
+#[test]
+fn parse_trim_from_without_characters() {
+    pg().one_statement_parses_to("SELECT TRIM(FROM ' x ')", "SELECT TRIM(' x 
')");
+}
+
 #[test]
 fn parse_insert_by_name_keywords_as_table_and_alias() {
     // Without a table name, `BY NAME` is not an INSERT BY NAME clause. 
PostgreSQL


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to