use chrono::{DateTime, NaiveDateTime, Utc};
use mz_ore::result::ResultExt;
use mz_repr::adt::numeric::Numeric;
use mz_repr::adt::timestamp::CheckedTimestamp;
use mz_repr::{strconv, Timestamp};
use crate::EvalError;
sqlfunc!(
#[sqlname = "mz_timestamp_to_text"]
#[preserves_uniqueness = true]
#[inverse = to_unary!(super::CastStringToMzTimestamp)]
fn cast_mz_timestamp_to_string(a: Timestamp) -> String {
let mut buf = String::new();
strconv::format_mz_timestamp(&mut buf, a);
buf
}
);
sqlfunc!(
#[sqlname = "text_to_mz_timestamp"]
#[preserves_uniqueness = false]
#[inverse = to_unary!(super::CastMzTimestampToString)]
fn cast_string_to_mz_timestamp(a: String) -> Result<Timestamp, EvalError> {
strconv::parse_mz_timestamp(&a).err_into()
}
);
sqlfunc!(
#[sqlname = "numeric_to_mz_timestamp"]
#[preserves_uniqueness = true]
#[is_monotone = true]
fn cast_numeric_to_mz_timestamp(a: Numeric) -> Result<Timestamp, EvalError> {
a.try_into()
.map_err(|_| EvalError::MzTimestampOutOfRange(a.to_string()))
}
);
sqlfunc!(
#[sqlname = "uint8_to_mz_timestamp"]
#[preserves_uniqueness = true]
#[is_monotone = true]
fn cast_uint64_to_mz_timestamp(a: u64) -> Timestamp {
a.into()
}
);
sqlfunc!(
#[sqlname = "uint4_to_mz_timestamp"]
#[preserves_uniqueness = true]
#[is_monotone = true]
fn cast_uint32_to_mz_timestamp(a: u32) -> Timestamp {
u64::from(a).into()
}
);
sqlfunc!(
#[sqlname = "bigint_to_mz_timestamp"]
#[preserves_uniqueness = true]
#[is_monotone = true]
fn cast_int64_to_mz_timestamp(a: i64) -> Result<Timestamp, EvalError> {
a.try_into()
.map_err(|_| EvalError::MzTimestampOutOfRange(a.to_string()))
}
);
sqlfunc!(
#[sqlname = "integer_to_mz_timestamp"]
#[preserves_uniqueness = true]
#[is_monotone = true]
fn cast_int32_to_mz_timestamp(a: i32) -> Result<Timestamp, EvalError> {
i64::from(a)
.try_into()
.map_err(|_| EvalError::MzTimestampOutOfRange(a.to_string()))
}
);
sqlfunc!(
#[sqlname = "timestamp_tz_to_mz_timestamp"]
#[is_monotone = true]
fn cast_timestamp_tz_to_mz_timestamp(
a: CheckedTimestamp<DateTime<Utc>>,
) -> Result<Timestamp, EvalError> {
a.timestamp_millis()
.try_into()
.map_err(|_| EvalError::MzTimestampOutOfRange(a.to_string()))
}
);
sqlfunc!(
#[sqlname = "timestamp_to_mz_timestamp"]
#[is_monotone = true]
fn cast_timestamp_to_mz_timestamp(
a: CheckedTimestamp<NaiveDateTime>,
) -> Result<Timestamp, EvalError> {
a.timestamp_millis()
.try_into()
.map_err(|_| EvalError::MzTimestampOutOfRange(a.to_string()))
}
);
sqlfunc!(
#[sqlname = "step_mz_timestamp"]
#[preserves_uniqueness = true]
#[is_monotone = true]
fn step_mz_timestamp(a: Timestamp) -> Result<Timestamp, EvalError> {
a.checked_add(1).ok_or(EvalError::MzTimestampStepOverflow)
}
);