You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by fi...@apache.org on 2025/07/24 18:10:48 UTC

(datafusion) branch main updated: Chore: add unit tests for chr function (#16856)

This is an automated email from the ASF dual-hosted git repository.

findepi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 07516aa4a3 Chore: add unit tests for chr function (#16856)
07516aa4a3 is described below

commit 07516aa4a369aceb2ef2438fa81e5a87691f76a6
Author: Ruihang Xia <wa...@gmail.com>
AuthorDate: Thu Jul 24 11:10:43 2025 -0700

    Chore: add unit tests for chr function (#16856)
    
    * MINOR: add unit tests for chr function
    
    Signed-off-by: Ruihang Xia <wa...@gmail.com>
    
    * handle negative input
    
    Signed-off-by: Ruihang Xia <wa...@gmail.com>
    
    * fix clippy
    
    Signed-off-by: Ruihang Xia <wa...@gmail.com>
    
    * add more test cases
    
    Signed-off-by: Ruihang Xia <wa...@gmail.com>
    
    * add a surrogate codepoint case
    
    Signed-off-by: Ruihang Xia <wa...@gmail.com>
    
    ---------
    
    Signed-off-by: Ruihang Xia <wa...@gmail.com>
---
 datafusion/functions/src/string/chr.rs | 122 +++++++++++++++++++++++++++++++++
 1 file changed, 122 insertions(+)

diff --git a/datafusion/functions/src/string/chr.rs b/datafusion/functions/src/string/chr.rs
index a811de7fcc..718f96e4f1 100644
--- a/datafusion/functions/src/string/chr.rs
+++ b/datafusion/functions/src/string/chr.rs
@@ -49,6 +49,8 @@ pub fn chr(args: &[ArrayRef]) -> Result<ArrayRef> {
             Some(integer) => {
                 if integer == 0 {
                     return exec_err!("null character not permitted.");
+                } else if integer < 0 {
+                    return exec_err!("negative input not permitted.");
                 } else {
                     match core::char::from_u32(integer as u32) {
                         Some(c) => {
@@ -132,3 +134,123 @@ impl ScalarUDFImpl for ChrFunc {
         self.doc()
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use arrow::array::{Array, Int64Array, StringArray};
+    use datafusion_common::assert_contains;
+
+    #[test]
+    fn test_chr_normal() {
+        let input = Arc::new(Int64Array::from(vec![
+            Some(65),       // A
+            Some(66),       // B
+            Some(67),       // C
+            Some(128640),   // 🚀
+            Some(8364),     // €
+            Some(945),      // α
+            None,           // NULL
+            Some(32),       // space
+            Some(10),       // newline
+            Some(9),        // tab
+            Some(0x10FFFF), // 0x10FFFF, the largest Unicode code point
+        ]));
+        let result = chr(&[input]).unwrap();
+        let string_array = result.as_any().downcast_ref::<StringArray>().unwrap();
+        let expected = [
+            "A",
+            "B",
+            "C",
+            "🚀",
+            "€",
+            "α",
+            "",
+            " ",
+            "\n",
+            "\t",
+            "\u{10ffff}",
+        ];
+
+        assert_eq!(string_array.len(), 11);
+        for (i, e) in expected.iter().enumerate() {
+            assert_eq!(string_array.value(i), *e);
+        }
+    }
+
+    #[test]
+    fn test_chr_error() {
+        // chr(0) returns an error
+        let input = Arc::new(Int64Array::from(vec![0]));
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "null character not permitted"
+        );
+
+        // invalid Unicode code points (too large)
+        let input = Arc::new(Int64Array::from(vec![i64::MAX]));
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "requested character too large for encoding"
+        );
+
+        // invalid Unicode code points (too large) case 2
+        let input = Arc::new(Int64Array::from(vec![0x10FFFF + 1]));
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "requested character too large for encoding"
+        );
+
+        // invalid Unicode code points (surrogate code point)
+        // link: <https://learn.microsoft.com/en-us/globalization/encoding/unicode-standard#surrogate-pairs>
+        let input = Arc::new(Int64Array::from(vec![0xD800 + 1]));
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "requested character too large for encoding"
+        );
+
+        // negative input
+        let input = Arc::new(Int64Array::from(vec![i64::MIN + 2i64])); // will be 2 if cast to u32
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "negative input not permitted"
+        );
+
+        // negative input case 2
+        let input = Arc::new(Int64Array::from(vec![-1]));
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "negative input not permitted"
+        );
+
+        // one error with valid values after
+        let input = Arc::new(Int64Array::from(vec![65, 0, 66])); // A, NULL_CHAR, B
+        let result = chr(&[input]);
+        assert!(result.is_err());
+        assert_contains!(
+            result.err().unwrap().to_string(),
+            "null character not permitted"
+        );
+    }
+
+    #[test]
+    fn test_chr_empty() {
+        // empty input array
+        let input = Arc::new(Int64Array::from(Vec::<i64>::new()));
+        let result = chr(&[input]).unwrap();
+        let string_array = result.as_any().downcast_ref::<StringArray>().unwrap();
+        assert_eq!(string_array.len(), 0);
+    }
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org