Bug #111107 CallableStatement::getParameterMetaData reports incorrect parameterCount
Submitted: 22 May 15:54 Modified: 18 Aug 14:06
Reporter: Jason Boyer Email Updates:
Status: Analyzing Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:8.0.33, 8.1.0 OS:Any
Assigned to: MySQL Verification Team CPU Architecture:Any

[22 May 15:54] Jason Boyer
Description:
When getting the parameterCount for a procedure via callableStatement.getParameterMetaData().getParameterCount(), the result is one less that the actual parameter count (i.e. the number of placeholders).

How to repeat:
Here is a JUnit test that demonstrates the error.
This test will fail.

    @Test
    void callStoredProcedure()  {
        try (Connection connection = ds.getConnection()) {
            try (Statement statement = connection.createStatement()) {
                statement.execute("DROP PROCEDURE IF EXISTS test.badParameterCount");
                String definition = """
                        CREATE PROCEDURE test.badParameterCount(a BIGINT, b BIGINT, c BIGINT, d BIGINT)
                        BEGIN
                            SELECT 1;
                        END
                        """;
                statement.execute(definition);
            }
            try (PreparedStatement ps = connection.prepareCall("CALL test.badParameterCount(?,?,null,null)")) {
                ParameterMetaData pmd = ps.getParameterMetaData();
                assertEquals(2, pmd.getParameterCount(), "parameter count");
            }
        } catch (SQLException e) {
            fail(e);
        }
    }

Suggested fix:
In https://github.com/mysql/mysql-connector-j/blob/release/8.0/src/main/user-impl/java/com/my... line 181, there is an if statement that skips adding the first placeholder if it maps to the zeroth parameter. I believe that this should only apply to functions, not procedures.
(See the use of isFunctionCall on line 178.)

So, the if statement should be something along the lines of:

if (localParameterMap[i] != 0 || !this.isFunctionCall) {
[22 May 19:15] Jason Boyer
This only occurs when the query parameter count differs from the metadata parameter account. In the example:
 - the metadata parameter count is 4 because there are four procedure parameters, including the two NULLs.
 - the query parameter count is 2 because there are two occurrences of "?"
If the both counts are the same (i.e. all procedure parameters are specified with placeholders) the the code path leading to this bug is not followed, and it returns the correct number of results.
[18 Aug 14:06] Jason Boyer
This bug is still present in version 8.1.0.