morningman opened a new pull request, #67521:
URL: https://github.com/apache/doris/pull/67521

   ### What problem does this PR solve?
   
   Issue Number: close #67369
   
   Related PR: #58700 (removed PL/SQL from master)
   
   Problem Summary:
   
   Running a PL/SQL `CALL` over an Arrow Flight SQL / ADBC connection returns
   `INTERNAL: getMysqlChannel not in mysql connection` to the client **after** 
the procedure body has
   already run, so a `CALL` that contains DML applies its side effect and still 
reports failure. Clients
   that retry on that error duplicate the write.
   
   The PL/SQL interpreter is wired to the session's MySQL channel throughout:
   
   - `PlSqlOperation.execute()` ends its `finally` block with an unconditional 
`ctx.getMysqlChannel().reset()`;
   - `PlsqlResult` writes rows with `MysqlChannel.sendOnePacket()` / 
`getSerializer()`;
   - `PlsqlQueryExecutor.executeQuery()` runs every inner statement on a 
`ConnectContext.cloneContext()`,
     and `cloneContext()` builds a plain `ConnectContext` (`connectType = 
MYSQL`) while copying
     `mysqlChannel`, which is `null` on a Flight SQL session.
   
   `FlightSqlConnectContext.getMysqlChannel()` throws, but the throw happens in 
the `finally` block, i.e.
   after `Exec.parseAndEval()` has already executed the body. The exception is 
swallowed into an ERR state,
   `DorisFlightSqlProducer.executeQueryStatement()` turns that into `after 
executeQueryStatement handleQuery`,
   and the client sees `INTERNAL`.
   
   This PR refuses the statement in `CallProcedure.create()`. 
`CallCommand.run()` calls
   `CallFunc.getFunc()` — and therefore `create()` — before `CallFunc.run()`, 
so the check fires before
   anything is executed and before the `PlSqlOperation` interpreter is even 
constructed. The two built-in
   `CALL` functions (`EXECUTE_STMT`, `FLUSH_AUDIT_LOG`) are matched earlier in 
`CallFunc.getFunc()` and are
   unaffected; they keep working on Arrow Flight SQL.
   
   **Why this targets `branch-4.1` directly:** PL/SQL no longer exists on 
master — #58700 deleted the whole
   `org.apache.doris.plsql` package, the `PLLexer.g4` / `PLParser.g4` grammars, 
`CallProcedure`, and the
   `CREATE|DROP|SHOW CREATE PROCEDURE` grammar rules. On master `CALL 
<procedure>` is already rejected by
   `CallFunc.getFunc()` with `do not support call function X` before any 
execution, so the bug is not
   reproducible there and there is no master change to pick from. `branch-4.0` 
and `branch-3.1` still carry
   the same code and can take this commit as-is.
   
   **Not covered:** on a follower/observer FE, `CallCommand` is 
`ForwardWithSync`, so the statement is
   forwarded to the master before this check runs and is executed there against 
a proxy MySQL context. That
   path does not go through `FlightSqlConnectContext.getMysqlChannel()` and is 
left unchanged by this PR.
   
   ### Release note
   
   Fix a `CALL <stored procedure>` over an Arrow Flight SQL connection 
returning an error after its DML had
   already been applied. Stored procedures are now rejected up front on 
non-MySQL protocol connections.
   
   ### Check List (For Author)
   
   - Test
       - [x] Regression test
           - 
`regression-test/suites/arrow_flight_sql_p0/test_call_procedure_not_supported.groovy`:
             creates a procedure that inserts one row, calls it over Arrow 
Flight SQL, asserts the call is
             rejected, asserts the table is still empty, then asserts the same 
`CALL` still works over the
             MySQL protocol.
       - [ ] Unit Test
       - [ ] Manual test (add detailed scripts or steps below)
       - [ ] No need to test or manual test. Explain why:
   
   - Behavior changed:
       - [x] Yes. `CALL <stored procedure>` on a non-MySQL protocol connection 
(today: Arrow Flight SQL)
         now fails with `Stored procedure is only supported on the MySQL 
protocol, but the current
         connection type is ARROW_FLIGHT_SQL. Please run CALL over a MySQL 
protocol connection.` instead of
         executing the body and then reporting `getMysqlChannel not in mysql 
connection`. It never worked on
         that protocol; it now fails without a side effect.
   
   - Does this need documentation?
       - [x] No.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   
   https://claude.ai/code/session_01XEqxvGojqgh8LpovPdTDJt
   


-- 
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