Skip to content

Commit 311ab20

Browse files
authored
feat(eap): add not filter implementation (#6858)
Separating not filters into a separate PR instead of doing it in [this one](#6837) to allow product to use it before we merge that one
1 parent d1de0c8 commit 311ab20

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

snuba/web/rpc/common/common.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,18 @@ def trace_item_filters_to_expression(item_filter: TraceItemFilter) -> Expression
285285
return trace_item_filters_to_expression(filters[0])
286286
return or_cond(*(trace_item_filters_to_expression(x) for x in filters))
287287

288+
if item_filter.HasField("not_filter"):
289+
filters = item_filter.not_filter.filters
290+
if len(filters) == 0:
291+
raise BadSnubaRPCRequestException(
292+
"Invalid trace item filter, empty 'not' clause"
293+
)
294+
elif len(filters) == 1:
295+
return not_cond(trace_item_filters_to_expression(filters[0]))
296+
return not_cond(
297+
and_cond(*(trace_item_filters_to_expression(x) for x in filters))
298+
)
299+
288300
if item_filter.HasField("comparison_filter"):
289301
k = item_filter.comparison_filter.key
290302
k_expression = attribute_key_to_expression(k)

tests/web/rpc/v1/test_endpoint_trace_item_table/test_endpoint_trace_item_table.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
from sentry_protos.snuba.v1.trace_item_filter_pb2 import (
3737
ComparisonFilter,
3838
ExistsFilter,
39+
NotFilter,
3940
OrFilter,
4041
TraceItemFilter,
4142
)
@@ -2512,6 +2513,48 @@ def test_non_agg_formula(self, setup_teardown: Any) -> None:
25122513
),
25132514
]
25142515

2516+
def test_not_filter(setup_teardown: Any) -> None:
2517+
span_ts = BASE_TIME - timedelta(minutes=1)
2518+
write_eap_span(span_ts, {"attr1": "value1"}, 10)
2519+
write_eap_span(span_ts, {"attr1": "value1", "attr2": "value2"}, 10)
2520+
ts = Timestamp(seconds=int(BASE_TIME.timestamp()))
2521+
hour_ago = int((BASE_TIME - timedelta(hours=1)).timestamp())
2522+
message = TraceItemTableRequest(
2523+
meta=RequestMeta(
2524+
project_ids=[1, 2, 3],
2525+
organization_id=1,
2526+
cogs_category="something",
2527+
referrer="something",
2528+
start_timestamp=Timestamp(seconds=hour_ago),
2529+
end_timestamp=ts,
2530+
trace_item_type=TraceItemType.TRACE_ITEM_TYPE_SPAN,
2531+
),
2532+
columns=[
2533+
Column(key=AttributeKey(type=AttributeKey.TYPE_STRING, name="attr1")),
2534+
],
2535+
filter=TraceItemFilter(
2536+
not_filter=NotFilter(
2537+
filters=[
2538+
TraceItemFilter(
2539+
exists_filter=ExistsFilter(
2540+
key=AttributeKey(
2541+
type=AttributeKey.TYPE_STRING, name="attr2"
2542+
)
2543+
)
2544+
)
2545+
]
2546+
)
2547+
),
2548+
limit=50,
2549+
)
2550+
response = EndpointTraceItemTable().execute(message)
2551+
assert response.column_values == [
2552+
TraceItemColumnValues(
2553+
attribute_name="attr1",
2554+
results=[AttributeValue(val_str="value1") for _ in range(10)],
2555+
),
2556+
]
2557+
25152558

25162559
class TestUtils:
25172560
def test_apply_labels_to_columns_backward_compat(self) -> None:

0 commit comments

Comments
 (0)