Skip to content

Commit d0e2efb

Browse files
authored
feat(table): add primary-key full-text read data layer (#594)
1 parent 4c70d28 commit d0e2efb

12 files changed

Lines changed: 815 additions & 116 deletions

crates/paimon/src/spec/core_options.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ pub(crate) const BLOB_DESCRIPTOR_FIELD_OPTION: &str = "blob-descriptor-field";
123123
pub(crate) const BLOB_VIEW_FIELD_OPTION: &str = "blob-view-field";
124124
pub const BLOB_VIEW_RESOLVE_ENABLED_OPTION: &str = "blob-view.resolve.enabled";
125125
const PK_VECTOR_INDEX_COLUMNS_OPTION: &str = "pk-vector.index.columns";
126+
const PK_FULL_TEXT_INDEX_COLUMNS_OPTION: &str = "pk-full-text.index.columns";
126127

127128
/// Merge engine for primary-key tables.
128129
///
@@ -1198,6 +1199,23 @@ impl<'a> CoreOptions<'a> {
11981199
crate::vindex::pkvector::metric::VectorSearchMetric::parse(&raw)?;
11991200
Ok(raw)
12001201
}
1202+
1203+
/// True when the PK full-text index column option key is present (any value).
1204+
pub fn primary_key_full_text_index_enabled(&self) -> bool {
1205+
self.options.contains_key(PK_FULL_TEXT_INDEX_COLUMNS_OPTION)
1206+
}
1207+
1208+
/// Configured PK full-text index columns: split on ',' and trim each token,
1209+
/// mirroring Java `split(",",-1).map(trim)`. Blank tokens are PRESERVED (do NOT
1210+
/// filter them) so parsing matches Java exactly; `[]` only when the key is
1211+
/// absent. Never returns a `Result`, never errors (do not copy the fail-loud
1212+
/// shape of `primary_key_vector_index_columns`).
1213+
pub fn primary_key_full_text_index_columns(&self) -> Vec<String> {
1214+
match self.options.get(PK_FULL_TEXT_INDEX_COLUMNS_OPTION) {
1215+
None => Vec::new(),
1216+
Some(raw) => raw.split(',').map(|c| c.trim().to_string()).collect(),
1217+
}
1218+
}
12011219
}
12021220

12031221
/// Parse a memory size string to bytes using binary (1024-based) semantics.
@@ -2147,4 +2165,56 @@ mod tests {
21472165
.primary_key_vector_index_type("e")
21482166
.is_err());
21492167
}
2168+
2169+
#[test]
2170+
fn test_pk_full_text_index_absent_is_disabled_and_empty() {
2171+
let opts = HashMap::new();
2172+
let co = CoreOptions::new(&opts);
2173+
assert!(!co.primary_key_full_text_index_enabled());
2174+
assert_eq!(
2175+
co.primary_key_full_text_index_columns(),
2176+
Vec::<String>::new()
2177+
);
2178+
}
2179+
2180+
#[test]
2181+
fn test_pk_full_text_index_columns_split_and_trim() {
2182+
let opts = HashMap::from([(
2183+
"pk-full-text.index.columns".to_string(),
2184+
"a, b ,c".to_string(),
2185+
)]);
2186+
let co = CoreOptions::new(&opts);
2187+
assert!(co.primary_key_full_text_index_enabled());
2188+
assert_eq!(
2189+
co.primary_key_full_text_index_columns(),
2190+
vec!["a".to_string(), "b".to_string(), "c".to_string()]
2191+
);
2192+
}
2193+
2194+
#[test]
2195+
fn test_pk_full_text_index_columns_preserve_blank_tokens() {
2196+
// Java `split(",",-1).map(trim)` keeps empty tokens, so "a,,b" yields
2197+
// three columns with a blank in the middle.
2198+
let opts = HashMap::from([("pk-full-text.index.columns".to_string(), "a,,b".to_string())]);
2199+
let co = CoreOptions::new(&opts);
2200+
assert!(co.primary_key_full_text_index_enabled());
2201+
assert_eq!(
2202+
co.primary_key_full_text_index_columns(),
2203+
vec!["a".to_string(), "".to_string(), "b".to_string()]
2204+
);
2205+
}
2206+
2207+
#[test]
2208+
fn test_pk_full_text_index_blank_value_is_enabled_but_empty_no_error() {
2209+
// key present but only blanks: enabled (key exists), NO error (lenient,
2210+
// unlike vector). Blank tokens are PRESERVED to match Java's
2211+
// `split(",",-1).map(trim)`, so " , " yields two empty tokens (NOT []).
2212+
let opts = HashMap::from([("pk-full-text.index.columns".to_string(), " , ".to_string())]);
2213+
let co = CoreOptions::new(&opts);
2214+
assert!(co.primary_key_full_text_index_enabled());
2215+
assert_eq!(
2216+
co.primary_key_full_text_index_columns(),
2217+
vec!["".to_string(), "".to_string()]
2218+
);
2219+
}
21502220
}

crates/paimon/src/spec/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ pub use manifest_file_meta::*;
6464
mod index_file_meta;
6565
pub use index_file_meta::*;
6666

67-
mod pk_vector_source;
68-
pub use pk_vector_source::*;
67+
mod pk_index_source;
68+
pub use pk_index_source::*;
6969

7070
mod index_manifest;
7171
pub use index_manifest::{IndexManifest, IndexManifestEntry};

0 commit comments

Comments
 (0)