chore(deps): Bump chrono from 0.4.30 to 0.4.31 (#8752)

* chore(deps): Bump chrono from 0.4.30 to 0.4.31

Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.30 to 0.4.31.
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.30...v0.4.31)

---
updated-dependencies:
- dependency-name: chrono
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: chrono ts -> nanos can fail, fix deprecation warning

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marco Neumann <marco@crepererum.net>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
pull/24376/head
dependabot[bot] 2023-09-18 12:57:48 +00:00 committed by GitHub
parent af425f657c
commit 1760fe7736
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 114 additions and 47 deletions

4
Cargo.lock generated
View File

@ -793,9 +793,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.30"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",

View File

@ -592,10 +592,9 @@ mod test {
// infallible
let ts = nanos_to_timestamp(i64::MAX);
assert_eq!(ts.timestamp_nanos(), i64::MAX);
assert_eq!(ts.timestamp_nanos_opt().unwrap(), i64::MAX);
// let ts = nanos_to_timestamp(i64::MIN);
// This line panics with an arithmetic overflow.
// assert_eq!(ts.timestamp_nanos(), i64::MIN);
let ts = nanos_to_timestamp(i64::MIN);
assert_eq!(ts.timestamp_nanos_opt().unwrap(), i64::MIN);
}
}

View File

@ -252,7 +252,14 @@ pub fn split_cond(
};
let ts = match expr {
Expr::Literal(Literal::Timestamp(ts)) => ts.timestamp_nanos(),
Expr::Literal(Literal::Timestamp(ts)) => match ts.timestamp_nanos_opt() {
Some(ts) => ts,
None => {
return ControlFlow::Break(error::map::internal(
"timestamp out o range",
));
}
},
expr => {
return ControlFlow::Break(error::map::internal(format!(
"expected Timestamp, got: {}",
@ -390,7 +397,9 @@ impl TimeRange {
/// Simplifies an InfluxQL duration `expr` to a nanosecond interval represented as an `i64`.
pub fn duration_expr_to_nanoseconds(ctx: &ReduceContext, expr: &Expr) -> Result<i64, ExprError> {
match reduce_time_expr(ctx, expr)? {
Expr::Literal(Literal::Timestamp(v)) => Ok(v.timestamp_nanos()),
Expr::Literal(Literal::Timestamp(v)) => v
.timestamp_nanos_opt()
.ok_or_else(|| error::map::expr("timestamp out of range")),
_ => error::expr("invalid duration expression"),
}
}
@ -637,10 +646,15 @@ fn expr_to_duration(ctx: &ReduceContext, expr: Expr) -> ExprResult {
Ok(lit(match expr {
Expr::Literal(Literal::Duration(v)) => v,
Expr::Literal(Literal::Integer(v)) => Duration(v),
Expr::Literal(Literal::Timestamp(v)) => Duration(v.timestamp_nanos()),
Expr::Literal(Literal::String(v)) => {
Duration(parse_timestamp_nanos(&v, ctx.tz)?.timestamp_nanos())
}
Expr::Literal(Literal::Timestamp(v)) => Duration(
v.timestamp_nanos_opt()
.ok_or_else(|| error::map::expr("timestamp out of range"))?,
),
Expr::Literal(Literal::String(v)) => Duration(
parse_timestamp_nanos(&v, ctx.tz)?
.timestamp_nanos_opt()
.ok_or_else(|| error::map::expr("timestamp out of range"))?,
),
_ => return error::expr(format!("unable to cast {expr} to duration")),
}))
}

View File

@ -139,12 +139,15 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
let execution_start_time = Local::now();
let execution_start_time_nanos = execution_start_time
.timestamp_nanos_opt()
.expect("'now' is in nano range");
let start_datetime = datetime_nanoseconds(config.start.as_deref(), execution_start_time);
let end_datetime = datetime_nanoseconds(config.end.as_deref(), execution_start_time);
let start_display = start_datetime.unwrap_or_else(|| execution_start_time.timestamp_nanos());
let end_display = end_datetime.unwrap_or_else(|| execution_start_time.timestamp_nanos());
let start_display = start_datetime.unwrap_or(execution_start_time_nanos);
let end_display = end_datetime.unwrap_or(execution_start_time_nanos);
let continue_on = config.do_continue;
@ -201,7 +204,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
&mut points_writer_builder,
start_datetime,
end_datetime,
execution_start_time.timestamp_nanos(),
execution_start_time_nanos,
continue_on,
config.batch_size,
config.print,
@ -231,7 +234,9 @@ fn datetime_nanoseconds(arg: Option<&str>, now: DateTime<Local>) -> Option<i64>
now - chrono_duration
});
datetime.timestamp_nanos()
datetime
.timestamp_nanos_opt()
.expect("timestamp out of range")
})
}
@ -255,7 +260,9 @@ mod test {
fn relative() {
let fixed_now = Local::now();
let ns = datetime_nanoseconds(Some("1hr"), fixed_now);
let expected = (fixed_now - chrono::Duration::hours(1)).timestamp_nanos();
let expected = (fixed_now - chrono::Duration::hours(1))
.timestamp_nanos_opt()
.unwrap();
assert_eq!(ns, Some(expected));
}
}

View File

@ -39,12 +39,14 @@ mod test {
.start_timestamp
.value()
.expect("start timestamp")
.timestamp_nanos();
.timestamp_nanos_opt()
.expect("start timestamp in range");
let end_ts = $EXTRACTED
.end_timestamp
.value()
.expect("end timestamp")
.timestamp_nanos();
.timestamp_nanos_opt()
.expect("end timestamp in range");
assert!(start_ts > 0, "start timestamp was non zero");
assert!(end_ts > 0, "end timestamp was non zero");

View File

@ -1843,10 +1843,10 @@ impl<'a> InfluxQLToLogicalPlan<'a> {
Literal::Float(v) => Ok(lit(*v)),
Literal::String(v) => Ok(lit(v)),
Literal::Boolean(v) => Ok(lit(*v)),
Literal::Timestamp(v) => Ok(lit(ScalarValue::TimestampNanosecond(
Some(v.timestamp_nanos()),
None,
))),
Literal::Timestamp(v) => v
.timestamp_nanos_opt()
.ok_or_else(|| error::map::query("timestamp out of range"))
.map(|ts| lit(ScalarValue::TimestampNanosecond(Some(ts), None))),
Literal::Duration(v) => {
Ok(lit(ScalarValue::IntervalMonthDayNano(Some((**v).into()))))
}
@ -2210,9 +2210,14 @@ impl<'a> InfluxQLToLogicalPlan<'a> {
let time_range = if time_range.is_unbounded() {
TimeRange {
lower: Some(match cutoff {
MetadataCutoff::Absolute(dt) => dt.timestamp_nanos(),
MetadataCutoff::Absolute(dt) => dt
.timestamp_nanos_opt()
.ok_or_else(|| error::map::query("timestamp out of range"))?,
MetadataCutoff::Relative(delta) => {
start_time.timestamp_nanos() - delta.as_nanos() as i64
start_time
.timestamp_nanos_opt()
.ok_or_else(|| error::map::query("timestamp out of range"))?
- delta.as_nanos() as i64
}
}),
upper: None,

View File

@ -123,7 +123,7 @@ impl RewriteSelect {
let time_range = match (interval, time_range.upper) {
(Some(interval), None) if interval.duration > 0 => TimeRange {
lower: time_range.lower,
upper: Some(now.timestamp_nanos()),
upper: Some(now.timestamp_nanos_opt().expect("'now' in nano range")),
},
_ => time_range,
};

View File

@ -7,7 +7,7 @@ edition.workspace = true
license.workspace = true
[dependencies]
chrono = { version = "0.4.30", default-features = false, features = ["clock", "std"] }
chrono = { version = "0.4.31", default-features = false, features = ["clock", "std"] }
parking_lot = "0.12"
tokio = { version = "1.32", features = ["macros", "parking_lot", "rt-multi-thread", "sync", "time"] }
workspace-hack = { version = "0.1", path = "../workspace-hack" }

View File

@ -111,7 +111,8 @@ impl Time {
/// Returns the number of non-leap-nanoseconds since January 1, 1970 UTC
pub fn timestamp_nanos(&self) -> i64 {
self.0.timestamp_nanos()
// TODO: ensure that this can never over-/underflow
self.0.timestamp_nanos_opt().expect("nanos in range")
}
/// Returns the number of seconds since January 1, 1970 UTC
@ -539,7 +540,7 @@ mod test {
);
assert_eq!(
time,
Time::from_timestamp_nanos(date_time.timestamp_nanos())
Time::from_timestamp_nanos(date_time.timestamp_nanos_opt().unwrap())
);
assert_eq!(
Time::from_timestamp_millis(date_time.timestamp_millis()).unwrap(),
@ -549,7 +550,10 @@ mod test {
)
);
assert_eq!(time.timestamp_nanos(), date_time.timestamp_nanos());
assert_eq!(
time.timestamp_nanos(),
date_time.timestamp_nanos_opt().unwrap()
);
assert_eq!(time.timestamp_millis(), date_time.timestamp_millis());
assert_eq!(time.to_rfc3339(), date_time.to_rfc3339());

View File

@ -206,7 +206,11 @@ fn parse_time(input: &str) -> Result<i64> {
// See examples here https://docs.influxdata.com/influxdb/v2.0/reference/cli/influx/delete/#delete-all-points-within-a-specified-time-frame
let datetime_result = DateTime::parse_from_rfc3339(input);
match datetime_result {
Ok(datetime) => Ok(datetime.timestamp_nanos()),
Ok(datetime) => datetime
.timestamp_nanos_opt()
.ok_or_else(|| Error::InvalidTimestamp {
value: datetime.to_string(),
}),
Err(timestamp_err) => {
// See if it is in nanosecond form
let time_result = input.parse::<i64>();

View File

@ -199,7 +199,9 @@ fn to_timestamp_nanos_utc(
let ndatetime = NaiveDateTime::new(ndate, ntime);
let datetime = DateTime::<Utc>::from_naive_utc_and_offset(ndatetime, Utc);
datetime.timestamp_nanos()
datetime
.timestamp_nanos_opt()
.expect("timestamp nanos in range")
}
impl Add<Duration> for i64 {
@ -386,7 +388,7 @@ mod tests {
/// t: mustParseTime("1970-02-01T00:00:00Z"),
fn must_parse_time(s: &str) -> i64 {
let datetime = DateTime::parse_from_rfc3339(s).unwrap();
datetime.timestamp_nanos()
datetime.timestamp_nanos_opt().unwrap()
}
/// TestWindow_GetEarliestBounds

View File

@ -48,7 +48,7 @@ workspace-hack = { version = "0.1", path = "../workspace-hack" }
[dev-dependencies]
assert_matches = "1.5"
base64 = "0.21.4"
chrono = { version = "0.4.30", default-features = false }
chrono = { version = "0.4.31", default-features = false }
criterion = { version = "0.5", default-features = false, features = [
"async_tokio",
"rayon",

View File

@ -139,7 +139,19 @@ impl JaegerAgentExporter {
service_name: self.service_name.clone(),
tags: self.tags.clone(),
},
spans: spans.into_iter().map(Into::into).collect(),
spans: spans
.into_iter()
.filter_map(|span| match jaeger::Span::try_from(span) {
Ok(span) => Some(span),
Err(e) => {
warn!(
%e,
"cannot convert span to jaeger format",
);
None
}
})
.collect(),
seq_no,
stats: None,
}

View File

@ -13,8 +13,10 @@ fn split_trace_id(trace_id: TraceId) -> (i64, i64) {
(trace_id_high, trace_id_low)
}
impl From<Span> for jaeger::Span {
fn from(mut s: Span) -> Self {
impl TryFrom<Span> for jaeger::Span {
type Error = String;
fn try_from(mut s: Span) -> Result<Self, Self::Error> {
let (trace_id_high, trace_id_low) = split_trace_id(s.ctx.trace_id);
// A parent span id of 0 indicates no parent span ID (span IDs are non-zero)
@ -22,10 +24,17 @@ impl From<Span> for jaeger::Span {
let (start_time, duration) = match (s.start, s.end) {
(Some(start), Some(end)) => (
start.timestamp_nanos() / 1000,
start.timestamp_nanos_opt().ok_or_else(|| {
format!("start timestamp cannot be represented as nanos: {start}")
})? / 1000,
(end - start).num_microseconds().expect("no overflow"),
),
(Some(start), _) => (start.timestamp_nanos() / 1000, 0),
(Some(start), _) => (
start.timestamp_nanos_opt().ok_or_else(|| {
format!("start timestamp cannot be represented as nanos: {start}")
})? / 1000,
0,
),
_ => (0, 0),
};
@ -57,7 +66,12 @@ impl From<Span> for jaeger::Span {
let logs = match s.events.is_empty() {
true => None,
false => Some(s.events.into_iter().map(Into::into).collect()),
false => Some(
s.events
.into_iter()
.map(TryInto::try_into)
.collect::<Result<_, _>>()?,
),
};
let references = if s.ctx.links.is_empty() {
@ -81,7 +95,7 @@ impl From<Span> for jaeger::Span {
)
};
Self {
Ok(Self {
trace_id_low,
trace_id_high,
span_id: s.ctx.span_id.get() as i64,
@ -93,14 +107,18 @@ impl From<Span> for jaeger::Span {
duration,
tags,
logs,
}
})
}
}
impl From<SpanEvent> for jaeger::Log {
fn from(event: SpanEvent) -> Self {
Self {
timestamp: event.time.timestamp_nanos() / 1000,
impl TryFrom<SpanEvent> for jaeger::Log {
type Error = String;
fn try_from(event: SpanEvent) -> Result<Self, Self::Error> {
Ok(Self {
timestamp: event.time.timestamp_nanos_opt().ok_or_else(|| {
format!("timestamp cannot be represented as nanos: {}", event.time)
})? / 1000,
fields: vec![jaeger::Tag {
key: "event".to_string(),
v_type: jaeger::TagType::String,
@ -110,7 +128,7 @@ impl From<SpanEvent> for jaeger::Log {
v_long: None,
v_binary: None,
}],
}
})
}
}