Rozwiązanie
Najprawdopodobniej rozwiązanie jest zakwalifikowanie operatora do schematu:
SELECT *
FROM test
WHERE tagged OPERATOR([email protected]>) '{11}'::int2[]
ORDER BY id
LIMIT 100;
Dlaczego?
Jest to problem rozdzielczości operatora (w połączeniu z rozdzielczością typu i kontekstem rzutowania).
W standardowym Postgresie istnieje tylko jeden operator kandydujący anyarray @>anyarray
, właśnie tego chcesz.
Twoja konfiguracja działałaby dobrze, gdybyś nie zainstalował dodatkowego modułu intarray (moje założenie), który zapewnia inny operator dla integer[] @> integer[]
.
Dlatego innym rozwiązaniem byłoby użycie integer[]
zamiast tego i mieć indeks GIN z gin__int_ops
klasa operatora. Lub wypróbuj (domyślnie dla intarray) gist__int_ops
indeks. Oba mogą być szybsze, ale oba nie zezwalają na wartości NULL.
Lub możesz zmienić nazwę intarray
operator @> ujednoznacznić. (Nie zrobiłbym tego. Pojawiają się problemy z aktualizacją i przenoszeniem).
Dla wyrażeń zawierających co najmniej jeden operand typu integer[]
Postgres wie, który operator wybrać:operator intarray. Ale wtedy indeks nie ma zastosowania , ponieważ operator intarray działa tylko na integer
(int4
) nie int2
. A indeksy są ściśle powiązane z operatorami:
- Czy PostgreSQL może indeksować kolumny tablicy?
- Zachowanie PostgreSQL w obecności dwóch różnych typów indeksów w tej samej kolumnie
Ale dla int2[] @> int2[]
, Postgres nie jest w stanie wybrać najlepszego operatora. Oba wydają się równie odpowiednie. Ponieważ domyślny operator znajduje się w pg_catalog
schemat i operator intarray znajdują się w publicznie
schemat (domyślnie - lub gdziekolwiek zainstalowałeś rozszerzenie), możesz pomóc rozwiązać zagadkę, kwalifikując operatora do schematu za pomocą OPERATOR()
zbudować. Powiązane:
- Porównaj tablice pod kątem równości, ignorując kolejność elementów
Otrzymany komunikat o błędzie jest nieco mylący. Ale jeśli przyjrzysz się uważnie, znajdziesz WSKAZÓWKA
dodana linia, która podpowiada (tada!) we właściwym kierunku:
ERROR: operator is not unique: smallint[] @> smallint[] LINE 1: SELECT NULL::int2[] @> NULL::int2[] ^ HINT: Could not choose a best candidate operator. You might need to add explicit type casts.
Możesz zbadać istniejących kandydatów na operatora dla @>
z:
SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM pg_operator o
JOIN pg_namespace n ON n.oid = o.oprnamespace
WHERE oprname = '@>';
Innym alternatywnym rozwiązaniem byłoby tymczasowe(!) ustawienie innej ścieżki_wyszukiwania, aby znaleźć tylko żądany operator. W tej samej transakcji:
SET LOCAL search_path = pg_catalog;
SELECT ...
Ale wtedy musisz zakwalifikować wszystkie tabele w zapytaniu według schematu.
Informacje o kontekście przesyłania:
- Generuj serie dat — używając typu daty jako danych wejściowych
możesz zmień castcontext
z int2
-> int4
. Ale zdecydowanie odradzam. Zbyt wiele możliwych skutków ubocznych:
- Czy istnieje sposób na rzucenie typu danych postgresql 9.3, aby mógł wpływać tylko na jedną stronę?