Rozwiązanie
Najprawdopodobniej rozwiązanie jest zakwalifikowanie operatora do schematu:
SELECT *
FROM test
WHERE tagged OPERATOR(example@sqldat.com>) '{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ę?