From 8dcd531ab8dad7140f5dbb05abb687f81c9c43f0 Mon Sep 17 00:00:00 2001 From: "boyu.wjb" Date: Mon, 26 Jan 2026 19:18:22 +0800 Subject: [PATCH 1/3] [chore] Implement is_auto_partitioned method in table.rs --- crates/fluss/src/metadata/table.rs | 164 ++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 2 deletions(-) diff --git a/crates/fluss/src/metadata/table.rs b/crates/fluss/src/metadata/table.rs index 3b9da7d..2db858a 100644 --- a/crates/fluss/src/metadata/table.rs +++ b/crates/fluss/src/metadata/table.rs @@ -19,7 +19,7 @@ use crate::compression::ArrowCompressionInfo; use crate::error::Error::{IllegalArgument, InvalidTableError}; use crate::error::{Error, Result}; use crate::metadata::DataLakeFormat; -use crate::metadata::datatype::{DataField, DataType, RowType}; +use crate::metadata::datatype::{DataField, DataType, DataTypes, RowType}; use crate::{BucketId, PartitionId, TableId}; use core::fmt; use serde::{Deserialize, Serialize}; @@ -784,6 +784,69 @@ impl TableInfo { } } +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct AutoPartitionStrategy { + auto_partition_enabled: bool, + auto_partition_key: Option, + auto_partition_time_unit: Option, + auto_partition_num_precreate: i32, + auto_partition_num_retention: i32, + auto_partition_timezone: String, +} + +impl AutoPartitionStrategy { + pub fn from(properties: &HashMap) -> Self { + Self { + auto_partition_enabled: properties + .get("table.auto.partition.enabled") + .and_then(|s| s.parse().ok()) + .unwrap_or(false), + auto_partition_key: properties + .get("table.auto.partition.key") + .map(|s| s.to_string()), + auto_partition_time_unit: properties + .get("table.auto.partition.time.unit") + .map(|s| s.to_string()), + auto_partition_num_precreate: properties + .get("table.auto.partition.num.precreate") + .and_then(|s| s.parse().ok()) + .unwrap_or(0), + auto_partition_num_retention: properties + .get("table.auto.partition.num.retention") + .and_then(|s| s.parse().ok()) + .unwrap_or(0), + auto_partition_timezone: properties + .get("table.auto.partition.timezone") + .map(|s| s.to_string()) + .unwrap_or_else(|| "UTC".to_string()), + } + } + + pub fn is_auto_partition_enabled(&self) -> bool { + self.auto_partition_enabled + } + + pub fn key(&self) -> Option<&str> { + self.auto_partition_key.as_deref() + } + + pub fn time_unit(&self) -> Option<&str> { + self.auto_partition_time_unit.as_deref() + } + + pub fn num_precreate(&self) -> i32 { + self.auto_partition_num_precreate + } + + pub fn num_retention(&self) -> i32 { + self.auto_partition_num_retention + } + + pub fn timezone(&self) -> &str { + &self.auto_partition_timezone + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct TableConfig { pub properties: HashMap, @@ -816,6 +879,10 @@ impl TableConfig { .unwrap_or(DEFAULT_KV_FORMAT); kv_format.parse().map_err(Into::into) } + + pub fn get_auto_partition_strategy(&self) -> AutoPartitionStrategy { + AutoPartitionStrategy::from(&self.properties) + } } impl TableInfo { @@ -953,7 +1020,11 @@ impl TableInfo { } pub fn is_auto_partitioned(&self) -> bool { - self.is_partitioned() && todo!() + self.is_partitioned() + && self + .table_config + .get_auto_partition_strategy() + .is_auto_partition_enabled() } pub fn get_partition_keys(&self) -> &[String] { @@ -1106,3 +1177,92 @@ impl LakeSnapshot { &self.table_buckets_offset } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_is_auto_partitioned() { + let schema = Schema::builder() + .column("id", DataTypes::int()) + .column("name", DataTypes::string()) + .primary_key(vec!["id".to_string()]) + .build() + .unwrap(); + + let table_path = TablePath::new("db".to_string(), "tbl".to_string()); + + // 1. Not partitioned, auto partition disabled + let mut properties = HashMap::new(); + let table_info = TableInfo::new( + table_path.clone(), + 1, + 1, + schema.clone(), + vec!["id".to_string()], + vec![], // No partition keys + 1, + properties.clone(), + HashMap::new(), + None, + 0, + 0, + ); + assert!(!table_info.is_auto_partitioned()); + + // 2. Not partitioned, auto partition enabled + properties.insert("table.auto.partition.enabled".to_string(), "true".to_string()); + let table_info = TableInfo::new( + table_path.clone(), + 1, + 1, + schema.clone(), + vec!["id".to_string()], + vec![], // No partition keys + 1, + properties.clone(), + HashMap::new(), + None, + 0, + 0, + ); + assert!(!table_info.is_auto_partitioned()); + + // 3. Partitioned, auto partition disabled + properties.insert("table.auto.partition.enabled".to_string(), "false".to_string()); + let table_info = TableInfo::new( + table_path.clone(), + 1, + 1, + schema.clone(), + vec!["id".to_string()], + vec!["name".to_string()], // Partition keys + 1, + properties.clone(), + HashMap::new(), + None, + 0, + 0, + ); + assert!(!table_info.is_auto_partitioned()); + + // 4. Partitioned, auto partition enabled + properties.insert("table.auto.partition.enabled".to_string(), "true".to_string()); + let table_info = TableInfo::new( + table_path.clone(), + 1, + 1, + schema.clone(), + vec!["id".to_string()], + vec!["name".to_string()], // Partition keys + 1, + properties.clone(), + HashMap::new(), + None, + 0, + 0, + ); + assert!(table_info.is_auto_partitioned()); + } +} From 31047c6f5e86b8f9274006492b2ab3b7364ee4ea Mon Sep 17 00:00:00 2001 From: "boyu.wjb" Date: Tue, 27 Jan 2026 09:23:21 +0800 Subject: [PATCH 2/3] code format --- crates/fluss/src/metadata/table.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/crates/fluss/src/metadata/table.rs b/crates/fluss/src/metadata/table.rs index 2db858a..f3fb82d 100644 --- a/crates/fluss/src/metadata/table.rs +++ b/crates/fluss/src/metadata/table.rs @@ -1212,7 +1212,10 @@ mod tests { assert!(!table_info.is_auto_partitioned()); // 2. Not partitioned, auto partition enabled - properties.insert("table.auto.partition.enabled".to_string(), "true".to_string()); + properties.insert( + "table.auto.partition.enabled".to_string(), + "true".to_string(), + ); let table_info = TableInfo::new( table_path.clone(), 1, @@ -1230,7 +1233,10 @@ mod tests { assert!(!table_info.is_auto_partitioned()); // 3. Partitioned, auto partition disabled - properties.insert("table.auto.partition.enabled".to_string(), "false".to_string()); + properties.insert( + "table.auto.partition.enabled".to_string(), + "false".to_string(), + ); let table_info = TableInfo::new( table_path.clone(), 1, @@ -1248,7 +1254,10 @@ mod tests { assert!(!table_info.is_auto_partitioned()); // 4. Partitioned, auto partition enabled - properties.insert("table.auto.partition.enabled".to_string(), "true".to_string()); + properties.insert( + "table.auto.partition.enabled".to_string(), + "true".to_string(), + ); let table_info = TableInfo::new( table_path.clone(), 1, From d74970e5241324edb613a1d9c9da14975b2d1dec Mon Sep 17 00:00:00 2001 From: "boyu.wjb" Date: Tue, 27 Jan 2026 12:14:22 +0800 Subject: [PATCH 3/3] fix(table): correct auto-partitioning configuration properties and default values --- crates/fluss/src/metadata/table.rs | 38 +++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/crates/fluss/src/metadata/table.rs b/crates/fluss/src/metadata/table.rs index f3fb82d..9c52d2d 100644 --- a/crates/fluss/src/metadata/table.rs +++ b/crates/fluss/src/metadata/table.rs @@ -788,7 +788,7 @@ impl TableInfo { pub struct AutoPartitionStrategy { auto_partition_enabled: bool, auto_partition_key: Option, - auto_partition_time_unit: Option, + auto_partition_time_unit: String, auto_partition_num_precreate: i32, auto_partition_num_retention: i32, auto_partition_timezone: String, @@ -798,27 +798,33 @@ impl AutoPartitionStrategy { pub fn from(properties: &HashMap) -> Self { Self { auto_partition_enabled: properties - .get("table.auto.partition.enabled") + .get("table.auto-partition.enabled") .and_then(|s| s.parse().ok()) .unwrap_or(false), auto_partition_key: properties - .get("table.auto.partition.key") + .get("table.auto-partition.key") .map(|s| s.to_string()), auto_partition_time_unit: properties - .get("table.auto.partition.time.unit") - .map(|s| s.to_string()), + .get("table.auto-partition.time-unit") + .map(|s| s.to_string()) + .unwrap_or_else(|| "DAY".to_string()), auto_partition_num_precreate: properties - .get("table.auto.partition.num.precreate") + .get("table.auto-partition.num-precreate") .and_then(|s| s.parse().ok()) - .unwrap_or(0), + .unwrap_or(2), auto_partition_num_retention: properties - .get("table.auto.partition.num.retention") + .get("table.auto-partition.num-retention") .and_then(|s| s.parse().ok()) - .unwrap_or(0), + .unwrap_or(7), auto_partition_timezone: properties - .get("table.auto.partition.timezone") + .get("table.auto-partition.time-zone") .map(|s| s.to_string()) - .unwrap_or_else(|| "UTC".to_string()), + .unwrap_or_else(|| { + jiff::tz::TimeZone::system() + .iana_name() + .unwrap_or("UTC") + .to_string() + }), } } @@ -830,8 +836,8 @@ impl AutoPartitionStrategy { self.auto_partition_key.as_deref() } - pub fn time_unit(&self) -> Option<&str> { - self.auto_partition_time_unit.as_deref() + pub fn time_unit(&self) -> &str { + &self.auto_partition_time_unit } pub fn num_precreate(&self) -> i32 { @@ -1213,7 +1219,7 @@ mod tests { // 2. Not partitioned, auto partition enabled properties.insert( - "table.auto.partition.enabled".to_string(), + "table.auto-partition.enabled".to_string(), "true".to_string(), ); let table_info = TableInfo::new( @@ -1234,7 +1240,7 @@ mod tests { // 3. Partitioned, auto partition disabled properties.insert( - "table.auto.partition.enabled".to_string(), + "table.auto-partition.enabled".to_string(), "false".to_string(), ); let table_info = TableInfo::new( @@ -1255,7 +1261,7 @@ mod tests { // 4. Partitioned, auto partition enabled properties.insert( - "table.auto.partition.enabled".to_string(), + "table.auto-partition.enabled".to_string(), "true".to_string(), ); let table_info = TableInfo::new(