morningman opened a new issue, #67369: URL: https://github.com/apache/doris/issues/67369
### Search before asking - [X] I had searched in the [issues](https://github.com/apache/doris/issues?q=is%3Aissue) and found no similar issues. ### Version Apache Doris 4.1.3-rc02, commit `31263df4dc1d4d3a27517d264802cd4d6b92c874` Client: Python + ADBC Flight SQL driver (`adbc_driver_flightsql`), FE `arrow_flight_sql_port` = 41070. The MySQL/JDBC protocol is used as the control path for comparison. ### What's Wrong? Executing a PL/SQL `CALL` that contains an `INSERT` **once** over Python ADBC Flight SQL returns an error to the client: ``` INTERNAL: getMysqlChannel not in mysql connection ``` but the procedure's `INSERT` side effect is actually executed **four times**. A single call must execute its side effect at most once. Two independent ADBC calls (keys `444` and `666`) each produced exactly four rows. The JDBC control call (key `555`) succeeded and produced exactly one row. ### What You Expected? A single `CALL` should succeed and insert exactly one row. If `CALL` is not supported over the Flight SQL protocol, the server must reject it *before* executing anything, and must never repeat DML side effects after returning an error. ### How to Reproduce? 1. Create the table and the stored procedure below. 2. Execute `CALL plsql_variable_insert(444,'adbc444')` **once** over Python ADBC. 3. Observe the `INTERNAL` error returned by ADBC. 4. Over MySQL/JDBC, count the rows for `id=444`; `COUNT(*)` is 4. 5. Run the same `CALL` for key `555` over JDBC; `COUNT(*)` is 1. ```sql DROP TABLE IF EXISTS plsql_variable; CREATE TABLE plsql_variable ( id INT, name VARCHAR(20) ) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 4 PROPERTIES ("replication_num"="1"); CREATE OR REPLACE PROCEDURE plsql_variable_insert(IN id INT, IN name STRING) BEGIN INSERT INTO plsql_variable VALUES(id,name); END; -- Execute this ONCE through Python ADBC Flight SQL. CALL plsql_variable_insert(444,'adbc444'); -- Inspect through MySQL/JDBC after the ADBC error. SELECT id, name, COUNT(*) FROM plsql_variable WHERE id=444 GROUP BY id, name; ``` Client side: ```python import adbc_driver_flightsql.dbapi as flight_sql conn = flight_sql.connect(uri="grpc://127.0.0.1:41070", db_kwargs={"username": "root", "password": ""}) cur = conn.cursor() cur.execute("CALL plsql_variable_insert(444,'adbc444')") ``` ### Anything Else? The error message (`getMysqlChannel not in mysql connection`) shows that the PL/SQL executor assumes a MySQL channel is available on the session. On a Flight SQL connection that assumption does not hold, and the failure apparently happens after the statement has already been executed, and is then retried, so the DML lands multiple times. Data correctness impact: this can silently duplicate writes. **Workaround:** run PL/SQL `CALL` over the MySQL/JDBC protocol. Clients must not auto-retry on this error, since the server may already have applied the side effect. Tracking issue: #65615 ### Are you willing to submit PR? - [ ] Yes I am willing to submit a PR! ### Code of Conduct - [X] I agree to follow this project's [Code of Conduct](https://www.apache.org/foundation/policies/conduct) -- 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]
