Skip to content
Merged
Show file tree
Hide file tree
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
20 changes: 13 additions & 7 deletions src/zero_server/server/pg_query_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ class _Unsafe(int):
"""An integer JavaScript cannot hold exactly. Upstream parses it as a bigint and refuses it."""


def _parse_int(text: str) -> int:
value = int(text)
return _Unsafe(value) if abs(value) > _MAX_SAFE else value


def _parse_float(text: str) -> int | float:
"""A whole number written with a fraction, as `numeric` epoch milliseconds are, comes back an `int`.

Expand All @@ -53,8 +48,19 @@ def _path_to_unsafe(value: Any) -> str | None:


def extract_zql_result(rows: list[Row]) -> Any:
result = json.loads(rows[0][ZQL_RESULT_KEY], parse_int=_parse_int, parse_float=_parse_float)
if (path := _path_to_unsafe(result)) is not None:
unsafe = False

def parse_int(text: str) -> int:
nonlocal unsafe
value = int(text)
if abs(value) <= _MAX_SAFE:
return value
unsafe = True
return _Unsafe(value)

result = json.loads(rows[0][ZQL_RESULT_KEY], parse_int=parse_int, parse_float=_parse_float)
# A duplicate key can drop a parsed unsafe integer, so the walk may still find none.
if unsafe and (path := _path_to_unsafe(result)) is not None:
raise Exception(f"Value exceeds safe Number range. {path}")
return result

Expand Down
15 changes: 15 additions & 0 deletions tests/unit/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,18 @@ def test_server_ast_maps_to_server_names() -> None:
ast: Any = server_ast(create_builder(schema).issue.where("ownerID", "u"), schema).to_json()
assert ast["table"] == "issues"
assert ast["where"]["left"]["name"] == "owner_id"


def test_zql_result_names_the_first_unsafe_integer() -> None:
from zero_server.server.pg_query_executor import extract_zql_result

text = '[{"n": [1], "m": [2, -9007199254740993]}, {"n": 9007199254740993}]'
with pytest.raises(Exception, match=r"^Value exceeds safe Number range\. \[0\]\['m'\]\[1\] = -9007199254740993$"):
extract_zql_result([{"zql_result": text}])


def test_zql_result_ignores_an_unsafe_integer_a_duplicate_key_replaced() -> None:
from zero_server.server.pg_query_executor import extract_zql_result

text = '{"n": 9007199254740993, "n": 9007199254740991}'
assert extract_zql_result([{"zql_result": text}]) == {"n": 9007199254740991}
Loading