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

felipecrv pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new 16ff4d472 fix(rust/core): Handle the ASCII characters from sqlstate 
instead of their decimal values (#4141)
16ff4d472 is described below

commit 16ff4d472265c718bbc98a2eb378c857a2a21b99
Author: Felipe Oliveira Carvalho <[email protected]>
AuthorDate: Sun May 31 11:30:38 2026 -0300

    fix(rust/core): Handle the ASCII characters from sqlstate instead of their 
decimal values (#4141)
---
 rust/core/src/error.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 3 deletions(-)

diff --git a/rust/core/src/error.rs b/rust/core/src/error.rs
index 92671f7e9..772876e61 100644
--- a/rust/core/src/error.rs
+++ b/rust/core/src/error.rs
@@ -79,7 +79,8 @@ pub struct Error {
     /// A vendor-specific error code, if applicable.
     pub vendor_code: i32,
     /// A SQLSTATE error code, if provided, as defined by the SQL:2003 
standard.
-    /// If not set, it should be set to `\0\0\0\0\0`.
+    ///
+    /// If not set, it should be set to `"\0\0\0\0\0"` (all zeroes) or 
`"00000"` (48 ASCII).
     pub sqlstate: [c_char; 5], // TODO(alexandreyc): should we move to 
something else than c_char? (see 
https://github.com/apache/arrow-adbc/pull/1725#discussion_r1567531539)
     /// Additional metadata. Introduced in ADBC 1.1.0.
     pub details: Option<Vec<(String, Vec<u8>)>>,
@@ -102,10 +103,26 @@ impl Error {
 
 impl Display for Error {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        let safe_ascii = |c: c_char| -> char {
+            if c == 0 {
+                '0'
+            } else if (32..=126).contains(&c) {
+                char::from(c as u8)
+            } else {
+                '\u{FFFD}'
+            }
+        };
         write!(
             f,
-            "{:?}: {} (sqlstate: {:?}, vendor_code: {})",
-            self.status, self.message, self.sqlstate, self.vendor_code
+            "{:?}: {} (sqlstate: {}{}{}{}{}, vendor_code: {})",
+            self.status,
+            self.message,
+            safe_ascii(self.sqlstate[0]),
+            safe_ascii(self.sqlstate[1]),
+            safe_ascii(self.sqlstate[2]),
+            safe_ascii(self.sqlstate[3]),
+            safe_ascii(self.sqlstate[4]),
+            self.vendor_code
         )
     }
 }
@@ -207,3 +224,66 @@ impl From<Status> for AdbcStatusCode {
         }
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn display_unset_sqlstate() {
+        let err = Error::with_message_and_status("something failed", 
Status::Unknown);
+        let msg = err.to_string();
+        assert_eq!(
+            msg,
+            "Unknown: something failed (sqlstate: 00000, vendor_code: 0)"
+        );
+    }
+
+    #[test]
+    fn display_ascii_sqlstate() {
+        let err = Error {
+            message: "constraint violation".into(),
+            status: Status::Integrity,
+            vendor_code: 42,
+            sqlstate: [
+                b'2' as c_char,
+                b'3' as c_char,
+                b'5' as c_char,
+                b'0' as c_char,
+                b'5' as c_char,
+            ],
+            details: None,
+        };
+        let msg = err.to_string();
+        assert_eq!(
+            msg,
+            "Integrity: constraint violation (sqlstate: 23505, vendor_code: 
42)"
+        );
+    }
+
+    #[test]
+    fn display_non_printable_sqlstate() {
+        let err = Error {
+            message: "bad state".into(),
+            status: Status::Internal,
+            vendor_code: 0,
+            sqlstate: [1, 2, 3, 4, 5],
+            details: None,
+        };
+        let msg = err.to_string();
+        assert_eq!(msg, "Internal: bad state (sqlstate: �����, vendor_code: 
0)");
+    }
+
+    #[test]
+    fn display_mixed_sqlstate() {
+        let err = Error {
+            message: "mixed".into(),
+            status: Status::InvalidData,
+            vendor_code: 7,
+            sqlstate: [b'H' as c_char, b'V' as c_char, 0, 0, 1],
+            details: None,
+        };
+        let msg = err.to_string();
+        assert_eq!(msg, "InvalidData: mixed (sqlstate: HV00�, vendor_code: 
7)");
+    }
+}

Reply via email to