Trong trường hợp thoát ?
là không thể, bạn có thể tạo toán tử trùng lặp với tên khác.
Nhà điều hành mới
Cú pháp để tạo toán tử trong 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 ]
)
Trong trường hợp ?|
được sử dụng trong jsonb
nó sẽ là:
CREATE OPERATOR ^|(
PROCEDURE = jsonb_exists_any,
LEFTARG = jsonb,
RIGHTARG = _text,
RESTRICT = contsel,
JOIN = contjoinsel);
Tôi đã sử dụng ^|
như một ví dụ, tên thay thế. Nó có thể là bất kỳ chuỗi nào từ danh sách này:+ - * / < > = ~ ! @ # % ^ & |
? `.
Bạn có thể tìm định nghĩa hiện tại cho toán tử mà bạn quan tâm bằng cách truy vấn bảng pg_catalog.pg_operator.
SELECT oid, *
FROM pg_catalog.pg_operator
WHERE oprname = '?|'
AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
Bạn cũng có thể sử dụng công cụ GUI như pgAdmin và duyệt pg_catalog
để có được định nghĩa SQL sẵn sàng để sử dụng lại.
Đang kích hoạt chỉ mục
Nếu bạn muốn sử dụng chỉ mục cho toán tử "mới" này, bạn sẽ yêu cầu tạo lớp toán tử mới và họ tùy chọn. Trong trường hợp của chúng tôi, chúng tôi cần cả hai, vì chúng tôi không thể thêm nó vào nhóm hiện có, vì toán tử mặc định đã sử dụng vị trí chiến lược.
Cũng giống như với các toán tử, bạn nên sử dụng công cụ GUI như pgAdmin để duyệt qua các lớp toán tử và chỉ cần sao chép và dán nó.
Đầu tiên, chúng tôi sử dụng OID của toán tử mà chúng tôi đã tạo bản sao của:
SELECT oid, *
FROM pg_catalog.pg_operator
WHERE oprname = '?|'
AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');
Tương tự đối với họ toán tử (thay vào đó chúng ta sẽ lấy nó từ bảng lớp toán tử), chúng ta đang tìm kiếm lớp gin vì đây là lớp hỗ trợ ?|
. opcdefault
được sử dụng, vì có lớp tùy chọn jsonb_path_ops
không hỗ trợ toán tử này:
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
Sau đó, chúng tôi nhận được chiến lược được sử dụng bởi nhà điều hành mà chúng tôi đã sao chép:
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
Sau đó, các hàm được sử dụng bởi lớp:
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
Điều này đưa chúng ta đến lớp toán tử này. Nó sẽ tạo họ toán tử nếu nó chưa tồn tại.
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);
Bây giờ bạn chỉ cần tạo chỉ mục bằng cách sử dụng tên toán tử đã được tạo, giống như:
CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)
Và bạn sẽ có thể sử dụng chỉ mục:
SET enable_seqscan = off;
EXPLAIN ANALYZE
SELECT * FROM jsonb_table WHERE jsonb_column ^| array['b', 'c'];