@@ -1403,6 +1403,30 @@ def test_filter_expression():
14031403 )
14041404 assert filter_expr .expr (row1 ) is True
14051405
1406+ # BETWEEN test where the attribute itself is exactly 0 -- regression test.
1407+ # 0 is a valid Decimal value and must not be treated as "no value" via
1408+ # bare truthiness (bool(Decimal("0")) is False), the same way start/end
1409+ # already correctly special-case 0. Item with Id=0 must be included in
1410+ # a BETWEEN 0 AND 10 (and BETWEEN -5 AND 10) range.
1411+ row_zero = moto .dynamodb .models .Item (
1412+ hash_key = None ,
1413+ range_key = None ,
1414+ attrs = {"Id" : {"N" : "0" }},
1415+ )
1416+ filter_expr = moto .dynamodb .comparisons .get_filter_expression (
1417+ "Id BETWEEN :v0 AND :v1" , {}, {":v0" : {"N" : "0" }, ":v1" : {"N" : "10" }}
1418+ )
1419+ assert filter_expr .expr (row_zero ) is True
1420+ filter_expr = moto .dynamodb .comparisons .get_filter_expression (
1421+ "Id BETWEEN :v0 AND :v1" , {}, {":v0" : {"N" : "-5" }, ":v1" : {"N" : "10" }}
1422+ )
1423+ assert filter_expr .expr (row_zero ) is True
1424+ # And it must still correctly exclude 0 when it falls outside the range.
1425+ filter_expr = moto .dynamodb .comparisons .get_filter_expression (
1426+ "Id BETWEEN :v0 AND :v1" , {}, {":v0" : {"N" : "1" }, ":v1" : {"N" : "10" }}
1427+ )
1428+ assert filter_expr .expr (row_zero ) is False
1429+
14061430 # PAREN test
14071431 filter_expr = moto .dynamodb .comparisons .get_filter_expression (
14081432 "Id = :v0 AND (Subs = :v0 OR Subs = :v1)" ,
0 commit comments