Skip to content

fix: propagate ROW_COUNT() through stored procedures#25944

Open
ck89119 wants to merge 6 commits into
matrixorigin:mainfrom
ck89119:issue-24783-main
Open

fix: propagate ROW_COUNT() through stored procedures#25944
ck89119 wants to merge 6 commits into
matrixorigin:mainfrom
ck89119:issue-24783-main

Conversation

@ck89119

@ck89119 ck89119 commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • API-change
  • BUG
  • Improvement
  • Documentation
  • Feature
  • Enhancement
  • Refactoring
  • Performance
  • Test and CI
  • Infrastructure
  • Other

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 procedure
interpreters, and CALL did not propagate the procedure's final affected-row
count 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 shared
background transaction and adds unit, protocol, and BVT coverage.

Validation:

  • mo-cgo-test -count=1 -timeout=240s ./pkg/frontend
  • mo-cgo-test -count=1 -timeout=300s -run '^TestRowCountOverMySQLProtocol$' ./pkg/embed
  • targeted frontend race tests
  • go vet ./pkg/frontend ./pkg/embed
  • make -j8 build
  • row_count.sql: 83/83 passed

@matrix-meow matrix-meow added size/L Denotes a PR that changes [500,999] lines and removed size/M Denotes a PR that changes [100,499] lines labels Jul 21, 2026
@ck89119
ck89119 marked this pull request as ready for review July 21, 2026 08:03
@ck89119
ck89119 requested review from XuPeng-SH and heni02 as code owners July 21, 2026 08:03
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@gouhongshen gouhongshen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 gouhongshen left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread pkg/frontend/plsql_interpreter.go Outdated
Comment thread pkg/frontend/back_exec.go
Comment thread pkg/frontend/authenticate.go

@XuPeng-SH XuPeng-SH left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread pkg/embed/cluster_test.go
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()")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Something isn't working size/L Denotes a PR that changes [500,999] lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants