This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/paimon-rust.git
The following commit(s) were added to refs/heads/main by this push:
new 57448476 [core] Accept canonical REST identifier casing (#1110)
57448476 is described below
commit 5744847670e03b2666aa5c0088e546cf22979fa1
Author: shyjsarah <[email protected]>
AuthorDate: Mon Oct 12 23:28:45 2026 +0800
[core] Accept canonical REST identifier casing (#1110)
---
crates/paimon/src/table/rest_env.rs | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/crates/paimon/src/table/rest_env.rs
b/crates/paimon/src/table/rest_env.rs
index 48ad5e19..b8cdc314 100644
--- a/crates/paimon/src/table/rest_env.rs
+++ b/crates/paimon/src/table/rest_env.rs
@@ -557,7 +557,12 @@ fn response_identifier(
})?;
let identifier = Identifier::new(database, name);
identifier.validate()?;
- if &identifier != requested {
+ // A REST catalog may return the canonical case for an otherwise matching
identifier.
+ if !identifier
+ .database()
+ .eq_ignore_ascii_case(requested.database())
+ || !identifier.object().eq_ignore_ascii_case(requested.object())
+ {
return Err(Error::DataInvalid {
message: format!(
"Table response identifier '{}' does not match requested
identifier '{}'",
@@ -628,6 +633,32 @@ mod tests {
use crate::common::CatalogOptions;
use crate::io::cache::create_local_cache;
+ #[test]
+ fn response_identifier_accepts_canonicalized_ascii_case() {
+ let requested = Identifier::new("Default", "MixedTable");
+ let response: GetTableResponse =
+
serde_json::from_str(r#"{"database":"default","name":"mixedtable"}"#).unwrap();
+
+ let actual = response_identifier(&requested, &response).unwrap();
+
+ assert_eq!(actual, Identifier::new("default", "mixedtable"));
+ }
+
+ #[test]
+ fn response_identifier_rejects_a_different_table() {
+ let requested = Identifier::new("default", "requested");
+ let response: GetTableResponse =
+
serde_json::from_str(r#"{"database":"default","name":"different"}"#).unwrap();
+
+ let error = response_identifier(&requested, &response).unwrap_err();
+
+ assert!(matches!(
+ error,
+ Error::DataInvalid { message, .. }
+ if message.contains("does not match requested identifier")
+ ));
+ }
+
#[tokio::test]
async fn
dependency_reads_preserve_the_outermost_identifier_and_catalog_options() {
let table = crate::table::rest_query_auth_table().await;