diff --git a/crates/paimon/src/catalog/rest/rest_catalog.rs b/crates/paimon/src/catalog/rest/rest_catalog.rs index 1da2aa16..889b720e 100644 --- a/crates/paimon/src/catalog/rest/rest_catalog.rs +++ b/crates/paimon/src/catalog/rest/rest_catalog.rs @@ -250,8 +250,12 @@ impl Catalog for RESTCatalog { RESTTokenFileIO::new(identifier.clone(), table_path.clone(), self.options.clone()); token_file_io.build_file_io().await? } else { - // Use standard FileIO from path - FileIO::from_path(&table_path)?.build()? + // Mirrors Java RESTCatalog.fileIOFromOptions: build FileIO from + // catalog options so OSS-backed paths can pick up the + // user-supplied `fs.oss.*` keys. + let mut builder = FileIO::from_path(&table_path)?; + builder = builder.with_props(self.options.to_map()); + builder.build()? }; let rest_env = RESTEnv::new(identifier.clone(), uuid, self.api.clone()); diff --git a/crates/paimon/tests/rest_catalog_test.rs b/crates/paimon/tests/rest_catalog_test.rs index 958d50bd..2166b44d 100644 --- a/crates/paimon/tests/rest_catalog_test.rs +++ b/crates/paimon/tests/rest_catalog_test.rs @@ -263,6 +263,56 @@ async fn test_catalog_get_table_not_found() { assert!(result.is_err(), "getting non-existent table should fail"); } +/// When no data token is vended (`data_token_enabled=false` or external +/// table), `get_table` must propagate catalog options to FileIO so an +/// OSS-pathed table picks up `fs.oss.*` keys. Java parity: +/// `RESTCatalog.fileIOFromOptions`. +#[tokio::test] +async fn test_catalog_get_table_propagates_oss_options_in_else_branch() { + let prefix = "mock-test"; + let mut defaults = HashMap::new(); + defaults.insert("prefix".to_string(), prefix.to_string()); + let config = ConfigResponse::new(defaults); + + let server = start_mock_server( + "test_warehouse".to_string(), + "/tmp/test_warehouse".to_string(), + config, + vec!["default".to_string()], + ) + .await; + + let url = server.url().expect("Failed to get server URL"); + let mut options = Options::new(); + options.set("uri", &url); + options.set("warehouse", "test_warehouse"); + options.set("token.provider", "bear"); + options.set("token", "test_token"); + options.set("fs.oss.endpoint", "https://oss-cn-shanghai.aliyuncs.com"); + options.set("fs.oss.accessKeyId", "test-ak"); + options.set("fs.oss.accessKeySecret", "test-sk"); + + let catalog = RESTCatalog::new(options, true) + .await + .expect("create catalog"); + + let schema = test_schema(); + server.add_table_with_schema( + "default", + "oss_table", + schema, + "oss://test-bucket/warehouse/default.db/oss_table", + ); + + let identifier = Identifier::new("default", "oss_table"); + let result = catalog.get_table(&identifier).await; + assert!( + result.is_ok(), + "expected get_table to succeed when fs.oss.* keys are present in catalog options; \ + got {result:?}" + ); +} + #[tokio::test] async fn test_catalog_create_table() { let ctx = setup_catalog(vec!["default"]).await;