Skip to content

Commit 8863bd1

Browse files
authored
feat(processor): Handle casted columns in UUID column processor (#7552)
The UUID column processor handles simple conditions like `equals(column, 'value')` but fails when the column is casted like `equals(cast(column, 'String'), 'value')`. This adds support for the casted case
1 parent 9654ebf commit 8863bd1

File tree

2 files changed

+66
-25
lines changed

2 files changed

+66
-25
lines changed

snuba/query/processors/physical/type_converters.py

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,27 +69,50 @@ def __init__(self, columns: Set[str], optimize_ordering: bool = False):
6969
)
7070

7171
col = Param("col", ColumnMatch(None, column_match))
72+
casted_col = FunctionCallMatch(String("cast"), (col, LiteralMatch(String("String"))))
7273

7374
self.__condition_matcher = Or(
7475
[
7576
FunctionCallMatch(operator, (literal, col)),
7677
FunctionCallMatch(operator, (col, literal)),
7778
FunctionCallMatch(Param("operator", String("has")), (col, literal)),
79+
# These are the same as above but the column is wrapped in `cast(..., 'String')`
80+
FunctionCallMatch(operator, (casted_col, literal)),
81+
FunctionCallMatch(operator, (literal, casted_col)),
82+
FunctionCallMatch(Param("operator", String("has")), (casted_col, literal)),
7883
]
7984
)
8085

81-
self.__in_condition_matcher = FunctionCallMatch(
82-
in_operators,
83-
(
84-
col,
85-
Param(
86-
"literals",
87-
FunctionCallMatch(
88-
Or([String("array"), String("tuple")]),
89-
all_parameters=LiteralMatch(),
86+
self.__in_condition_matcher = Or(
87+
[
88+
FunctionCallMatch(
89+
in_operators,
90+
(
91+
col,
92+
Param(
93+
"literals",
94+
FunctionCallMatch(
95+
Or([String("array"), String("tuple")]),
96+
all_parameters=LiteralMatch(),
97+
),
98+
),
9099
),
91100
),
92-
),
101+
# These are the same as above but the column is wrapped in `cast(..., 'String')`
102+
FunctionCallMatch(
103+
in_operators,
104+
(
105+
casted_col,
106+
Param(
107+
"literals",
108+
FunctionCallMatch(
109+
Or([String("array"), String("tuple")]),
110+
all_parameters=LiteralMatch(),
111+
),
112+
),
113+
),
114+
),
115+
]
93116
)
94117

95118
self.__unoptimizable_condition_matcher = Or(
@@ -100,9 +123,7 @@ def __init__(self, columns: Set[str], optimize_ordering: bool = False):
100123
)
101124

102125
def process_query(self, query: Query, query_settings: QuerySettings) -> None:
103-
query.transform_expressions(
104-
self._process_expressions, skip_transform_condition=True
105-
)
126+
query.transform_expressions(self._process_expressions, skip_transform_condition=True)
106127

107128
condition = query.get_condition()
108129
if condition is not None:
@@ -117,9 +138,7 @@ def process_query(self, query: Query, query_settings: QuerySettings) -> None:
117138

118139
def __strip_column_alias(self, exp: Expression) -> Expression:
119140
assert isinstance(exp, Column)
120-
return Column(
121-
alias=None, table_name=exp.table_name, column_name=exp.column_name
122-
)
141+
return Column(alias=None, table_name=exp.table_name, column_name=exp.column_name)
123142

124143
def __contains_unoptimizable_condition(self, exp: Expression) -> bool:
125144
"""
@@ -144,9 +163,7 @@ def assert_literal(lit: Expression) -> Literal:
144163
match.string("operator"),
145164
(
146165
self.__strip_column_alias(match.expression("col")),
147-
self._translate_literal(
148-
assert_literal(match.expression("literal"))
149-
),
166+
self._translate_literal(assert_literal(match.expression("literal"))),
150167
),
151168
)
152169

tests/query/processors/test_uuid_column_processor.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,8 @@
8181
None,
8282
"tuple",
8383
(
84-
Literal(
85-
None, str(uuid.UUID("a7d67cf7-9677-4551-a95b-e6543cacd459"))
86-
),
87-
Literal(
88-
None, str(uuid.UUID("a7d67cf7-9677-4551-a95b-e6543cacd45a"))
89-
),
84+
Literal(None, str(uuid.UUID("a7d67cf7-9677-4551-a95b-e6543cacd459"))),
85+
Literal(None, str(uuid.UUID("a7d67cf7-9677-4551-a95b-e6543cacd45a"))),
9086
),
9187
),
9288
),
@@ -231,6 +227,34 @@
231227
"equals(column2, 'a7d67cf7-9677-4551-a95b-e6543cacd460') AND equals(column1, 'a7d67cf7-9677-4551-a95b-e6543cacd459')",
232228
id="equals(column2, 'a7d67cf7-9677-4551-a95b-e6543cacd460') AND equals(column1, 'a7d67cf7-9677-4551-a95b-e6543cacd459')",
233229
),
230+
pytest.param(
231+
binary_condition(
232+
ConditionFunctions.EQ,
233+
FunctionCall(None, "cast", (Column(None, None, "column1"), Literal(None, "String"))),
234+
Literal(None, "a7d67cf796774551a95be6543cacd459"),
235+
),
236+
binary_condition(
237+
ConditionFunctions.EQ,
238+
Column(None, None, "column1"),
239+
Literal(None, str(uuid.UUID("a7d67cf7-9677-4551-a95b-e6543cacd459"))),
240+
),
241+
"equals(column1, 'a7d67cf7-9677-4551-a95b-e6543cacd459')",
242+
id="equals(column1, 'a7d67cf7-9677-4551-a95b-e6543cacd459')",
243+
),
244+
pytest.param(
245+
binary_condition(
246+
ConditionFunctions.IN,
247+
FunctionCall(None, "cast", (Column(None, None, "column1"), Literal(None, "String"))),
248+
FunctionCall(None, "tuple", (Literal(None, "a7d67cf796774551a95be6543cacd459"),)),
249+
),
250+
binary_condition(
251+
ConditionFunctions.IN,
252+
Column(None, None, "column1"),
253+
FunctionCall(None, "tuple", (Literal(None, "a7d67cf7-9677-4551-a95b-e6543cacd459"),)),
254+
),
255+
"in(column1, tuple('a7d67cf7-9677-4551-a95b-e6543cacd459'))",
256+
id="in(column1, tuple('a7d67cf7-9677-4551-a95b-e6543cacd459'))",
257+
),
234258
]
235259

236260

0 commit comments

Comments
 (0)