{"record":{"id":"3678db255fd30329","repo":"databendlabs/databend","slug":"midnight-is-valid","errorCode":null,"errorMessage":"midnight is valid","messagePattern":"midnight is valid","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src/query/expression/src/types/timestamp_tz.rs","lineNumber":267,"sourceCode":"    build_timestamp_tz(micros, resolved.offset_seconds)\n}\n\n#[inline]\npub fn string_to_timestamp_tz<'a, F: FnOnce() -> &'a Tz>(\n    ts_str: &[u8],\n    fn_tz: F,\n) -> databend_common_exception::Result<timestamp_tz> {\n    if let Some(parsed) = try_parse_standard_timestamp_with_offset(ts_str) {\n        return parsed;\n    }\n\n    let text = std::str::from_utf8(ts_str)\n        .map_err(|_| ErrorCode::BadBytes(\"Timestamp text is not valid UTF-8\".to_string()))?\n        .trim();\n\n    // A bare date is midnight in the session timezone.\n    if let Ok(date) = NaiveDate::parse_from_str(text, \"%Y-%m-%d\") {\n        let local = date.and_hms_opt(0, 0, 0).expect(\"midnight is valid\");\n        return timestamp_tz_from_local(&local, fn_tz());\n    }\n\n    for format in PARSE_FORMATS_WITH_OFFSET {\n        if let Ok(value) = DateTime::parse_from_str(text, format) {\n            check_input_year(value.year())?;\n            check_timezone_offset(value.offset().local_minus_utc())?;\n            let micros = i128::from(value.timestamp()) * 1_000_000\n                + i128::from(value.timestamp_subsec_micros());\n            return build_timestamp_tz(micros, value.offset().local_minus_utc());\n        }\n    }\n\n    for format in PARSE_FORMATS_NAIVE {\n        if let Ok(local) = NaiveDateTime::parse_from_str(text, format) {\n            return timestamp_tz_from_local(&local, fn_tz());\n        }\n    }","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/expression/src/types/timestamp_tz.rs#L249-L285","documentation":"string_to_timestamp_tz parses timestamp text; when the text is a bare date (YYYY-MM-DD), it treats it as midnight in the session timezone via date.and_hms_opt(0,0,0). The expect('midnight is valid') fires only if chrono cannot construct midnight on the parsed date — impossible for any NaiveDate that successfully parsed from %Y-%m-%d, making it an invariant assertion rather than an input check.","triggerScenarios":"Effectively never: any NaiveDate parseable from '%Y-%m-%d' supports 00:00:00. Could only fire on chrono regression or if the parsing path is changed to allow out-of-range hour components.","commonSituations":"Not user-reachable; encountered only when modifying the parse formats or chrono versions.","solutions":["No caller action needed; input issues surface as ErrorCode::BadBytes or the check_input_year error instead.","Keep the format constant '%Y-%m-%d' in sync with and_hms_opt usage if refactoring."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Not required; bare-date inputs return proper errors for bad UTF-8/year.\nlet ts = string_to_timestamp_tz(text, &tz)?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["No guard needed; invalid timestamps surface as ErrorCode::BadBytes or year-check errors, not this panic."],"tags":["panic","timestamp","parsing","unreachable"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}