Description:
When calling a stored procedure with datatype Decimal(m,d) (i.e. Decimal(18,0)) the Connector/J library throws the exception below. After looking into the code it appears that the getCallStmtParameterTypes method does not expect that a parameter datatype could include a comma. Therefore, any stored procedure created with a compound datatype: Float(M,D), Decimal(M,D), etc... will have this problem.
Error Message:
java.sql.SQLException: Internal error when parsing callable statement metadata (missing parameter type)
at com.mysql.jdbc.DatabaseMetaData.getCallStmtParameterTypes(DatabaseMetaData.java:6902)
Error in JDBC sampling: java.sql.SQLException: Internal error when parsing callable statement metadata (missing parameter type)
at com.mysql.jdbc.DatabaseMetaData.getProcedureColumns(DatabaseMetaData.java:2653)
at com.mysql.jdbc.CallableStatement.determineParameterTypes(CallableStatement.java:1042)
at com.mysql.jdbc.CallableStatement.<init>(CallableStatement.java:83)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:1248)
at com.mysql.jdbc.Connection.prepareCall(Connection.java:1225)
at TestCallableStatement.<init>(TestCallableStatement.java:34)
at TestCallableStatement.main(TestCallableStatement.java:112)
How to repeat:
Create Stored Procedure:
DELIMITER //
DROP PROCEDURE IF EXISTS TEST_PROC//
CREATE PROCEDURE TEST_PROC(decimalParam DECIMAL(18,0))
BEGIN
SELECT param_list FROM mysql.proc WHERE name='TEST_PROC';
END
//
Create Java / JDBC Program to call Stored Procedure
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.DriverManager;
import java.sql.CallableStatement;
public class TestClass
{
public TestClass()
{
Connection conn = null;
CallableStatement cStmt = null;
try
{
// Load class
Class.forName("com.mysql.jdbc.Driver");
// Modify URL with correct user, pass, host, and db name
conn = DriverManager.getConnection("jdbc:mysql://<HOST>/<DB>?user=<USER>&password=<PASS>");
cStmt = conn.prepareCall("Call TEST_PROC(?)");
cStmt.setDouble(1, 18.0);
cStmt.execute();
}
catch (Exception ex)
{
System.out.println("Error: " + ex);
ex.printStackTrace();
}
finally
{
if (cStmt != null)
{
try
{
cStmt.close();
}
catch (SQLException err)
{
cStmt = null;
}
}
try
{
if (conn != null && conn.isClosed() == false)
conn.close();
}
catch (SQLException err)
{
conn = null;
}
}
}
public static void main(String[] args)
{
new TestClass();
}
}
Suggested fix:
Work around:
Don't use , in defining JDBC called stored procedure parameters. For example, DECIMAL(18) instead of DECIMAL(18,0).
Fix:
On line 6836 of com.mysql.jdbc.DatabaseMetaData the statement for parsing the parameter list is "List parseList = StringUtils.split(parameterDef, ",", true);". Since this is the problem this needs to be modified. Either add some intelligence to the argument parsing or change how the parameter list is retrieved.