Ошибка синтаксиса в процессе создания агрегированных
Попытка создать агрегатную функцию:
create aggregate min (my_type) (
sfunc = least,
stype = my_type
);
ERROR: syntax error at or near "least"
LINE 2: sfunc = least,
^
Что я упускаю?
Хотя руководство вызывает least функцию:
Наибольшая и наименьшая функции выбирают наибольшее или наименьшее значение из списка любого числа выражений.
Я не могу его найти:
dfS least
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------+------------------+---------------------+------
(0 rows)
2 ответа:
LEASTиGREATESTне являются реальными функциями; внутренне они разбираются какMinMaxExpr(см.src/include/nodes/primnodes.h).Вы можете достичь желаемого с помощью такой универсальной функции:
CREATE FUNCTION my_least(anyelement, anyelement) RETURNS anyelement LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT AS 'SELECT LEAST($1, $2)';(Спасибо Эрвину Брандштеттеру за
CALLED ON NULL INPUTи идею использоватьLEAST.)Тогда вы можете создать свой агрегат как
CREATE AGGREGATE min(my_type) (sfunc = my_least, stype = my_type);Это будет работать только в том случае, если существуют функции сравнения для
my_type, в противном случае вам придется придумать другую функциюmy_least.
Как
CASE,COALESCEи ещеNULLIF,GREATESTиLEASTперечислены в главе условные выражения. Эти конструкции SQL не реализуются как функции .. как @Laurenz обеспечил в то же время.Руководство советует:
Совет: Если ваши потребности выходят за рамки возможностей этих условных выражения, вы можете рассмотреть возможность записи хранимой процедуры в более выразительное Программирование язык.
Терминология здесь тоже немного не та, поскольку Postgres не поддерживает истинные "хранимые процедуры", а только функции. (Именно поэтому существуетоткрытый пункт TODO "реализация хранимых процедур".)
Эту страницу руководства можно было бы заострить, чтобы избежать путаницы ...
@Laurenz также привел пример. Я бы просто использовал
LEASTв функции, чтобы получить идентичную функциональность:CREATE FUNCTION f_least(anyelement, anyelement) RETURNS anyelement LANGUAGE sql IMMUTABLE AS 'SELECT LEAST($1, $2)';Do нет сделайте это
STRICT, чтобы это было бы неверно.LEAST(1, NULL)возвращает1, а неNULL.Даже если бы
Обратите внимание, что эта функция ограничена ровно двумя параметрами, в то время какSTRICTбыл правильным, я бы не стал его использовать, потому что он может предотвратить подстановку функций.LEASTпринимает любое число параметров. Вы можете перегрузить функцию, чтобы покрыть 3, 4 и т. д. входной параметр. Или вы можете написать функциюVARIADICДля 100 параметров.