Skip to content

feat(mysql-dual-conn): add a FLOAT/DOUBLE/BIGINT UNSIGNED fidelity fixture - #150

Merged
slayerjain merged 1 commit into
mainfrom
feat/mysql-numeric-fidelity-fixture
Aug 17, 2026
Merged

feat(mysql-dual-conn): add a FLOAT/DOUBLE/BIGINT UNSIGNED fidelity fixture#150
slayerjain merged 1 commit into
mainfrom
feat/mysql-numeric-fidelity-fixture

Conversation

@slayerjain

Copy link
Copy Markdown
Member

Describe the changes that are made

Adds the fixture that would have caught keploy/keploy#4426, where keploy read MySQL FLOAT and DOUBLE result-set columns with a numeric conversion instead of an IEEE-754 reinterpret. A column holding 9.99 was recorded as 1.0926057e+09 (FLOAT) and 4.621813488089437e+18 (DOUBLE). The corruption happened at record time, so it survived re-recording and replay asserted against a value the database never returned.

Nothing in the e2e suite round-tripped a real typed row through record and replay, which is why the defect went unnoticed.

init.sql — a numeric_fidelity table with FLOAT, DOUBLE and BIGINT UNSIGNED columns, seeded with 9.99 plus sign, zero, whole and subnormal cases. The BIGINT UNSIGNED values above MaxInt64 cover the neighbouring defect: they have no lossless float64 form, so a mock format that routes them through one collapses distinct rows onto the same number.

QueryController — two endpoints:

Endpoint Covers
GET /api/oms/numerics binary-protocol result-set decode (FLOAT + DOUBLE + BIGINT UNSIGNED)
GET /api/oms/float-param/{v} COM_STMT_EXECUTE FLOAT parameter decode, and the matcher's mixed-width float comparison

Both bind a parameter deliberately. Without one, JdbcTemplate issues a plain Statement, Connector/J sends COM_QUERY, and MySQL answers with a text result set whose values are all length-encoded strings — which never touches the binary decode this fixture exists to cover. The OMS datasource already runs with useServerPrepStmts=true, so a bound parameter is all it takes.

Verification

Run locally against keploy 1b6ead43 (buggy) and against the #4426 fix:

buggy keploy fixed keploy
recorded price_f 1.0926057e+09 9.99
recorded ratio_d 4.621813488089437e+18 9.99
recorded big_u 18446744073709551615
replay 4/6, FAILED 6/6, PASSED

Both the YAML and JSON storage formats were exercised.

Consumer

The keploy-side PR wires these endpoints into .github/workflows/test_workflow_scripts/java/mysql_dual_conn/java-linux.sh, gated so only the record_build_replay_build matrix cell calls them — the fix has to be present in both binaries, so the cross-version cells self-skip.

This PR needs to merge first, otherwise the keploy-side guard fails on endpoints that do not exist yet.

…xture

keploy/keploy#4426: keploy read MySQL FLOAT and DOUBLE result-set columns
with a numeric conversion instead of an IEEE-754 reinterpret, so a column
holding 9.99 was recorded as 1.0926057e+09 (FLOAT) and
4.621813488089437e+18 (DOUBLE). The corruption happened at record time, so
it survived re-recording and replay asserted against a value the database
never returned.

Nothing in the e2e suite round-tripped a real typed row through record and
replay, which is why the defect went unnoticed. This adds the fixture that
would have caught it.

  - init.sql: a numeric_fidelity table carrying FLOAT, DOUBLE and BIGINT
    UNSIGNED columns, seeded with 9.99 plus sign, zero, whole and
    subnormal cases, and with BIGINT UNSIGNED values above MaxInt64 (no
    lossless float64 form, so a mock format routing them through one
    collapses distinct rows onto the same number).

  - GET /api/oms/numerics selects those columns and
    GET /api/oms/float-param/{v} binds a FLOAT parameter, covering the
    result-set decode and the COM_STMT_EXECUTE parameter decode
    respectively.

Both endpoints bind a parameter deliberately. Without one, JdbcTemplate
issues a plain Statement, Connector/J sends COM_QUERY, and MySQL answers
with a text result set whose values are all length-encoded strings — which
never touches the binary decode this fixture exists to cover. The OMS
datasource already runs with useServerPrepStmts=true, so a bound parameter
is all it takes to get a binary-protocol result set.

Verified locally against keploy at 1b6ead43 (buggy) and the #4426 fix:
the fixture records 1.0926057e+09 / 4.621813488089437e+18 on the former
and 9.99 / 9.99 on the latter, and replay goes 4/6 -> 6/6.

Signed-off-by: slayerjain <shubham@keploy.io>
@slayerjain
slayerjain merged commit 1133d02 into main Aug 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant