PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да избягвате знака за въпросителен знак (?) с Spring JpaRepository

В случай на екраниране на ? не е възможно, можете да създадете дублиран оператор с различно име.

Нов оператор

Синтаксис за създаване на оператори в 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');

Можете също да използвате GUI инструмент като pgAdmin и да преглеждате pg_catalog за да подготвите SQL дефиницията за повторна употреба.

Активиране на индекс

Ако искате да използвате индекс за този "нов" оператор, ще трябва да създадете нов клас на оператора и по избор семейство. В нашия случай имаме нужда и от двете, тъй като не можем да го добавим към съществуващото семейство, тъй като операторът по подразбиране вече заема слот за стратегия.

Точно както при операторите, препоръчително е да използвате GUI инструмент като pgAdmin, за да преглеждате операторски класове и просто да го копирате и поставите.

Първо вземаме 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)

И трябва да можете да използвате index:

SET enable_seqscan = off;
EXPLAIN ANALYZE
SELECT * FROM jsonb_table WHERE jsonb_column ^| array['b', 'c'];


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Не може да се свърже с heroku postgresql база данни от локално приложение на възел със sequelize

  2. Осмисляне на размерите на редовете в Postgres

  3. Интегриране на PostgreSQL със системи за удостоверяване

  4. Ограничения за имена на колони в таблицата Postgres?

  5. Използване на текущото време в UTC като стойност по подразбиране в PostgreSQL