0

I am trying to create a JRT function that accepts a parameter of type INTERVAL. My query can provide any type of INTERVAL but I'd prefer to use INTERVAL DAY type if possible.

According to the HSQL documentation, my function should look something like:

public static String exampleHsqlFunction(final java.time.Period duration) {
    return "In example function, arg: " + duration.toString();
}

Then, the function needs to be registered. There is no INTERVAL DAY type specified in the table from documentation so I will use INTERVAL MONTH instead:

CREATE FUNCTION EXAMPLE_FUNCTION (duration INTERVAL MONTH)
RETURNS CHAR VARYING(100)
LANGUAGE JAVA DETERMINISTIC NO SQL
EXTERNAL NAME 'CLASSPATH:hsqltest.HsqlIntervalFunctionTest.exampleHsqlFunction';

So far so good, my function is registered properly and no errors are shown.

I will now create a dummy table so I have something to SELECT from when testing the function:

CREATE TABLE DUMMY(id INT); INSERT INTO DUMMY VALUES (0);

Finally, I can try calling the function itself:

SELECT EXAMPLE_FUNCTION(INTERVAL '3' MONTH) FROM DUMMY;

aaand I'm getting an error:

java.lang.IllegalArgumentException: argument type mismatch

I did some debugging, put a breakpoint in java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) and it turns out that HSQL passes org.hsqldb.types.IntervalMonthData as argument to the method (or org.hsqldb.types.IntervalSecondData for INTERVAL SECOND type).

When the parameter type of Java method is changed to IntervalMonthData, however, HSQL is not able to recognize it:

org.hsqldb.HsqlException: Java execution: unresolved class name, method name or signature

I also tried some silly stuff, such as passing INTERVAL '3' DAY as argument. Then the following exception is thrown:

org.hsqldb.HsqlException: data exception: interval field overflow

The function works if we change the parameter to some other type, for example INT and corresponding Integer. It's only INTERVAL that seems to be flaky.

I am using HSQL in version 2.5.0 (newest in Maven Central), minimal working example:

package hsqltest;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class HsqlIntervalFunctionTest {

    public static String exampleHsqlFunction(final java.time.Period duration) {
        return "In example function, arg: " + duration.toString();
    }

    public static void main(final String... args) throws SQLException {
        try (
            final Connection connection = DriverManager.getConnection(
                "jdbc:hsqldb:mem:testdb",
                "sa",
                "sa"
            );
            final Statement statement = connection.createStatement()
        ) {
            // create function and link it to Java method
            statement.executeUpdate(
                "CREATE FUNCTION EXAMPLE_FUNCTION (duration INTERVAL MONTH)"
              + " RETURNS CHAR VARYING(100)"
              + " LANGUAGE JAVA DETERMINISTIC NO SQL"
              + " EXTERNAL NAME 'CLASSPATH:hsqltest.HsqlIntervalFunctionTest.exampleHsqlFunction';"
            );

            // create dummy table so we have something to SELECT from
            statement.executeUpdate("CREATE TABLE DUMMY(id INT);");
            statement.executeUpdate("INSERT INTO DUMMY VALUES (0);");

            // use the function and print the result
            final ResultSet result = statement.executeQuery(
                "SELECT EXAMPLE_FUNCTION(INTERVAL '3' MONTH) FROM DUMMY;"
            );
            while (result.next()) {
                System.out.println(result.getString(1));
            }
        }
    }

}
Jezor
  • 3,253
  • 2
  • 19
  • 43
  • It seems that the Java type mapping for INTERVAL types is invalid: https://sourceforge.net/p/hsqldb/svn/HEAD/tree/base/trunk/src/org/hsqldb/types/Types.java#l624 – Jezor Jan 14 '20 at 12:23
  • Here is the mapping in `IntervalType`, the correct types are commented out for some reason: https://sourceforge.net/p/hsqldb/svn/HEAD/tree/base/trunk/src/org/hsqldb/types/IntervalType.java#l152 – Jezor Jan 14 '20 at 12:52
  • These comments turn out to be a feature: http://hsqldb.org/doc/guide/building-app.html#bga_codeswitcher – Jezor Jan 14 '20 at 13:00
  • Created a bug ticket in SourceForge: https://sourceforge.net/p/hsqldb/bugs/1564/ – Jezor Jan 14 '20 at 13:00

0 Answers0