3

レガシー データベースの問題を修正しようとしています。postgres の 8.4 インストールで特定のデータベースに対して quote_literal 関数が機能しません。

新しいテストデータベースでの私の結果は次のとおりです。

select quote_literal(42);
 quote_literal 
---------------
 '42'
(1 row)

そして今、ターゲットデータベースで同じ

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_literal(anyvalue) 関数は整数値を正常に処理する必要があり、これは最初のテストで支持されているようです。

したがって、このデータベースで quote_literal 関数がオーバーライドされている必要があると考えましたが、そうではないようです。特定の quote_literal(integer) 関数でオーバーライドできますが、なぜそうしなければならないのかわかりません。

問題は、新しいデータベースに影響を与えずに、この特定のデータベースでこの関数の失敗を引き起こしている可能性があるのは何ですか?

4

2 に答える 2

4

別の可能性: 誰かがテキストからデータベースに暗黙のキャストを追加した。これは、8.3 での意図的な BC の中断に対する一般的な回避策でした8.3、E.57.2のリリース ノートを参照してください。バージョン 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)
于 2012-11-07T12:02:41.280 に答える
1

誰かが、のように、quote_literalの割り当てと互換性のある引数タイプを使用して、別の単一引数関数を定義した可能性があります。integerbigint

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)

の最初の2つだけが必要です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=> 
于 2012-11-07T11:40:55.960 に答える