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]

Reply via email to