我使用PostgreSQL 10.3。
我创建了以下域名:
CREATE DOMAIN common.citext_nullable
AS extensions.citext;
CREATE DOMAIN common.citext_not_null
AS extensions.citext NOT NULL;
CREATE DOMAIN common.smallint_ge_zero_nullable
AS smallint;
ALTER DOMAIN common.smallint_ge_zero_nullable
ADD CONSTRAINT smallint_ge_zero_nullable_check CHECK (value >= 0);
以及以下功能:
CREATE OR REPLACE FUNCTION common.fun_name(
p_1 common.citext_not_null,
p_2 common.citext_nullable,
p_3 common.citext_nullable,
p_4 common.smallint_ge_zero_nullable)
RETURNS ...
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
...
BEGIN
...
END;
$BODY$;
注意:
我可以通过
调用该函数SELECT fun_name('any', 'any', 'any', 5::smallint_ge_zero_nullable);
甚至
SELECT fun_name('any', 'any', 'any', '5');
但我无法通过以下方式来称呼它:
SELECT fun_name('any', 'any', 'any', 5);
我收到以下错误:
SQL Error [42883]: ERROR: function fun_name(unknown, unknown, unknown, integer) does not exist
Hint: No function matches the given name and argument types. You might need to add explicit type casts.
Position: 8
为什么"基于citext"的参数显示为"未知"?根据文档,第1431页
argtype
函数参数的数据类型(可选择模式限定),如果有的话。参数类型可以是基本类型,复合类型或域类型,或者......
("有趣"" 未知"参数最终被接受并按预期工作," 整数"参数不被接受,行为异常。)
答案 0 :(得分:1)
此行为与int - smallint转换有关,而与域无关。
您可以找到将函数调用与函数关联的规则here。它将在可用时使用隐式转换,并始终将“未知”类型与任何内容匹配。由于您的函数只有一个签名,因此案例1(显式转换)和2(所有未知)将与您的函数匹配。
没有自动向下转换,所以整数 - > smallInt不会隐含地发生。让我们考虑一个具有两个签名f(input as int)
和f(input as smallint)
的函数。如果要进行向下转换,在调用f(5)
时应该使用哪一个?此邮件列表thread将提供更多详细信息。
所以解决方案要么是
- 进行明确的铸造(案例1)
- 或者有一个函数包装器,其中包含为您执行转换的泛型类型(整数)(并处理错误..)
- 或者使用具有正确类型的表列的输出调用该函数。