zclllyybb commented on issue #65848: URL: https://github.com/apache/doris/issues/65848#issuecomment-5031906686
Breakwater-GitHub-Analysis-Slot: slot_c0710c8beb32 This content is generated by AI for reference only. Initial code-path analysis: this looks like a real FE prepared-statement forwarding bug, not a BE/storage issue. I checked the affected 4.1.x code path in the Doris tags `4.1.0-rc03`, `4.1.1-rc01`, and `4.1.2-rc01`, and also refreshed `upstream/master` (`6f4134cbe426f2385cf2515c3e409b3c2706c8d7`, 2026-07-21). The same state-transfer shape is still present. Why the reported behavior matches the code: 1. `MysqlConnectProcessor.handleExecute()` caches the raw binary execute buffer in `ConnectContext.prepareExecuteBuffer` before parsing parameters. It only rewrites the `PrepareCommand` with typed `Placeholder`s when `new_params_bind_flag != 0`. 2. For a direct connection to the same FE, repeat `COM_STMT_EXECUTE` packets with `new_params_bind_flag = 0` can work because that FE's `PreparedStatementContext.command` already contains typed placeholders from the first execute. 3. For a redirected write on a follower FE, `StmtExecutor.forwardToMaster()` sends a `TMasterOpRequest` through `FEOpExecutor`. The request carries `sql` and `prepareExecuteBuffer`, but the thrift request has no field for the cached placeholder MySQL type codes. 4. On the master, `ConnectProcessor.proxyExecute()` prepares the SQL again in a fresh proxy context, then calls `handleExecute()` with the forwarded execute buffer. If that buffer is a cached repeat execute with `new_params_bind_flag = 0`, the master never receives or rebuilds the placeholder types. 5. The next parameter parse calls `prepareCommand.getPlaceholders().get(i).getMysqlColType()`, and `Placeholder.getMysqlColType()` unwraps an empty `Optional`. That is consistent with the reported `NoSuchElementException` stack, and also explains why first execute succeeds, repeated cached executes fail, master-direct succeeds, and fresh-connection-per-insert avoids the issue. Suggested fix direction: - Preferred: transfer the placeholder MySQL type codes/signedness across the forward RPC, or have the follower reconstruct a forwardable execute representation that includes the cached types when the client sends `new_params_bind_flag = 0`. The follower already has this state in its `PreparedStatementContext.command` after the first execute. - A master-only fallback from bound values is risky because the MySQL binary value parser needs the type before it can parse each value correctly. - Even after the functional fix, the missing-type state should be converted to a clear Doris error instead of allowing `Optional.get()` to surface as errCode 1105. Recommended validation: - Add a regression/integration test that prepares an `INSERT` through a follower FE, executes once with parameter type bytes present, then repeats on the same connection with `new_params_bind_flag = 0`, and verifies that the rows are inserted through master forwarding. - Please also attach the exact Doris build commit for the tested Docker image and the full master FE `fe.log` stack from the 4.1.2 reproduction, mainly to map the image to an official source revision. The current report is already sufficient to point to the FE forward-state bug. Operational workaround until a fix is available: route server-prepared write traffic to the master FE, or disable client-side prepared-statement caching / use a client mode that resends parameter types on each execute. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
