用户定义的 SQL-函数计算错误

Wrong Calculation by User-Defined SQL-Function

我有一个由

定义的函数
CREATE OR REPLACE FUNCTION public.div(dividend INTEGER, divisor INTEGER)
    RETURNS INTEGER
    LANGUAGE 'sql'
    IMMUTABLE
    LEAKPROOF
    STRICT
    SECURITY DEFINER
    PARALLEL SAFE
    AS $BODY$
        SELECT ( + /2) / ;
    $BODY$;

它应该计算一个商业四舍五入的结果。大多数时候,它完成了工作。我不知道为什么,但是 select div(5, 3) 给了我正确的答案,而当一个参数是由聚合计算时却没有,例如select div(sum(val), 3) from (select 1 as val UNION SELECT 4) list 足以触发它。 我该如何修复 div?我不想投射每一个输入。

顺便说一句,使用 SELECT (cast( as integer) + cast( as integer)/2) / cast( as integer); 作为 div 的定义没有帮助。

更改函数的名称。

函数 div(numeric, numeric) 是一个内置的 Postgres 函数,你想调用哪个函数有歧义:

select div(5, 3)           -- calls your function public.div(integer, integer)
select div(5::bigint, 3)   -- calls pg_catalog.div(numeric, numeric)

在第二种情况下,必须解析参数,首先选择系统函数。

请注意,函数 sum(integer) 给出了 bigint 作为结果。

允许浮点数作为参数,然后在计算时显式转换,否则在传递参数时会进行隐式转换。

CREATE OR REPLACE FUNCTION my_div(dividend FLOAT, divisor FLOAT)
    RETURNS INTEGER
    LANGUAGE 'sql'
    IMMUTABLE
    -- LEAKPROOF -- not allowed at dbfiddle.uk
    STRICT
    SECURITY DEFINER
    PARALLEL SAFE
    AS $BODY$
        SELECT --( + /2) / ;
           (cast( as integer) + cast( as integer)/2) / cast( as integer)
    $BODY$;
select my_div(sum(val), 3) 
from (select 1 as val UNION SELECT 4) x
| my_div |
| -----: |
|      2 |

dbfiddle here