Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,11 @@ pub fn extract_sample_by_from_create_table(sql: &str) -> Option<String> {
if let Some(i) = after_upper.find("PRIMARY KEY") {
end = end.min(i);
}
// Note: Match " TTL" with leading space to avoid matching substrings
// within identifiers (e.g., "cattle" contains "ttl")
if let Some(i) = after_upper.find(" TTL") {
end = end.min(i);
}

let expr = after[..end].trim();
if expr.is_empty() {
Expand Down Expand Up @@ -1420,6 +1425,35 @@ pub mod tests {
);
}

#[test]
fn test_extract_sample_by_with_ttl_single_line() {
// When parsing CREATE TABLE with both SAMPLE BY and TTL,
// the parser needs to stop at TTL keyword to avoid capturing the TTL expression.
//
// Bug: Parser only checked for ORDER BY, SETTINGS, and PRIMARY KEY as terminators,
// so it extracted "sample_hash TTL toDateTime(...)" instead of just "sample_hash".
//
// This primarily affected tables created outside Moose (not in state storage).
// For Moose-managed tables, the correct value from state storage was used instead.
// Customer reported this when migrating external tables.
let sql = "CREATE TABLE t (id UInt64, ts DateTime) ENGINE = MergeTree ORDER BY (hour_stamp, sample_hash, ts) SAMPLE BY sample_hash TTL toDateTime(ts / 1000) + toIntervalDay(30) SETTINGS index_granularity = 8192";
assert_eq!(
extract_sample_by_from_create_table(sql),
Some("sample_hash".to_string())
);
}

#[test]
fn test_extract_sample_by_with_identifier_containing_ttl() {
// Edge case: Ensure identifiers containing "ttl" substring don't cause false matches
// "cattle" contains "ttl" when uppercased, but shouldn't be treated as TTL keyword
let sql = "CREATE TABLE t (id UInt64, cattle_count UInt64) ENGINE = MergeTree ORDER BY id SAMPLE BY cattle_count SETTINGS index_granularity = 8192";
assert_eq!(
extract_sample_by_from_create_table(sql),
Some("cattle_count".to_string())
);
}

#[test]
fn test_extract_indexes_from_create_table_multiple() {
let sql = "CREATE TABLE local.table_name (`u64` UInt64, `i32` Int32, `s` String, \
Expand Down
Loading