我正在尝试修复遗留数据库的问题。 quote_literal函数不适用于8.4安装postgres的特定数据库。
以下是我在新测试数据库中的结果:
select quote_literal(42);
quote_literal
---------------
'42'
(1 row)
现在在目标db上也是如此
select quote_literal(42);
ERROR: function quote_literal(integer) is not unique
LINE 1: select quote_literal(42);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
AIUI,quote_lite(anyvalue)函数应该处理整数值,这似乎是第一次测试所支持的。
所以我认为必须在此数据库中覆盖quote_literal函数,但似乎并非如此。我可以使用特定的quote_lite(整数)函数覆盖它,但我不明白为什么我应该这样做。
问题是在这个特定数据库中导致此功能失败的原因是什么,而不影响新数据库?
答案 0 :(得分:4)
另一种可能性:有人在文本中添加了隐式强制转换。 This was a common workaround for an intentional BC break in 8.3。请参阅release notes for 8.3, E.57.2. Migration to Version 8.3
演示:
regress=# \df quote_literal
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+---------------+------------------+---------------------+--------
pg_catalog | quote_literal | text | anyelement | normal
pg_catalog | quote_literal | text | text | normal
(2 rows)
regress=# CREATE FUNCTION pg_catalog.text(integer) RETURNS text STRICT IMMUTABLE LANGUAGE SQL AS 'SELECT textin(int4out($1));';
CREATE FUNCTION
regress=# CREATE CAST (integer AS text) WITH FUNCTION pg_catalog.text(integer) AS IMPLICIT;
CREATE CAST
regress=# SELECT quote_literal(42);
ERROR: function quote_literal(integer) is not unique
LINE 1: SELECT quote_literal(42);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
regress=#
这将解决它,但可能会破坏仍然依赖于演员的其他代码:
regress=# DROP CAST (integer AS text);
DROP CAST
regress=# SELECT quote_literal(42);
quote_literal
---------------
'42'
(1 row)
答案 1 :(得分:1)
有人可能已经定义了另一个单参数quote_literal
函数,其参数类型与integer
的赋值兼容,如bigint
。
在psql
中,连接并运行:
\df quote_literal
你会看到多个条目,如下所示:
regress=> \df quote_literal
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+---------------+------------------+---------------------+--------
pg_catalog | quote_literal | text | anyelement | normal
pg_catalog | quote_literal | text | text | normal
public | quote_literal | text | bigint | normal
(3 rows)
你只需要pg_catalog
中的前两个。但是,我不能建议你只是:
DROP FUNCTION public.quote_literal(bigint);
...因为你可能有代码期望它存在。是时候去挖掘,看看它在哪里使用。玩得开心。
演示显示这可能是问题所在:
regress=> SELECT quote_literal(42);
quote_literal
---------------
'42'
(1 row)
regress=> CREATE OR REPLACE FUNCTION quote_literal(bigint) RETURNS text AS 'SELECT ''borkborkbork''::text;' LANGUAGE sql;
CREATE FUNCTION
regress=> SELECT quote_literal(42);
ERROR: function quote_literal(integer) is not unique
LINE 1: SELECT quote_literal(42);
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
regress=>