Dalam kasus melarikan diri ?
tidak mungkin, Anda dapat membuat duplikat operator dengan nama yang berbeda.
Operator baru
Sintaks untuk membuat operator di 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 ]
)
Dalam kasus ?|
digunakan di jsonb
itu akan menjadi:
CREATE OPERATOR ^|(
PROCEDURE = jsonb_exists_any,
LEFTARG = jsonb,
RIGHTARG = _text,
RESTRICT = contsel,
JOIN = contjoinsel);
Saya telah menggunakan ^|
sebagai contoh, nama alternatif. Ini dapat berupa urutan apa pun dari daftar ini:+ - * / < > = ~ ! @ # % ^ & |
?`.
Anda dapat menemukan definisi terkini untuk operator yang Anda minati dengan menanyakan tabel pg_catalog.pg_operator.
SELECT oid, *
FROM pg_catalog.pg_operator
WHERE oprname = '?|'
AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
Anda juga dapat menggunakan alat GUI seperti pgAdmin dan menelusuri pg_catalog
untuk menyiapkan definisi SQL untuk digunakan kembali.
Mengaktifkan indeks
Jika Anda ingin menggunakan indeks untuk operator "baru" ini, Anda harus membuat kelas operator baru dan secara opsional keluarga. Dalam kasus kami, kami membutuhkan keduanya, karena kami tidak dapat menambahkannya ke keluarga yang ada, karena operator default sudah mengambil slot strategi.
Sama seperti operator, disarankan untuk menggunakan alat GUI seperti pgAdmin untuk menelusuri kelas operator dan cukup salin &tempel.
Pertama, kita ambil OID dari operator yang kita buat duplikatnya:
SELECT oid, *
FROM pg_catalog.pg_operator
WHERE oprname = '?|'
AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
Hal yang sama untuk keluarga operator (kami akan mendapatkannya dari tabel kelas operator), kami mencari kelas gin karena ini adalah yang mendukung ?|
. opcdefault
digunakan, karena ada kelas opsional jsonb_path_ops
yang tidak mendukung operator ini:
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
Kemudian kami mendapatkan strategi yang digunakan oleh operator yang kami duplikat:
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
Kemudian fungsi yang digunakan oleh kelas:
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
Ini membawa kita ke kelas operator ini. Ini akan membuat keluarga operator jika belum ada.
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);
Sekarang Anda hanya perlu membuat indeks menggunakan nama operator yang telah dibuat, seperti:
CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)
Dan Anda harus dapat menggunakan indeks:
SET enable_seqscan = off;
EXPLAIN ANALYZE
SELECT * FROM jsonb_table WHERE jsonb_column ^| array['b', 'c'];