[CONJ-1069] DatabaseMetaData#getProcedureColumns reports incorrect data after executing a stored procedure Created: 2023-04-11  Updated: 2023-06-07  Resolved: 2023-06-07

Status: Closed
Project: MariaDB Connector/J
Component/s: stored procedure
Affects Version/s: 2.7.2, 3.1.0
Fix Version/s: N/A

Type: Bug Priority: Major
Reporter: Julian Bui Assignee: Diego Dupin
Resolution: Not a Bug Votes: 0
Labels: None
Environment:

mac, mariadb server 10.6.9, java 8, used dbeaver to create/replace the stored procedures


Issue Links:
Blocks
is blocked by MDEV-31064 I_S.parameters not immediatly changed... Closed

 Description   

Noteworthy:

  1. This repro exhibits a problem found in mariadb jdbc driver 2.7 and 3.1.
  2. Interestingly, using the mysql driver did not exhibit this problem.
  3. The mariadb jdbc driver code pulls from information_schema.parameters to implement #getProcedureColumns. However, if you query this table via DBeaver (or other client), it does in fact show the correct number of parameters/columns.

REPRO:

1) Create a stored procedure with two parameters:

delimiter //
create or replace procedure test(p1 int, p2 int)
BEGIN
select p1 as 'p1';
END
//

2. In the java code (found down below) replace the jdbcUrl, userName, password, and spName (e.g., value = test) variables and then run the application. The application will execute the stored procedure then call getProcedureColumns in a loop forever. Observe that it reports the correct number of stored procedure parameters parameters/columns (in this case, 2).

3. Remove one of the parameters of the stored procedure and then replace the procedure of step 1.

delimiter //
create or replace procedure test(p1 int)
BEGIN
select p1 as 'p1';
END
//

4.
EXPECTATION: that as soon as you perform step 3, the app reports 1 parameter.
ACTUAL: after performing step 3, the app continues to report 2 parameters.

-----------

Repro java application of step 2:

import java.sql.*;
 
public class GetProcedureColumnsRepro {
  public static void execute() throws SQLException {
    String jdbcUrl = "jdbc:mariadb://localhost:3306/YOURDB";
//    String jdbcUrl = "jdbc:mysql://localhost:3306/YOURDB";
    String userName = "yourusername";
    String password = "yourpassword";
    String spName = "yourstoredprocedurename";
 
    try (Connection conn = DriverManager.getConnection(jdbcUrl, userName, password)) {
      System.out.println("---");
      DatabaseMetaData databaseMetaData = conn.getMetaData();
 
      // EXECUTE A STORED PROCEDURE
      try (CallableStatement call = conn.prepareCall("{call " + spName + "(?, ?)}")) {
        call.setQueryTimeout(0);
        call.setObject(1, 1);
        call.setObject(2, 2);
        call.execute();
      } catch (Exception e) {
        System.out.println("Should not have encountered error here. Make sure the procedure was created before starting the repro: " + e.getMessage());
        throw e;
      }
 
      // LOOP FOREVER, REPORTING THE PROCEDURE'S PARAMETERS
      while (true) {
        try (ResultSet rs = databaseMetaData.getProcedureColumns(null, null, spName, null)) {
          String columns = "";
          while (rs.next()) {
            columns += rs.getString("COLUMN_NAME") + ",";
          }
          System.out.println("GetProcedureColumns found: " + columns);
        }
      }
    } catch (Exception e) {
      System.out.println("e: " + e.getMessage());
    }
  }
}



 Comments   
Comment by Diego Dupin [ 2023-04-17 ]

mysql connector implementation completly differ from mariadb connector :

mysql try to use mysql.proc first, and if not working (mysql 8 has removed that table) use SHOW PROCEDURE STATUS to find procedures, then runs SHOW CREATE PROCEDURE command to get procedure code and extract parameters.

mariadb use directly INFORMATION_SCHEMA.parameters that is way faster.

Problem (reproduced) is that if a connection has called a procedure and that procedure is changed by another connections, then metadata is then wrong.
This is a server issue and i've create a issue for that https://jira.mariadb.org/browse/MDEV-31064
(tested and MySQL 8.0.32 doesn't have this issue)

Comment by Diego Dupin [ 2023-06-07 ]

closing since this will not be corrected connector side but server side with https://jira.mariadb.org/browse/MDEV-31064

Generated at Thu Feb 08 03:20:23 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.