Skip to content

Commit b3a225e

Browse files
committed
Budget numeric MySQL wire parameters conservatively
1 parent 0b1e891 commit b3a225e

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

‎src/openstatspec/sql/profiles.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,9 @@ def statement_payload_bytes(
307307
size = 32
308308
for variable in variables:
309309
if variable.get("storage_kind") == "numeric":
310-
size += 8
310+
# PyMySQL serializes binary64 parameters as decimal wire text;
311+
# the longest finite literal is 24 bytes (including its sign).
312+
size += 24
311313
else:
312314
value = row.get(str(variable["physical_name"]), "")
313315
size += len(str(value).encode("utf-8")) + 8

‎tests/test_catalog_lifecycle.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,19 @@ def test_bounded_batches_never_exceed_statement_payload_limit():
277277
assert batches == [rows[:2], rows[2:]]
278278

279279

280+
def test_bounded_batches_budget_numeric_pymysql_wire_literals():
281+
variables = [{
282+
"source_name": "value",
283+
"physical_name": "value",
284+
"storage_kind": "numeric",
285+
}]
286+
rows = [{"value": -1.7976931348623157e+308}] * 2
287+
288+
assert wide.statement_payload_bytes(rows[0], variables) == 56
289+
assert list(_bounded_batches(rows, variables, 111)) == [[rows[0]], [rows[1]]]
290+
assert list(_bounded_batches(rows, variables, 112)) == [rows]
291+
292+
280293
def test_duplicate_import_failure_preserves_existing_dataset(tmp_path):
281294
path = tmp_path / "duplicate.sqlite"
282295
database = f"sqlite:///{path}"

0 commit comments

Comments
 (0)