これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。

pgroonga_command_escape_value関数

1.1.9で追加。

概要

pgroonga_command_escape_value関数はGroongaコマンドのフォーマットのうち「値」部分の特別な文字をエスケープします。

以下はGroongaコマンドのフォーマット例です。

select --table Logs --match_columns message --query Error

selectはコマンド名です。--XXX YYYは引数の名前と値です。XXXは引数名です。YYYは引数値です。たとえば、--table Logsではtableが引数名でLogsが引数値です。

pgroonga_command_escape_value関数はpgroonga_command関数経由でのGroongaコマンドインジェクションを防ぐために使えます。Groongaコマンドインジェクションを防ぐことについてはpgroonga_query_escape関数pgroonga_escape関数も見てください。

pgroonga_command(command, ARRAY[arguments...])スタイルを使っている場合はこの関数を使う必要はありません。なぜなら、このスタイルではこの関数がやることと同じことを内部でやってくれるからです。

構文

この関数の構文は次の通りです。

text pgroonga_command_escape_value(value)

valuetext型の値です。Groongaコマンドのフォーマットの「値」部分を指定します。

pgroonga_command_escape_valuetext型の値を返します。この値中の特別な意味を持つ文字はすべてエスケープされています。

使い方

サンプルスキーマとデータは次の通りです。

CREATE TABLE memos (
  content text
);

CREATE INDEX pgroonga_memos_index
          ON memos
       USING pgroonga (content);

INSERT INTO memos VALUES ('PGroonga (PostgreSQL+Groonga) is great!');

クエリーが「(PostgreSQL」の場合はエラーが発生します。なぜなら「(」が特別な文字だからです。

SELECT jsonb_pretty(
  pgroonga_command('select ' ||
                   '--table ' || pgroonga_table_name('pgroonga_memos_index') || ' ' ||
                   '--match_columns content ' ||
                   '--query (PostgreSQL')::jsonb
);
--                      jsonb_pretty                      
-- -------------------------------------------------------
--  [                                                    +
--      [                                                +
--          -22,                                         +
--          1480483949.578879,                           +
--          0.0002233982086181641,                       +
--          "[select][table] invalid name: <PostgreSQL>",+
--          [                                            +
--              [                                        +
--                  "grn_select",                        +
--                  "proc_select.c",                     +
--                  2973                                 +
--              ]                                        +
--          ]                                            +
--      ]                                                +
--  ]
-- (1 row)

pgroonga_command_escape_value関数をpgroonga_query_escape関数と一緒に使うとこのケースを防げます。

SELECT jsonb_pretty(
  pgroonga_command('select ' ||
                   '--table ' || pgroonga_table_name('pgroonga_memos_index') || ' ' ||
                   '--match_columns content ' ||
                   '--query ' || pgroonga_command_escape_value(pgroonga_query_escape('(PostgreSQL')))::jsonb
);
--                         jsonb_pretty                        
-- ------------------------------------------------------------
--  [                                                         +
--      [                                                     +
--          0,                                                +
--          1480432832.061276,                                +
--          0.0252687931060791                                +
--      ],                                                    +
--      [                                                     +
--          [                                                 +
--              [                                             +
--                  1                                         +
--              ],                                            +
--              [                                             +
--                  [                                         +
--                      "_id",                                +
--                      "UInt32"                              +
--                  ],                                        +
--                  [                                         +
--                      "content",                            +
--                      "LongText"                            +
--                  ],                                        +
--                  [                                         +
--                      "ctid",                               +
--                      "UInt64"                              +
--                  ]                                         +
--              ],                                            +
--              [                                             +
--                  1,                                        +
--                  "PGroonga (PostgreSQL+Groonga) is great!",+
--                  1                                         +
--              ]                                             +
--          ]                                                 +
--      ]                                                     +
--  ]
-- (1 row)

コマンドの引数を配列で指定するスタイルでpgroonga_command関数使ってもこのケースを防ぐことができます。

SELECT jsonb_pretty(
  pgroonga_command('select',
                   ARRAY[
                     'table', pgroonga_table_name('pgroonga_memos_index'),
                     'match_columns', 'content',
                     'query', pgroonga_query_escape('(PostgreSQL')
                   ])::jsonb
);
--                         jsonb_pretty                        
-- ------------------------------------------------------------
--  [                                                         +
--      [                                                     +
--          0,                                                +
--          1480433038.482539,                                +
--          0.0001201629638671875                             +
--      ],                                                    +
--      [                                                     +
--          [                                                 +
--              [                                             +
--                  1                                         +
--              ],                                            +
--              [                                             +
--                  [                                         +
--                      "_id",                                +
--                      "UInt32"                              +
--                  ],                                        +
--                  [                                         +
--                      "content",                            +
--                      "LongText"                            +
--                  ],                                        +
--                  [                                         +
--                      "ctid",                               +
--                      "UInt64"                              +
--                  ]                                         +
--              ],                                            +
--              [                                             +
--                  1,                                        +
--                  "PGroonga (PostgreSQL+Groonga) is great!",+
--                  1                                         +
--              ]                                             +
--          ]                                                 +
--      ]                                                     +
--  ]
-- (1 row)

参考