Repository: tikv/tikv
File: components/tidb_query_expr/src/impl_time.rs (Rust)

Code before:
        return Ok(Decimal::zero());
    }

    let time_in_decimal = Decimal::from(micro_time);
    let value: std::result::Result<Decimal, Error> = time_in_decimal
        .shift(-6)
        .into_result(ctx)?
        .round(frac, RoundMode::Truncate)
        .into();
    Ok(value?)
}

fn get_micro_timestamp(time: &DateTime, tz: &Tz) -> Result<i64> {
    let year = time.year() as i32;
    let month = time.month();
    let day = time.day();
    let hour = time.hour();
    let minute = time.minute();
    let second = time.second();
    let naive_date = chrono::NaiveDate::from_ymd(year, month, day);
    let naive_time = chrono::NaiveTime::from_hms_micro(hour, minute, second, time.micro());
    let naive_datetime = chrono::NaiveDateTime::new(naive_date, naive_time);

    // MySQL chooses earliest time when there are multi mapped time
    let res_opt = tz.from_local_datetime(&naive_datetime).earliest();
    let res = match res_opt {
        Some(val) => val,
        None => {
            let tz_opt = tz.get_chrono_tz();
            let chrono_tz = match tz_opt {
                Some(val) => val,
                None => return Err(Error::incorrect_parameters("Can't get chrono tz").into()),
            };

            // year, month, day, hour, minute and second is enough
            let time_with_tz = chrono::Utc
                .ymd(year, month, day)
                .and_hms(hour, minute, second)
                .with_timezone(&chrono_tz);
            let ret_res = find_zone_transition(time_with_tz);
            match ret_res {
                Ok(val) => return Ok(val.naive_utc().timestamp_micros()),
                Err(err) => return Err(err),
            }
        }
    };
    return Ok(res.naive_utc().timestamp_micros());
}

#[rpn_fn(capture = [ctx])]
#[inline]

Review comment (suggestion):
```suggestion
    let res = match tz.from_local_datetime(&naive_datetime).earliest() {
```

Code after:
    frac: i8,
) -> Result<Decimal> {
    if !(1000000..=32536771199999999).contains(&micro_time) {
        return Ok(Decimal::zero());
    }

    let time_in_decimal = Decimal::from(micro_time);
    let value: std::result::Result<Decimal, Error> = time_in_decimal
        .shift(-6)
        .into_result(ctx)?
        .round(frac, RoundMode::Truncate)
        .into();
    Ok(value?)
}

fn get_micro_timestamp(time: &DateTime, tz: &Tz) -> Result<i64> {
    let year = time.year() as i32;
    let month = time.month();
    let day = time.day();
    let hour = time.hour();
    let minute = time.minute();
    let second = time.second();
    let naive_date = chrono::NaiveDate::from_ymd(year, month, day);
    let naive_time = chrono::NaiveTime::from_hms_micro(hour, minute, second, time.micro());
    let naive_datetime = chrono::NaiveDateTime::new(naive_date, naive_time);

    // MySQL chooses earliest time when there are multi mapped time
    let res = match tz.from_local_datetime(&naive_datetime).earliest() {
        Some(val) => val,
        None => {
            let chrono_tz = match tz.get_chrono_tz() {
                Some(val) => val,
                None => return Err(Error::incorrect_parameters("Can't get chrono tz").into()),
            };

            // year, month, day, hour, minute and second is enough
            let time_with_tz = chrono::Utc
                .ymd(year, month, day)
                .and_hms(hour, minute, second)
                .with_timezone(&chrono_tz);
            match find_zone_transition(time_with_tz) {
                Ok(val) => return Ok(val.naive_utc().timestamp_micros()),
                Err(err) => return Err(err),
            }
        }
    };
    Ok(res.naive_utc().timestamp_micros())
}

#[rpn_fn(capture = [ctx])]
#[inline]