PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak uciec przed znakiem zapytania (?) za pomocą Spring JpaRepository?

W przypadku ucieczki ? nie jest możliwe, możesz utworzyć zduplikowany operator o innej nazwie.

Nowy operator

Składnia tworzenia operatorów w Postgresie:

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 ]
)

W przypadku ?| używane w jsonb to będzie:

CREATE OPERATOR ^|(
  PROCEDURE = jsonb_exists_any,
  LEFTARG = jsonb,
  RIGHTARG = _text,
  RESTRICT = contsel,
  JOIN = contjoinsel);

Użyłem ^| jako przykład alternatywna nazwa. Może to być dowolna sekwencja z tej listy:+ - * / < > = ~ ! @ # % ^ & | ?`.

Aktualną definicję operatora, który Cię interesuje, możesz znaleźć w tabeli pg_catalog.pg_operator.

SELECT oid, *
  FROM pg_catalog.pg_operator
 WHERE oprname = '?|'
   AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');

Możesz także użyć narzędzia GUI, takiego jak pgAdmin i przeglądać pg_catalog aby przygotować definicję SQL do ponownego użycia.

Włączanie indeksu

Jeśli chcesz użyć indeksu dla tego „nowego” operatora, będziesz musiał utworzyć nową klasę operatora i opcjonalnie rodzinę. W naszym przypadku potrzebujemy obu, ponieważ nie możemy dodać go do istniejącej rodziny, ponieważ domyślny operator już zajmuje miejsce na strategię.

Podobnie jak w przypadku operatorów, zaleca się używanie narzędzia GUI, takiego jak pgAdmin, do przeglądania klas operatorów i po prostu ich kopiowania i wklejania.

Najpierw bierzemy OID operatora, którego zduplikowaliśmy:

SELECT oid, *
  FROM pg_catalog.pg_operator
 WHERE oprname = '?|'
   AND oprleft = (SELECT oid FROM pg_type WHERE typname = 'jsonb');

To samo dla rodziny operatorów (zamiast tego otrzymamy ją z tabeli klas operatorów), szukamy klasy gin, ponieważ jest to ta, która obsługuje ?| . opcdefault jest używana, ponieważ istnieje opcjonalna klasa jsonb_path_ops który nie obsługuje tego operatora:

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

Następnie otrzymujemy strategię używaną przez operatora, którego zduplikowaliśmy:

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

Następnie funkcje używane przez klasę:

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

To prowadzi nas do tej klasy operatorów. Stworzy rodzinę operatorów, jeśli jeszcze nie istnieje.

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);

Teraz wystarczy utworzyć indeks przy użyciu utworzonej nazwy operatora, na przykład:

CREATE INDEX ON jsonb_table USING gin(jsonb_column jsonb_ops_custom)

Powinieneś być w stanie korzystać z indeksu:

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. Zwiększanie wydajności PostgreSQL dzięki HAProxy

  2. Przegląd kompilacji Just-in-Time (JIT) dla PostgreSQL

  3. Jak ustawić wartość pola zmiennej złożonej za pomocą dynamicznego SQL?

  4. jsonb vs jsonb[] dla wielu adresów dla klienta

  5. Nowe funkcje zgodności z Oracle w PostgresPlus Advanced Server 9.3Beta