Skip to content

Commit 2992870

Browse files
refactor: Improve SessionContext::parse_duration API
1 parent 422b545 commit 2992870

File tree

3 files changed

+36
-10
lines changed

3 files changed

+36
-10
lines changed

datafusion/core/src/execution/context/mod.rs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ impl SessionContext {
11841184
builder.with_object_list_cache_limit(limit)
11851185
}
11861186
"list_files_cache_ttl" => {
1187-
let duration = Self::parse_duration(value)?;
1187+
let duration = Self::parse_duration(variable, value)?;
11881188
builder.with_object_list_cache_ttl(Some(duration))
11891189
}
11901190
_ => return plan_err!("Unknown runtime configuration: {variable}"),
@@ -1323,21 +1323,27 @@ impl SessionContext {
13231323
}
13241324
}
13251325

1326-
fn parse_duration(duration: &str) -> Result<Duration> {
1326+
fn parse_duration(config_name: &str, duration: &str) -> Result<Duration> {
1327+
if duration.trim().is_empty() {
1328+
return Err(plan_datafusion_err!(
1329+
"Duration should not be empty or blank for '{config_name}'"
1330+
));
1331+
}
1332+
13271333
let mut minutes = None;
13281334
let mut seconds = None;
13291335

13301336
for duration in duration.split_inclusive(&['m', 's']) {
13311337
let (number, unit) = duration.split_at(duration.len() - 1);
13321338
let number: u64 = number.parse().map_err(|_| {
1333-
plan_datafusion_err!("Failed to parse number from duration '{duration}'")
1339+
plan_datafusion_err!("Failed to parse number from duration '{duration}' for '{config_name}'")
13341340
})?;
13351341

13361342
match unit {
13371343
"m" if minutes.is_none() && seconds.is_none() => minutes = Some(number),
13381344
"s" if seconds.is_none() => seconds = Some(number),
1339-
_ => plan_err!(
1340-
"Invalid duration, unit must be either 'm' (minutes), or 's' (seconds), and be in the correct order"
1345+
other => plan_err!(
1346+
"Invalid duration unit: '{other}'. The unit must be either 'm' (minutes), or 's' (seconds), and be in the correct order for '{config_name}'"
13411347
)?,
13421348
}
13431349
}
@@ -1347,7 +1353,9 @@ impl SessionContext {
13471353
);
13481354

13491355
if duration.is_zero() {
1350-
return plan_err!("Duration must be greater than 0 seconds");
1356+
return plan_err!(
1357+
"Duration must be greater than 0 seconds for '{config_name}'"
1358+
);
13511359
}
13521360

13531361
Ok(duration)
@@ -2803,21 +2811,33 @@ mod tests {
28032811

28042812
#[test]
28052813
fn test_parse_duration() {
2814+
const LIST_FILES_CACHE_TTL: &str = "datafusion.runtime.list_files_cache_ttl";
2815+
28062816
// Valid durations
28072817
for (duration, want) in [
28082818
("1s", Duration::from_secs(1)),
28092819
("1m", Duration::from_secs(60)),
28102820
("1m0s", Duration::from_secs(60)),
28112821
("1m1s", Duration::from_secs(61)),
28122822
] {
2813-
let have = SessionContext::parse_duration(duration).unwrap();
2823+
let have =
2824+
SessionContext::parse_duration(LIST_FILES_CACHE_TTL, duration).unwrap();
28142825
assert_eq!(want, have);
28152826
}
28162827

28172828
// Invalid durations
2818-
for duration in ["0s", "0m", "1s0m", "1s1m"] {
2819-
let have = SessionContext::parse_duration(duration);
2829+
for duration in [
2830+
"0s", "0m", "1s0m", "1s1m", "XYZ", "1h", "XYZm2s", "", " ", "-1m", "1m 1s",
2831+
"1m1s ", " 1m1s",
2832+
] {
2833+
let have = SessionContext::parse_duration(LIST_FILES_CACHE_TTL, duration);
28202834
assert!(have.is_err());
2835+
assert!(
2836+
have.unwrap_err()
2837+
.message()
2838+
.to_string()
2839+
.contains(LIST_FILES_CACHE_TTL)
2840+
);
28212841
}
28222842
}
28232843

datafusion/sqllogictest/test_files/set_variable.slt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,3 +450,9 @@ datafusion.runtime.temp_directory
450450

451451
statement error DataFusion error: Error during planning: Unsupported value Null
452452
SET datafusion.runtime.memory_limit = NULL
453+
454+
statement error DataFusion error: Error during planning: Unsupported value Null
455+
SET datafusion.runtime.list_files_cache_ttl = NULL
456+
457+
statement error DataFusion error: Error during planning: Duration should not be empty or blank for 'datafusion.runtime.list_files_cache_ttl'
458+
SET datafusion.runtime.list_files_cache_ttl = ' '

docs/source/library-user-guide/upgrading/52.0.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ those changes until the `ListingTableProvider` instance is dropped and recreated
5151
You can configure the maximum cache size and cache entry expiration time via configuration options:
5252

5353
- `datafusion.runtime.list_files_cache_limit` - Limits the size of the cache in bytes
54-
- `datafusion.runtime.list_files_cache_ttl` - Limits the TTL (time-to-live) of an entry in seconds
54+
- `datafusion.runtime.list_files_cache_ttl` - Limits the TTL (time-to-live) of an entry in minutes and/or seconds
5555

5656
Detailed configuration information can be found in the [DataFusion Runtime
5757
Configuration](https://datafusion.apache.org/user-guide/configs.html#runtime-configuration-settings) user's guide.

0 commit comments

Comments
 (0)