为什么这个postgres函数只在一个特定的数据库上失败?

时间:2012-11-07 10:58:58

标签: postgresql

我正在尝试修复遗留数据库的问题。 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(整数)函数覆盖它,但我不明白为什么我应该这样做。

问题是在这个特定数据库中导致此功能失败的原因是什么,而不影响新数据库?

2 个答案:

答案 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=>