これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。
pgroonga_escape
関数1.1.9で追加。
pgroonga_escape
関数は渡された値をスクリプト構文のリテラルに変換します。このリテラルはスクリプト構文内で安全に使えます。スクリプト構文はJSONBの@@
演算子などで使っています。
pgroonga_escape
関数はpgroonga_command
関数経由でのGroongaコマンドインジェクションが発生することを防ぐために使えます。Groongaコマンドインジェクションを防ぐことについてはpgroonga_command_escape_value
関数とpgroonga_query_escape
関数も見てください。
この関数の構文は次の通りです。
text pgroonga_escape(value)
value
の型は次のどれかです。
text
boolean
int2
int4
int8
float4
float8
timestamp
timestamptz
value
はスクリプト構文で使うリテラルです。
pgroonga_query_escape
はtext
型の値を返します。この値はスクリプト構文中でリテラルとして安全に使えます。
もしvalue
がtext
型の値の場合は、次のようにエスケープ対象の文字を0個以上指定できます。
text pgroonga_escape(value, special_characters)
special_characters
はtext
型の値です。この値にエスケープ対象の文字をすべて含めます。「(」と「)」をエスケープしたい場合は'()'
と指定します。
サンプルスキーマとデータは次の通りです。
CREATE TABLE logs (
message jsonb
);
CREATE INDEX pgroonga_logs_index
ON logs
USING pgroonga (message);
INSERT INTO logs VALUES ('{"body": "\"index.html\" not found"}');
"index.html" not found
を検索したい場合は、次のように"
を\"
とエスケープします。
SELECT * FROM logs
WHERE message @@ 'string @ "\"index.html\" not found"';
-- message
-- --------------------------------------
-- {"body": "\"index.html\" not found"}
-- (1 row)
この用途にpgroonga_escape
関数を使えます。
SELECT * FROM logs
WHERE message @@ ('string @ ' || pgroonga_escape('"index.html" not found'));
-- message
-- --------------------------------------
-- {"body": "\"index.html\" not found"}
-- (1 row)
pgroonga_escape
関数はpgroonga_command
関数と組み合わせたときも便利です。
SELECT jsonb_pretty(
pgroonga_command('select',
ARRAY[
'table', pgroonga_table_name('pgroonga_logs_index'),
'output_columns', 'message.string',
'filter', 'message.string @ ' || pgroonga_escape('"index.html" not found')
])::jsonb
);
-- jsonb_pretty
-- ------------------------------------------------
-- [ +
-- [ +
-- 0, +
-- 1480435379.074671, +
-- 0.0004425048828125 +
-- ], +
-- [ +
-- [ +
-- [ +
-- 1 +
-- ], +
-- [ +
-- [ +
-- "message.string", +
-- "LongText" +
-- ] +
-- ], +
-- [ +
-- [ +
-- "", +
-- "\"index.html\" not found"+
-- ] +
-- ] +
-- ] +
-- ] +
-- ]
-- (1 row)
数値のようにtext
型以外の値にもpgroonga_escape
関数を使えます。
SELECT jsonb_pretty(
pgroonga_command('select',
ARRAY[
'table', pgroonga_table_name('pgroonga_logs_index'),
'output_columns', '_id',
'filter', '_id == ' || pgroonga_escape(1)
])::jsonb
);
-- jsonb_pretty
-- --------------------------------
-- [ +
-- [ +
-- 0, +
-- 1480435504.153011, +
-- 0.00009799003601074219+
-- ], +
-- [ +
-- [ +
-- [ +
-- 1 +
-- ], +
-- [ +
-- [ +
-- "_id", +
-- "UInt32" +
-- ] +
-- ], +
-- [ +
-- 1 +
-- ] +
-- ] +
-- ] +
-- ]
-- (1 row)