Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions snuba/clickhouse/formatter/expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ def visit_function_call(self, exp: FunctionCall) -> str:
formatted = (c.accept(self) for c in get_first_level_or_conditions(exp))
return f"({' OR '.join(formatted)})"

elif exp.function_name == BooleanFunctions.NOT:
# Format NOT function without applying alias to avoid malformed SQL
# when the inner expression has an alias starting with special characters
formatted = self.__visit_params(exp.parameters)
return f"not({formatted})"

Comment on lines +160 to +164
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: New code for BooleanFunctions.NOT silently drops aliases from FunctionCall objects during formatting.
Severity: HIGH | Confidence: 0.95

🔍 Detailed Analysis

When a FunctionCall object with function_name == "not" and a non-null alias is processed by the formatter, the alias is silently dropped. This occurs because the new code introduced for BooleanFunctions.NOT in snuba/clickhouse/formatter/expression.py:160~164 does not include a call to self._alias(ret, exp.alias), unlike other function calls. This omission results in the alias information, which is present in the query AST and actively used in production code (e.g., snuba/query/processors/physical/empty_tag_condition_processor.py), not being applied to the formatted output.

💡 Suggested Fix

After formatting the NOT expression, ensure self._alias(ret, exp.alias) is called to apply the alias, consistent with how other function calls are handled in the formatter.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: snuba/clickhouse/formatter/expression.py#L160-L164

Potential issue: When a `FunctionCall` object with `function_name == "not"` and a
non-null `alias` is processed by the formatter, the alias is silently dropped. This
occurs because the new code introduced for `BooleanFunctions.NOT` in
`snuba/clickhouse/formatter/expression.py:160~164` does not include a call to
`self._alias(ret, exp.alias)`, unlike other function calls. This omission results in the
alias information, which is present in the query AST and actively used in production
code (e.g., `snuba/query/processors/physical/empty_tag_condition_processor.py`), not
being applied to the formatted output.

Did we get this right? 👍 / 👎 to inform future reviews.

ret = f"{escape_identifier(exp.function_name)}({self.__visit_params(exp.parameters)})"
return self._alias(ret, exp.alias)

Expand Down
Loading