…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>
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:
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:
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.