Skip to content

Commit 68931bd

Browse files
committed
Support signed numeric literals in BSL filter translation
Python parses -5 as ast.UnaryOp(USub, Constant(5)), not as a negative Constant. _expr_to_sql only handled Constant, so filters like _.delta > -5 produced None on the RHS and failed at parse time. Handle UnaryOp with USub to emit the negated value.
1 parent 2013f63 commit 68931bd

2 files changed

Lines changed: 12 additions & 0 deletions

File tree

sidemantic/adapters/bsl_expr.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ def _expr_to_sql(node: ast.AST) -> str | None:
127127
if isinstance(node.value, (int, float)):
128128
return str(node.value)
129129

130+
# Python parses -5 as UnaryOp(USub, Constant(5))
131+
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
132+
operand = _expr_to_sql(node.operand)
133+
if operand is not None:
134+
return f"-{operand}"
135+
130136
if isinstance(node, ast.Name) and node.id == "_":
131137
return None
132138

tests/adapters/bsl/test_parsing.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,12 @@ def test_notnull(self):
11481148
result = bsl_filter_to_sql("_.origin.notnull()")
11491149
assert result == "origin IS NOT NULL"
11501150

1151+
def test_negative_number(self):
1152+
assert bsl_filter_to_sql("_.delta > -5") == "delta > -5"
1153+
1154+
def test_negative_float(self):
1155+
assert bsl_filter_to_sql("_.score < -0.5") == "score < -0.5"
1156+
11511157

11521158
class TestBSLFilterAutoApply:
11531159
"""Tests that model-level filters are auto-applied in queries via model.sql."""

0 commit comments

Comments
 (0)