Affects:

V6.1.11 and others

Problem statement

The given situation: a legacy Informix database and a defined function with a signature similar to this:

CREATE FUNCTION create_lock (
    type            VARCHAR
  , external_ref VARCHAR
)
RETURNS INTEGER AS lock_id;

In our spring service we originally called this like

database // ebean Database object
                .sqlQuery("execute function create_lock (type = :type, external_ref = :ref)")
                .setParameter("type", type)
                .setParameter("ref", externalRef)
                .findOne()!!
                .get("lock_id")

We now try to move this towards a SimpleJdbcCall and this is my code that I think should work:

        val lockStartAction =
            SimpleJdbcCall(dataSource)
                .withoutProcedureColumnMetaDataAccess() // Informix not supported
                .withFunctionName("create_lock")
                .withReturnValue()
                .declareParameters(
                    // SqlOutParameter("lock_id", Types.INTEGER), 
                    SqlParameter("type", Types.VARCHAR),
                    SqlParameter("external_ref", Types.VARCHAR),
                )
        val lockId =
            lockStartAction.executeFunction(Int::class.java, mapOf("type" to type, "external_ref" to externalRef))

If I run this, the code fails with:

org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call create_lock(?)}]; SQL state [IX000]; error code [-674]; Routine (create_lock) can not be resolved.

You can see, that the function is not found due to the number of parameters in the signature being one instead of two

If I change the code above and add the SqlOutParameter to the declared parameters, the exception changes to:

CallableStatementCallback; uncategorized SQLException for SQL [{? = call create_lock(?, ?)}]; SQL state [IX000]; error code [-79827]; Function doesn't have an output parameter or the out parameter isn't returned.

Now the signature looks right, the function is found, but the code correctly complains about the function not having an OUT parameter.

Using a SqlParameter constructor instead of the SqlOutParameter makes this fail later at executeFunction due to missing input parameter.

I did not find a way to define the returned property so that the callable statement is correctly generated and the parameters are correctly applied.

IMHO either there is a SqlParameter subtype missing that could be provided in the parameter list to specify the name of the return value, or if this should have been handled by .withReturnValue() and no further parameter needs to be listed, then the code generating the callable statement from the parameter list needs to be fixed to count it's placeholders (?) properly.

Please advise.