Lösning
Mest troligt är lösningen är att schemakvalificera operatören:
SELECT *
FROM test
WHERE tagged OPERATOR(example@sqldat.com>) '{11}'::int2[]
ORDER BY id
LIMIT 100; Varför?
Det är ett problem med operatörsupplösning (i kombination med typupplösning och castkontext).
I standard Postgres finns det bara en enda kandidatoperator anyarray @> anyarray , det är den du vill ha.
Din installation skulle fungera bra om du inte hade installerat extra modul intarray (mitt antagande), som tillhandahåller en annan operator för integer[] @> integer[] .
Därför skulle en annan lösning vara att använda integer[] istället och ha ett GIN-index med gin__int_ops operatörsklass. Eller prova (standard för intarray) gist__int_ops index. Båda kan vara snabbare, men båda tillåter inte NULL-värden.
Eller så kan du byta namn på intarray operator @> att disambiguera. (Jag skulle inte göra det. Uppgraderings- och portabilitetsproblem uppstår.)
För uttryck som involverar minst en operand av typen integer[] , Postgres vet vilken operatör som ska väljas:intarray-operatorn. Men då är indexet inte tillämpligt , eftersom intarray-operatorn bara fungerar på integer (int4 ) inte int2 . Och index är strikt bundna till operatörer:
- Kan PostgreSQL indexera arraykolumner?
- PostgreSQL-beteende i närvaro av två olika typer av index i samma kolumn
Men för int2[] @> int2[] , Postgres kan inte bestämma den bästa operatören. Båda verkar lika tillämpliga. Eftersom standardoperatorn finns i pg_catalog schemat och intarray-operatorn tillhandahålls i public schema (som standard - eller var du än installerade tillägget), kan du hjälpa till att lösa gåtan genom att schemakvalificera operatören med OPERATOR() konstruera. Relaterat:
- Jämför matriser för likhet, ignorera ordningen på elementen
Felmeddelandet du får är lite missvisande. Men om du tittar noga så finns det ett HINT rad tillagd som antyder (tada!) i rätt riktning:
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.
Du kan undersöka befintliga operatörskandidater för @> med:
SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM pg_operator o
JOIN pg_namespace n ON n.oid = o.oprnamespace
WHERE oprname = '@>';
En annan alternativ lösning skulle vara att tillfälligt(!) ställa in en annan sökväg, så att endast den önskade operatorn hittas. I samma transaktion:
SET LOCAL search_path = pg_catalog;
SELECT ...
Men då måste du schemakvalificera alla tabeller i frågan.
Om medverkande sammanhang:
- Generera serier av datum - använd datumtyp som indata
Du kunde ändra castcontext av int2 -> int4 . Men jag avråder starkt från det. För många möjliga biverkningar:
- Finns det något sätt att casta postgresql 9.3 datatyp så att den bara kan påverka en sida