Проблема была не в синтаксисе, потому что синтаксис отлично работал с flyway или напрямую в PostgreSQL CLI. Проблема была в Hibernate, особенно с разбором файла импорта. Принцип работы Hibernate заключается в том, что он выполняет каждое выражение из файлов по отдельности, а не весь контент как единое выражение. Я попытался поместить все определения функций в одну строку, и это сработало, но не было читабельным. Таким образом, я обнаружил, что в Hibernate есть конфигурация, которая сообщает, что выражения могут быть многострочными, но разделитель $$
все еще не распознается при использовании в многострочном режиме.
Таким образом, решение состояло в том, чтобы определить команду с '
разделителем и затем экранировать одинарные кавычки, где необходимо, с дополнительным '
.
Решение состоит в том, чтобы установить spring.jpa.properties.hibernate.hbm2ddl.import_files_sql_extractor
для использования org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor
. MultipleLinesSqlCommandExtractor извлекает выражение SQL из нескольких строк и останавливается при наличии точки с запятой. Это конец выражения. Оборачивая тело функции в строку в одинарные кавычки, Hibernate будет обрабатывать эту обертку как одну строку.
data.sql
CREATE OR REPLACE FUNCTION insert_timeout_configuration() RETURNS bigint AS '
DECLARE created_id bigint;
BEGIN
INSERT INTO timeout_configuration (id, version, timeout)
VALUES (nextval(''my_sequence''), 0, 300)
RETURNING id INTO created_id;
return created_id;
END;
' language plpgsql;
CREATE OR REPLACE FUNCTION insert_url_configuration() RETURNS bigint AS '
DECLARE created_id bigint;
BEGIN
INSERT INTO url_configuration (id, version, my_url)
VALUES (nextval(''my_sequence''), 0,''http://localhost:8080/'')
RETURNING id INTO created_id;
return created_id;
END;
' language plpgsql;
DO '
INSERT INTO global_configuration(id, version, name, timeout_configuration_id, url_configuration_id)
VALUES (nextval(''my_sequence''), 0, ''My global config'', insert_timeout_configuration(), insert_url_configuration());
-- do some other code
END
';
drop function insert_timeout_configuration();
drop function insert_url_configuration();
Мне всегда нужно помнить, чтобы избежать выражений в выражениях, заключенных в одинарные кавычки, но теперь у меня может быть более читаемый исходный файл.