?
をエスケープする場合 不可能な場合は、別の名前で重複する演算子を作成できます。
新しい演算子
Postgresで演算子を作成するための構文:
CREATE OPERATOR name (
PROCEDURE = function_name
[, LEFTARG = left_type ] [, RIGHTARG = right_type ]
[, COMMUTATOR = com_op ] [, NEGATOR = neg_op ]
[, RESTRICT = res_proc ] [, JOIN = join_proc ]
[, HASHES ] [, MERGES ]
)
?|
の場合 jsonb
で使用されます
CREATE OPERATOR ^|(
PROCEDURE = jsonb_exists_any,
LEFTARG = jsonb,
RIGHTARG = _text,
RESTRICT = contsel,
JOIN = contjoinsel);
^|
を使用しました 例として、別名。このリストの任意のシーケンスにすることができます:+ - * / < > = ~ ! @ # % ^ & |
?`。
pg_catalog.pg_operatorテーブルをクエリすると、関心のある演算子の現在の定義を見つけることができます。
SELECT oid, *
FROM pg_catalog.pg_operator
WHERE oprname = '?|'
AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
pgAdminなどのGUIツールを使用して、pg_catalog
を参照することもできます。 SQL定義を再利用できるようにするため。
インデックスの有効化
この「新しい」演算子にインデックスを使用する場合は、新しい演算子クラスとオプションでファミリを作成する必要があります。この場合、デフォルトのオペレーターがすでに戦略スロットを使用しているため、既存のファミリーに追加できないため、両方が必要です。
オペレーターの場合と同様に、pgAdminなどのGUIツールを使用してオペレータークラスを参照し、コピーして貼り付けることをお勧めします。
まず、複製した演算子のOIDを取得します:
SELECT oid, *
FROM pg_catalog.pg_operator
WHERE oprname = '?|'
AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
オペレーターファミリーについても同じです(代わりにオペレータークラステーブルから取得します)。これは?|
をサポートするものであるため、ginクラスを探しています。 。 opcdefault
オプションのクラスjsonb_path_ops
があるため、が使用されます この演算子をサポートしていません:
SELECT opcfamily
FROM pg_opclass
WHERE opcintype = (SELECT oid FROM pg_type WHERE typname = 'jsonb')
AND opcmethod = (SELECT oid FROM pg_am WHERE amname = 'gin')
AND opcdefault
次に、複製したオペレーターが使用する戦略を取得します:
SELECT amopstrategy,
(SELECT typname FROM pg_type WHERE oid = amoplefttype) AS left_t,
(SELECT typname FROM pg_type WHERE oid = amoprighttype) AS right_t,*
FROM pg_amop
WHERE amopfamily = 4036 --family oid
AND amopopr = 3248 --operator oid
次に、クラスで使用される関数:
SELECT amprocnum, amproc::text, pg_get_function_identity_arguments(amproc::oid) AS args,
(SELECT typname FROM pg_type WHERE oid = amproclefttype) AS left_t,
(SELECT typname FROM pg_type WHERE oid = amprocrighttype) AS right_t,*
FROM pg_amproc
WHERE amprocfamily = 4036 --op family
これにより、この演算子クラスが表示されます。オペレーターファミリーがまだ存在しない場合は作成されます。
CREATE OPERATOR CLASS jsonb_ops_custom
FOR TYPE jsonb USING gin AS
OPERATOR 10 ^|(jsonb, _text),
FUNCTION 1 gin_compare_jsonb(text, text),
FUNCTION 2 gin_extract_jsonb(jsonb, internal, internal),
FUNCTION 3 gin_extract_jsonb_query(jsonb, internal, smallint, internal, internal, internal, internal),
FUNCTION 4 gin_consistent_jsonb(internal, smallint, jsonb, integer, internal, internal, internal, internal),
FUNCTION 6 gin_triconsistent_jsonb(internal, smallint, jsonb, integer, internal, internal, internal);
ここで、作成された演算子名を使用してインデックスを作成する必要があります。たとえば、次のようになります。
CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)
そして、インデックスを使用できるはずです:
SET enable_seqscan = off;
EXPLAIN ANALYZE
SELECT * FROM jsonb_table WHERE jsonb_column ^| array['b', 'c'];