From 990f621daa9f615d2d5db18aec6ccc9a727da946 Mon Sep 17 00:00:00 2001 From: Anna Mayzner Date: Mon, 14 Oct 2024 14:40:40 +0000 Subject: [PATCH] tp: Interval intersect errors on negative ts Change-Id: I2ad9eef24a0aef702818892311bd67ac67bc4a79 --- .../intrinsics/functions/type_builders.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/trace_processor/perfetto_sql/intrinsics/functions/type_builders.cc b/src/trace_processor/perfetto_sql/intrinsics/functions/type_builders.cc index a9d928752b..93ce52df60 100644 --- a/src/trace_processor/perfetto_sql/intrinsics/functions/type_builders.cc +++ b/src/trace_processor/perfetto_sql/intrinsics/functions/type_builders.cc @@ -308,25 +308,29 @@ struct IntervalTreeIntervalsAgg struct AggCtx : SqliteAggregateContext { perfetto_sql::PartitionedTable partitions; std::vector tmp_vals; - uint64_t max_ts = std::numeric_limits::min(); + uint64_t last_interval_start = 0; }; static void Step(sqlite3_context* ctx, int rargc, sqlite3_value** argv) { auto argc = static_cast(rargc); PERFETTO_DCHECK(argc >= kMinArgCount); auto& agg_ctx = AggCtx::GetOrCreateContextForStep(ctx); - auto& parts = AggCtx::GetOrCreateContextForStep(ctx).partitions; // Fetch and validate the interval. Interval interval; interval.id = static_cast(sqlite::value::Int64(argv[0])); interval.start = static_cast(sqlite::value::Int64(argv[1])); - if (interval.start < agg_ctx.max_ts) { + if (interval.start < agg_ctx.last_interval_start) { + if (sqlite::value::Int64(argv[1]) < 0) { + sqlite::result::Error( + ctx, "Interval intersect only accepts positive `ts` values."); + return; + } sqlite::result::Error( ctx, "Interval intersect requires intervals to be sorted by ts."); return; } - agg_ctx.max_ts = interval.start; + agg_ctx.last_interval_start = interval.start; int64_t dur = sqlite::value::Int64(argv[2]); if (dur < 1) { sqlite::result::Error( @@ -336,6 +340,7 @@ struct IntervalTreeIntervalsAgg interval.end = interval.start + static_cast(dur); // Fast path for no partitions. + auto& parts = agg_ctx.partitions; if (argc == kMinArgCount) { auto& part = parts.partitions_map[0]; part.intervals.push_back(interval);