Как использовать типы INTERVAL в функции H SQL JRT? - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь создать функцию JRT, которая принимает параметр типа INTERVAL. Мой запрос может предоставить любой тип INTERVAL, но я бы предпочел использовать тип INTERVAL DAY, если это возможно.

Согласно документации H SQL , моя функция должна выглядеть примерно так как:

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

Затем функция должна быть зарегистрирована. В документации не указан тип INTERVAL DAY, указанный в документации, поэтому вместо него я буду использовать INTERVAL MONTH:

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

Пока все хорошо, моя функция зарегистрирована правильно и ошибки не отображаются.

Теперь я создам фиктивную таблицу, чтобы у меня было что-то для SELECT при тестировании функции:

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

Наконец, я могу попробовать вызвать саму функцию:

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

aa и я получаю сообщение об ошибке:

java .lang.IllegalArgumentException: несоответствие типов аргументов

Я сделал некоторую отладку, установил точку останова в java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) и получается, что H SQL передает org.hsqldb.types.IntervalMonthData в качестве аргумента методу (или org.hsqldb.types.IntervalSecondData для INTERVAL SECOND типа).

Когда тип параметра метода Java изменяется на IntervalMonthData, однако H SQL не может его распознать:

org.hsqldb.HsqlException: Java выполнение: неразрешенное имя класса, имя метода или подпись

Я также попробовал некоторые глупости, такие как передача INTERVAL '3' DAY в качестве аргумента. Затем выдается следующее исключение:

org.hsqldb.HsqlException: исключение данных: интервал переполнения поля

Функция работает, если мы изменим параметр на какой-то другой тип, например INT и соответствующий Integer. Это всего лишь INTERVAL, что кажется ненадежным.

Я использую H SQL в версии 2.5.0 (новейшей в Maven Central), минимальный рабочий пример:

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));
            }
        }
    }

}
...