[bug]: COM_STMT_FETCH / useCursorFetch=true not supported — cursor rows never recorded, replay drops the connection
Author: slayerjainCreated Jun 9, 2026Updated Sep 2, 2026
Labelsbug
Is there an existing issue for this?
- Searched; this tracks a gap noted in #4260.
Current behavior
With MySQL Connector/J on a JDBC URL that has useCursorFetch=true and a
statement with setFetchSize(n) > 0, the driver opens a server-side cursor on
COM_STMT_EXECUTE (response = column-defs + EOF, no rows) and pages the rows
with repeated COM_STMT_FETCH (0x1C) commands.
keploy does not support this:
COM_STMT_FETCHis not decoded —pkg/models/mysql/const.go:177has the constant commented out (and the old value0x19was wrong;0x19isCOM_STMT_CLOSE, real FETCH is0x1C), and the decode case atpkg/agent/proxy/integrations/mysql/wire/decode.go:397is commented out. So FETCH falls to thedefaultbranch and is recorded as an unknown base64 packet withpacket_type: "0x1c".- The recorder never captures the FETCH response. Unknown
0x-prefixed packets are recorded as no-response mocks atpkg/agent/proxy/integrations/mysql/recorder/query.go:503-512(responses: [],responseOperation: NO Response Packet), so the cursor's row chunks are lost at record time. - On replay, the live
COM_STMT_FETCHhas no matcher case, somatchCommandreturnsok=falseandquery.godrops the connection with "no matching mock found" (since FETCH is a response command, this is fatal). This also tears down a pooled HikariCP connection, cascading 500s onto unrelated requests that reuse it.
pkg/models/mysql/comm.go:145 already documents this: "COM_STMT_FETCH packet
is not currently supported because its response involves multi-resultset."
Steps to Replicate
Against the tidb-stmt-cache sample (add useCursorFetch=true to the JDBC URL
and an endpoint that setFetchSize(2) on a multi-row SELECT):
keploy recordthe cursor endpoint → recorded mocks containpacket_type: "0x1c"withresponses: [].keploy testwith the DB down → connection drops on0x1c:Connection closing due to no matching mock found … request_type: "0x1c".
Proposed scope
This is a feature, not a one-line fix. Needs:
- define
COM_STMT_FETCH byte = 0x1C(+ string map) and wire the existingpreparedstmt.DecodeStmtFetch; - recorder: treat FETCH as a response command and capture each binary result-set chunk (rows + EOF with cursor-status flags);
- replayer: a
matchCommandcase that resolves FETCH by stmtID→query and serves the recorded chunks in FIFO order; - handle the cursor
EXECUTEresponse (col-defs + EOF, zero rows).
Environment
- keploy: v3 (main); MySQL integration matcher path.
- Driver: mysql-connector-j 8.x; server: TiDB :4000 (MySQL wire protocol).
- Repro: native (eBPF) on Linux; would also repro in Docker.
Tracked alongside #4260.
Source: keploy/keploy