3

postgres 9.1では、インデックス名、テーブル名、および可変数の列を受け取り、インデックスを作成してから、他のことを行う関数を作成したいと思います。

私の現在のアプローチは、plpgsqlを使用して、実行する動的コマンドを作成することです。quote_identただし、すべての識別子を保護するために使用しようとすると、つまずきます。これまでのコード:

CREATE OR REPLACE FUNCTION my_create_index(indexname text, tablename text, VARIADIC arr text[]) RETURNS void AS $$
  DECLARE
    command_string text;
  BEGIN
    command_string := 'CREATE INDEX ' || quote_ident(indexname) || ' ON ' ||
         quote_ident(tablename) || ' (' ||
         format(repeat('%I ', array_length($3, 1)), VARIADIC $3) ||
         ')';

    -- display the string
    RAISE NOTICE '%', command_string;

    -- execute the string
    EXECUTE command_string;

    -- (do other stuff)
  END;
$$ LANGUAGE plpgsql;

1つの列名を渡すとコードは成功したように見えますが、2つ以上あると、次のエラーが発生します。

ERROR:  too few arguments for format

私は何が間違っているのですか?(おそらく、formatまたは私の使用で何かVARIADIC。)

ありがとうございました!

4

2 に答える 2

4

format通常、との両方を使用することはありませんquote_identformat自分自身を引用する識別子を実行するのに十分賢いです。quote_ident不要な連結や他の場所での呼び出しを使用しながら、自分自身が表現の一部であることを示します。

formatただし、配列引数を使用して呼び出す場合と同じ問題が発生しておりVARIADIC、バグが見つかったと思われます。

何が起こっているのかがわかるまでの回避策は次のとおりです。

command_string := format('CREATE INDEX %I ON %I (%s)', 
    indexname, tablename, (
      SELECT string_agg(quote_ident(x), ', ') 
      FROM unnest($3) x
    )
);

元のコードでは、である必要があることに注意して'%I 'ください'%I, '

はい、バグが確認されました。以前に報告されていますが、チェックされていないようです。同じバグがとに存在しconcatますconcat_wsVARIADICこれらの関数は、引数フラグのチェックに失敗します。

観察:

regress=> SELECT format('%I', VARIADIC ARRAY['b','c','d']);
  format   
-----------
 "{b,c,d}"
(1 row)

regress=> SELECT format('%I', 'b','c','d');
 format 
--------
 b
(1 row)

regress=> SELECT format('%I, %I, %I', VARIADIC ARRAY['b','c','d']);
ERROR:  too few arguments for format

私が考えることができる唯一の回避策は、それらを回避するか(上記のように)EXECUTE、関数呼び出しを動的に構築するために使用することです。その場合はformat完全に冗長なので、上記のサブクエリを。で使用しますunnest

PostgreSQLメーリングリストでこれを追いかけようとしますが、来週はめちゃくちゃ忙しくなるので、私を突くか、pgsqlに投稿してください-この質問へのリンクが表示されない場合は、バグを投稿してください。次の週の半ばまでのフォローアップ。

于 2012-11-23T05:12:36.080 に答える
3

現在、フォーマット関数でVARIADICパラメータを使用することはできません:(。これは既知のバグであり、PostgreSQL 9.3で修正される予定です(願っています)。パッチhttp://archives.postgresql.org/message-id/を使用してみてください。 CAFj8pRDZc7wG1ewnmqUWkjDsB78Pu = Oj_WZ8_CS7qJUCKRUNmQ@mail.gmail.com

于 2012-11-23T10:06:20.403 に答える