fix: propagate ROW_COUNT() through stored procedures#25944
Conversation
# Conflicts: # pkg/frontend/authenticate.go
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
gouhongshen
left a comment
There was a problem hiding this comment.
Codex automated review
Two correctness gaps remain in affected-row propagation.
P1 - Preserve CALL status after result sets (pkg/frontend/result_row_stmt.go:434)
When CALL produces result sets, this branch creates ResultResponses with affectedRows=0 and emits no final OK/status response using execCtx.runResult. Therefore a procedure such as SELECT ...; UPDATE ... returns the result set but the client receives 0 instead of the final UPDATE count. MySQL requires CALL status in addition to procedure result sets: CALL documentation.
P2 - Record failed Starlark SQL as -1 (pkg/frontend/starlark_interpreter.go:231)
backExec.Exec now stores -1 on failure, but this early return skips recordAffectedRows. Since doInterpretCall later reads interpreter.lastAffectedRows, a handled final mo.sql error leaves the previous successful count visible to CALL and ROW_COUNT().
gouhongshen
left a comment
There was a problem hiding this comment.
Codex automated review
No actionable findings. The earlier protocol-final-OK and Starlark failure-state findings are addressed at this head. Focused Go tests were blocked locally by missing cgo dependency xxhash.h.
XuPeng-SH
left a comment
There was a problem hiding this comment.
Three correctness gaps remain in the ROW_COUNT()/CALL propagation path. I verified the expected behavior against MySQL 8.4 and traced each failure through the current head. The focused frontend tests and current non-skipped CI checks pass, but they do not cover these procedure-boundary cases. Please address the three inline findings and add the corresponding SQL/BVT and protocol coverage.
XuPeng-SH
left a comment
There was a problem hiding this comment.
Requesting changes because the new MySQL-protocol regression test does not pass repository static analysis. The current SCA job fails on one unchecked rows.Err() path and two *sql.Rows lifetimes that are not closed with defer; this failure also causes much of the downstream CI matrix to be skipped.
I re-reviewed the functional closure at c497730: the previous gaps around procedural-only statements, nested CALL result propagation, and caller ROW_COUNT seeding are fixed. Resource/transaction ownership and failure-state propagation did not reveal another blocker.
Fresh local validation on this exact HEAD:
- go build ./pkg/frontend ./pkg/embed
- go vet ./pkg/frontend ./pkg/embed
- go test -count=1 -timeout=300s ./pkg/frontend
- affected-row / nested-CALL focused tests with -race -count=10
- go test -count=1 -run TestRowCountOverMySQLProtocol ./pkg/embed
- git diff --check
All of those pass; the requested change is the confirmed repository-SCA failure described inline.
| require.NoError(t, err) | ||
| _, err = conn.ExecContext(ctx, "insert into t values (6), (7), (8), (9), (10), (11)") | ||
| require.NoError(t, err) | ||
| rows, err := conn.QueryContext(ctx, "call caller_count()") |
There was a problem hiding this comment.
[P1] Keep the new protocol test lint-clean
This test opens two *sql.Rows values, but neither lifetime is protected by a deferred Close, and this first result path never checks rows.Err() after iteration. The current SCA run fails here with rowserrcheck plus two sqlclosecheck errors (the two explicit closes at lines 250 and 271), so most downstream jobs are skipped. Please add a deferred close for each successful query and check rows.Err() after consuming each result set (scoping the two queries separately is also fine).
What type of PR is this?
Which issue(s) this PR fixes:
issue #24783
What this PR does / why we need it:
ROW_COUNT()did not observe DML affected rows executed by stored procedureinterpreters, and
CALLdid not propagate the procedure's final affected-rowcount back to the caller or its MySQL OK packet.
This change carries affected rows through background execution, snapshots the
last body-statement result in the SQL and Starlark interpreters, and propagates
the final value through
CALL. It also keeps nested procedures on the sharedbackground transaction and adds unit, protocol, and BVT coverage.
Validation:
mo-cgo-test -count=1 -timeout=240s ./pkg/frontendmo-cgo-test -count=1 -timeout=300s -run '^TestRowCountOverMySQLProtocol$' ./pkg/embedgo vet ./pkg/frontend ./pkg/embedmake -j8 buildrow_count.sql: 83/83 passed