バージョンごとのドキュメント一覧

43.3. 組み込み関数 #

<title>Built-in Functions</title>

43.3.1. PL/Perlからのデータベースアクセス #

<title>Database Access from PL/Perl</title>

Access to the database itself from your Perl function can be done via the following functions: Perl関数からデータベースそのものにアクセスするには以下の関数で行います。

spi_exec_query(query [, limit])

<function>spi_exec_query</function> executes an SQL command and returns the entire row set as a reference to an array of hash references. If <replaceable>limit</replaceable> is specified and is greater than zero, then <function>spi_exec_query</function> retrieves at most <replaceable>limit</replaceable> rows, much as if the query included a <literal>LIMIT</literal> clause. Omitting <replaceable>limit</replaceable> or specifying it as zero results in no row limit. spi_exec_queryはSQLコマンドを実行し、行セット全体をハッシュへの参照を要素とする配列への参照として返します。 limitが指定され、それがゼロより大きい場合、spi_exec_queryは、問い合わせにLIMIT句が含まれている場合と同様に、最大limit行を取得します。 limitを省略するか、ゼロを指定すると、行の制限はなくなります。

<emphasis>You should only use this command when you know that the result set will be relatively small.</emphasis> Here is an example of a query (<command>SELECT</command> command) with the optional maximum number of rows: 結果セットが相対的に小規模であることが分かっている場合にのみ、このコマンドを使用してください。 以下に最大行数オプションを持った問い合わせ(SELECTコマンド)の例を示します。

$rv = spi_exec_query('SELECT * FROM my_table', 5);

This returns up to 5 rows from the table <literal>my_table</literal>. If <literal>my_table</literal> has a column <literal>my_column</literal>, you can get that value from row <literal>$i</literal> of the result like this: これはmy_tableテーブルから5行までを返します。 my_tablemy_column列がある場合、結果の第$i行の列値を以下のように取り出すことができます。

$foo = $rv->{rows}[$i]->{my_column};

The total number of rows returned from a <command>SELECT</command> query can be accessed like this: SELECT問い合わせから返される行の総数は以下のようにアクセスできます。

$nrows = $rv->{processed}

Here is an example using a different command type: 以下は他の種類のコマンドを使用する例です。

$query = "INSERT INTO my_table VALUES (1, 'test')";
$rv = spi_exec_query($query);

You can then access the command status (e.g., <literal>SPI_OK_INSERT</literal>) like this: この後、以下のようにコマンドステータス(例えばSPI_OK_INSERT)にアクセスすることができます。

$res = $rv->{status};

To get the number of rows affected, do: 影響を受けた行数を取り出すには以下を行います。

$nrows = $rv->{processed};

Here is a complete example: 以下に複雑な例を示します。

CREATE TABLE test (
    i int,
    v varchar
);

INSERT INTO test (i, v) VALUES (1, 'first line');
INSERT INTO test (i, v) VALUES (2, 'second line');
INSERT INTO test (i, v) VALUES (3, 'third line');
INSERT INTO test (i, v) VALUES (4, 'immortal');

CREATE OR REPLACE FUNCTION test_munge() RETURNS SETOF test AS $$
    my $rv = spi_exec_query('select i, v from test;');
    my $status = $rv->{status};
    my $nrows = $rv->{processed};
    foreach my $rn (0 .. $nrows - 1) {
        my $row = $rv->{rows}[$rn];
        $row->{i} += 200 if defined($row->{i});
        $row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
        return_next($row);
    }
    return undef;
$$ LANGUAGE plperl;

SELECT * FROM test_munge();

spi_query(command)
spi_fetchrow(cursor)
spi_cursor_close(cursor)

<literal>spi_query</literal> and <literal>spi_fetchrow</literal> work together as a pair for row sets which might be large, or for cases where you wish to return rows as they arrive. <literal>spi_fetchrow</literal> works <emphasis>only</emphasis> with <literal>spi_query</literal>. The following example illustrates how you use them together: spi_queryおよびspi_fetchrowは、大規模になる可能性がある行セット用、または、行を順番通りに返したい場合向けに組み合わせて動作します。 spi_fetchrowspi_queryと一緒でなければ動作しません。 組み合わせて使用する方法について、以下の例で示します。

CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);

CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
    use Digest::MD5 qw(md5_hex);
    my $file = '/usr/share/dict/words';
    my $t = localtime;
    elog(NOTICE, "opening file $file at $t" );
    open my $fh, '<', $file # ooh, it's a file access!
        or elog(ERROR, "cannot open $file for reading: $!");
    my @words = <$fh>;
    close $fh;
    $t = localtime;
    elog(NOTICE, "closed file $file at $t");
    chomp(@words);
    my $row;
    my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
    while (defined ($row = spi_fetchrow($sth))) {
        return_next({
            the_num => $row->{a},
            the_text => md5_hex($words[rand @words])
        });
    }
    return;
$$ LANGUAGE plperlu;

SELECT * from lotsa_md5(500);

Normally, <function>spi_fetchrow</function> should be repeated until it returns <literal>undef</literal>, indicating that there are no more rows to read. The cursor returned by <literal>spi_query</literal> is automatically freed when <function>spi_fetchrow</function> returns <literal>undef</literal>. If you do not wish to read all the rows, instead call <function>spi_cursor_close</function> to free the cursor. Failure to do so will result in memory leaks. 通常spi_fetchrowは、読み取る行がなくなったことを示すundefが返されるまで繰り返されるはずです。 spi_fetchrowundefを返すとspi_queryで返されるカーソルは自動的に解放されます。 すべての行を読み取りたくない場合は代わりにspi_cursor_closeを呼び出してカーソルを解放してください。 これに失敗するとメモリリークという結果になります。

spi_prepare(command, argument types)
spi_query_prepared(plan, arguments)
spi_exec_prepared(plan [, attributes], arguments)
spi_freeplan(plan)

<literal>spi_prepare</literal>, <literal>spi_query_prepared</literal>, <literal>spi_exec_prepared</literal>, and <literal>spi_freeplan</literal> implement the same functionality but for prepared queries. <literal>spi_prepare</literal> accepts a query string with numbered argument placeholders ($1, $2, etc.) and a string list of argument types: spi_preparespi_query_preparedspi_exec_preparedspi_freeplanは、プリペアド問い合わせ用に同様の機能を実装します。 spi_prepareは番号付き引数プレースホルダ($1、$2など)を持つ問い合わせ文字列と引数の型を表す文字列リストを受け付けます。

$plan = spi_prepare('SELECT * FROM test WHERE id > $1 AND name = $2',
                                                     'INTEGER', 'TEXT');

Once a query plan is prepared by a call to <literal>spi_prepare</literal>, the plan can be used instead of the string query, either in <literal>spi_exec_prepared</literal>, where the result is the same as returned by <literal>spi_exec_query</literal>, or in <literal>spi_query_prepared</literal> which returns a cursor exactly as <literal>spi_query</literal> does, which can be later passed to <literal>spi_fetchrow</literal>. The optional second parameter to <literal>spi_exec_prepared</literal> is a hash reference of attributes; the only attribute currently supported is <literal>limit</literal>, which sets the maximum number of rows returned from the query. Omitting <literal>limit</literal> or specifying it as zero results in no row limit. spi_prepareを呼び出すことで問い合わせ計画が準備されると、spi_exec_queryにより返されるものと同様の結果となるspi_exec_preparedspi_queryとまったく同じカーソルが返されるspi_query_prepared(このカーソルは後でspi_fetchrowに渡すことができます)の中で、その計画を問い合わせ文字列の代わりに使用することができます。 spi_exec_preparedの省略可能な第二パラメータは属性のハッシュ参照です。 現在サポートされる唯一の属性は、問い合わせで返される最大行数を設定するlimitです。 limitを省略するか、ゼロを指定すると、行制限はなくなります。

The advantage of prepared queries is that is it possible to use one prepared plan for more than one query execution. After the plan is not needed anymore, it can be freed with <literal>spi_freeplan</literal>: プリペアド問い合わせの利点は、1つの準備された計画を複数回使用して問い合わせを実行することができるという点です。 計画が不要になった後、spi_freeplanを使用して、計画を解放することができます。

CREATE OR REPLACE FUNCTION init() RETURNS VOID AS $$
        $_SHARED{my_plan} = spi_prepare('SELECT (now() + $1)::date AS now',
                                        'INTERVAL');
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION add_time( INTERVAL ) RETURNS TEXT AS $$
        return spi_exec_prepared(
                $_SHARED{my_plan},
                $_[0]
        )->{rows}->[0]->{now};
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION done() RETURNS VOID AS $$
        spi_freeplan( $_SHARED{my_plan});
        undef $_SHARED{my_plan};
$$ LANGUAGE plperl;

SELECT init();
SELECT add_time('1 day'), add_time('2 days'), add_time('3 days');
SELECT done();

  add_time  |  add_time  |  add_time
------------+------------+------------
 2005-12-10 | 2005-12-11 | 2005-12-12

Note that the parameter subscript in <literal>spi_prepare</literal> is defined via $1, $2, $3, etc., so avoid declaring query strings in double quotes that might easily lead to hard-to-catch bugs. spi_prepare内のパラメータ添字が$1、$2、$3などを介して定義されることに注意してください。 そのため、検出困難な不具合が簡単に発生することになる二重引用符内での問い合わせ文字列宣言はやめてください。

Another example illustrates usage of an optional parameter in <literal>spi_exec_prepared</literal>: 他の例は、spi_exec_preparedにおける省略可能なパラメータの使用について示しています。

CREATE TABLE hosts AS SELECT id, ('192.168.1.'||id)::inet AS address
                      FROM generate_series(1,3) AS id;

CREATE OR REPLACE FUNCTION init_hosts_query() RETURNS VOID AS $$
        $_SHARED{plan} = spi_prepare('SELECT * FROM hosts
                                      WHERE address << $1', 'inet');
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION query_hosts(inet) RETURNS SETOF hosts AS $$
        return spi_exec_prepared(
                $_SHARED{plan},
                {limit => 2},
                $_[0]
        )->{rows};
$$ LANGUAGE plperl;

CREATE OR REPLACE FUNCTION release_hosts_query() RETURNS VOID AS $$
        spi_freeplan($_SHARED{plan});
        undef $_SHARED{plan};
$$ LANGUAGE plperl;

SELECT init_hosts_query();
SELECT query_hosts('192.168.1.0/30');
SELECT release_hosts_query();

    query_hosts
-----------------
 (1,192.168.1.1)
 (2,192.168.1.2)
(2 rows)

spi_commit()
spi_rollback()

Commit or roll back the current transaction. This can only be called in a procedure or anonymous code block (<command>DO</command> command) called from the top level. (Note that it is not possible to run the SQL commands <command>COMMIT</command> or <command>ROLLBACK</command> via <function>spi_exec_query</function> or similar. It has to be done using these functions.) After a transaction is ended, a new transaction is automatically started, so there is no separate function for that. 現在のトランザクションをコミットあるいはロールバックします。 これはプロシージャ、あるいはトップレベルから呼ばれた無名コードブロック(DOコマンド)の中からのみ呼び出すことができます。 (SQLコマンドのCOMMITROLLBACKspi_exec_queryなどを通して実行することはできない点に注意してください。前述の関数を使って行う必要があります。) トランザクションが終了した後、新たなトランザクションが自動的に開始されますので、開始するための別途の関数はありません。

Here is an example: 以下に例を示します。

CREATE PROCEDURE transaction_test1()
LANGUAGE plperl
AS $$
foreach my $i (0..9) {
    spi_exec_query("INSERT INTO test1 (a) VALUES ($i)");
    if ($i % 2 == 0) {
        spi_commit();
    } else {
        spi_rollback();
    }
}
$$;

CALL transaction_test1();

43.3.2. PL/Perlのユーティリティ関数 #

<title>Utility Functions in PL/Perl</title>
elog(level, msg)

Emit a log or error message. Possible levels are <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>, <literal>NOTICE</literal>, <literal>WARNING</literal>, and <literal>ERROR</literal>. <literal>ERROR</literal> raises an error condition; if this is not trapped by the surrounding Perl code, the error propagates out to the calling query, causing the current transaction or subtransaction to be aborted. This is effectively the same as the Perl <literal>die</literal> command. The other levels only generate messages of different priority levels. Whether messages of a particular priority are reported to the client, written to the server log, or both is controlled by the <xref linkend="guc-log-min-messages"/> and <xref linkend="guc-client-min-messages"/> configuration variables. See <xref linkend="runtime-config"/> for more information. ログまたはエラーメッセージを発行します。 使用できるレベルは、DEBUGLOGINFONOTICEWARNING、およびERRORです。 ERRORはエラー状態を発生します。 その上位のPerlコードでこのエラーを捕捉しない場合、エラーは問い合わせの呼び出し元まで伝播し、その結果、現在のトランザクションもしくはサブトランザクションはアボートします。 これは実質Perlのdieコマンドと同じです。 他のレベルは、異なる重要度のメッセージを生成するだけです。 log_min_messagesclient_min_messages設定パラメータは、特定の重要度のメッセージをクライアントに報告するか、サーバのログに書き出すか、あるいはその両方かを制御します。 詳細は第19章を参照してください。

quote_literal(string)

Return the given string suitably quoted to be used as a string literal in an SQL statement string. Embedded single-quotes and backslashes are properly doubled. Note that <function>quote_literal</function> returns undef on undef input; if the argument might be undef, <function>quote_nullable</function> is often more suitable. 与えられた文字列を、SQL文の文字列内で文字列リテラルとして使用するために適切に引用符付けして返します。 埋め込まれた単一引用符およびバックスラッシュは適切に二重化されます。 quote_literalは入力がundefならばundefを返すことに注意してください。 引数がundefの可能性があるのであれば、quote_nullableの方が適しています。

quote_nullable(string)

Return the given string suitably quoted to be used as a string literal in an SQL statement string; or, if the argument is undef, return the unquoted string "NULL". Embedded single-quotes and backslashes are properly doubled. 与えられた文字列を、SQL文の文字列内で文字列リテラルとして使用するために適切に引用符付けして返します。 引数がundefの場合引用符付けされない文字列"NULL"を返します。 埋め込まれた単一引用符およびバックスラッシュは適切に二重化されます。

quote_ident(string)

Return the given string suitably quoted to be used as an identifier in an SQL statement string. Quotes are added only if necessary (i.e., if the string contains non-identifier characters or would be case-folded). Embedded quotes are properly doubled. 与えられた文字列を、SQL文の文字列内で識別子として使用するために適切に引用符付けして返します。 必要な場合(つまり文字列に識別子用ではない文字列が含まれる、または、大文字小文字を保持する場合)のみ引用符が付けられます。 埋め込まれた引用符は適切に二重化されます。

decode_bytea(string)

Return the unescaped binary data represented by the contents of the given string, which should be <type>bytea</type> encoded. 与えられた文字列の内容を表す、エスケープのないバイナリデータを返します。 これはbytea符号化でなければなりません。

encode_bytea(string)

Return the <type>bytea</type> encoded form of the binary data contents of the given string. 与えられた文字列の内容をバイナリデータ形式で符号化したbyteaを返します。

encode_array_literal(array)
encode_array_literal(array, delimiter)

Returns the contents of the referenced array as a string in array literal format (see <xref linkend="arrays-input"/>). Returns the argument value unaltered if it's not a reference to an array. The delimiter used between elements of the array literal defaults to "<literal>, </literal>" if a delimiter is not specified or is undef. 参照先の配列の内容を、配列リテラル書式で表した文字列として返します(8.15.2参照)。 配列への参照でない場合は引数の値は変更されません。 配列リテラルの要素間の区切り文字は指定がない、または、undefの場合、デフォルトで", "です。

encode_typed_literal(value, typename)

Converts a Perl variable to the value of the data type passed as a second argument and returns a string representation of this value. Correctly handles nested arrays and values of composite types. Perl変数を2番目の引数として渡されたデータ型の値に変換し、その値の文字列表現を返します。 入れ子状の配列や複合型の値を正しく扱います。

encode_array_constructor(array)

Returns the contents of the referenced array as a string in array constructor format (see <xref linkend="sql-syntax-array-constructors"/>). Individual values are quoted using <function>quote_nullable</function>. Returns the argument value, quoted using <function>quote_nullable</function>, if it's not a reference to an array. 参照先の配列の内容を配列生成書式で表した文字列として返します(4.2.12参照)。 個々の値はquote_nullableを使用して引用符付けされます。 配列への参照でない場合は、quote_nullableを使用して引用符付けされた引数の値が返されます。

looks_like_number(string)

Returns a true value if the content of the given string looks like a number, according to Perl, returns false otherwise. Returns undef if the argument is undef. Leading and trailing space is ignored. <literal>Inf</literal> and <literal>Infinity</literal> are regarded as numbers. 与えられた文字列の内容がPerlの流儀で数値でありそうな場合に真値を、さもなくば偽を返します。 引数がundefならばundefを返します。 先頭の空白、末尾の空白は無視されます。 InfおよびInfinityは数値とみなします。

is_array_ref(argument)

Returns a true value if the given argument may be treated as an array reference, that is, if ref of the argument is <literal>ARRAY</literal> or <literal>PostgreSQL::InServer::ARRAY</literal>. Returns false otherwise. 指定された引数が配列参照として扱うことができる場合、つまり、引数のrefがARRAYまたはPostgreSQL::InServer::ARRAYの場合、真を返します。 さもなくば偽を返します。