daguimu opened a new pull request, #8028:
URL: https://github.com/apache/incubator-seata/pull/8028
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
- [x] I have read the
[CONTRIBUTING.md](https://github.com/apache/incubator-seata/blob/2.x/CONTRIBUTING.md)
guidelines.
- [ ] I have registered the PR
[changes](https://github.com/apache/incubator-seata/tree/2.x/changes). (Will
update after PR number is assigned)
### Ⅰ. Describe what this PR did
## Problem
When performing batch INSERT with function expressions that contain hidden
JDBC parameter placeholders (e.g. `ST_GeomFromText(CONCAT('POINT(', ?, ' ', ?,
')'))`) and 3+ rows, `parsePkValuesFromStatement()` throws
`NotSupportYetException` because it extracts wrong PK values due to incorrect
parameter index calculation.
## Root Cause
In `BaseInsertExecutor.parsePkValuesFromStatement()`, the code counts
visible `?` placeholders from the parsed row structure to track JDBC parameter
positions across rows. However, when `getInsertRows()` encounters a
`SQLMethodInvokeExpr` (function call), it wraps it as a single `SqlMethodExpr`
marker object, hiding any `?` parameters inside the function. This causes
`totalPlaceholderNum` to undercount the actual JDBC parameters per row, making
the parameter index calculation wrong for row 2 onwards. The error accumulates
with each row, so it typically manifests with 3+ rows.
## Fix
After counting visible placeholders in each row, calculate the number of
hidden parameters per row by comparing the actual JDBC parameter count
(`parameters.size() / nonEmptyRowCount`) with the visible placeholder count.
Add this `hiddenParamsPerRow` to `totalPlaceholderNum` after processing each
row so subsequent rows get the correct parameter offset.
- `BaseInsertExecutor.java`: Added hidden parameter compensation logic in
`parsePkValuesFromStatement()`
- `MySQLInsertExecutorTest.java`: Added 3 test cases
## Tests Added
- `testGetPkValuesByColumn_BatchInsertWithFunctionExpression`: 3-row batch
INSERT with `SqlMethodExpr` hiding 2 extra params per row — verifies all 3 PK
values are correctly extracted
- `testGetPkValuesByColumn_BatchInsertWithoutFunctionExpression`: 3-row
batch INSERT without function expressions — regression test
- `testGetPkValuesByColumn_SingleInsertWithFunctionExpression`: Single-row
INSERT with function expression — boundary case
## Impact
Only affects the parameter index calculation in
`parsePkValuesFromStatement()` when function expressions with hidden parameters
are present. No behavioral change for INSERTs without function expressions
(`hiddenParamsPerRow` remains 0).
### Ⅱ. Does this pull request fix one issue?
Fixes #6941
### Ⅲ. Why don't you add test cases (unit test/integration test)?
Test cases are included (3 new tests).
### Ⅳ. Describe how to verify it
Run the unit tests:
```
mvn test -pl rm-datasource -Dtest=MySQLInsertExecutorTest
```
### Ⅴ. Special notes for reviews
The fix uses `parameters.size() / nonEmptyRowCount` to determine actual JDBC
parameters per row. This is safe because all rows in a multi-value INSERT share
the same column structure. The `nonEmptyRowCount` accounts for Oracle's edge
case of appending an empty row for `:rowid`.
--
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]