diff --git a/src/sentry/profiles/profile_chunks.py b/src/sentry/profiles/profile_chunks.py index 65e3e7cf04f8e1..a89e423e0af246 100644 --- a/src/sentry/profiles/profile_chunks.py +++ b/src/sentry/profiles/profile_chunks.py @@ -1,4 +1,6 @@ -from snuba_sdk import Column, Condition, Direction, Op, OrderBy, Query, Request, Storage +from datetime import datetime + +from snuba_sdk import Column, Condition, Direction, Function, Op, OrderBy, Query, Request, Storage from sentry import options from sentry.search.events.types import ParamsType @@ -20,8 +22,16 @@ def get_chunk_ids( Column("chunk_id"), ], where=[ - Condition(Column("end_timestamp"), Op.GTE, params.get("start")), - Condition(Column("start_timestamp"), Op.LT, params.get("end")), + Condition( + Column("end_timestamp"), + Op.GTE, + resolve_datetime64(params.get("start")), + ), + Condition( + Column("start_timestamp"), + Op.LT, + resolve_datetime64(params.get("end")), + ), Condition(Column("project_id"), Op.EQ, project_id), Condition(Column("profiler_id"), Op.EQ, profiler_id), ], @@ -44,3 +54,23 @@ def get_chunk_ids( ) return [row["chunk_id"] for row in result["data"]] + + +def resolve_datetime64(value: datetime | None, precision: int = 6) -> Function | None: + # This is normally handled by the snuba-sdk but it assumes that the underlying + # table uses DateTime. Because we use DateTime64(6) as the underlying column, + # we need to cast to the same type or we risk truncating the timestamp which + # can lead to subtle errors. + + if value is None: + return None + + if isinstance(value, datetime) and value.tzinfo is not None: + # This is adapted from snuba-sdk + # See https://github.com/getsentry/snuba-sdk/blob/2f7f014920b4f527a87f18c05b6aa818212bec6e/snuba_sdk/visitors.py#L168-L172 + delta = value.utcoffset() + assert delta is not None + value -= delta + value.replace(tzinfo=None) + + return Function("toDateTime64", [value.isoformat(), precision])