Oplossing
Hoogstwaarschijnlijk de oplossing is om de operator schema-kwalificeren:
SELECT *
FROM test
WHERE tagged OPERATOR([email protected]>) '{11}'::int2[]
ORDER BY id
LIMIT 100;
Waarom?
Het is een probleem van operatorresolutie (in combinatie met typeresolutie en cast-context).
In standaard Postgres is er slechts één kandidaat-operator anyarray @> anyarray
, dat is degene die je wilt.
Je setup zou prima werken als je de extra module intarray niet had geïnstalleerd (mijn aanname), die een andere operator biedt voor integer[] @> integer[]
.
Daarom zou een andere oplossing zijn om integer[]
. te gebruiken in plaats daarvan en een GIN-index hebben met de gin__int_ops
operator klasse. Of probeer de (standaard voor intarray) gist__int_ops
inhoudsopgave. Beide kunnen sneller zijn, maar beide staan geen NULL-waarden toe.
Of u kunt de naam van de intarray
wijzigen operator @>
ondubbelzinnig te maken. (Dat zou ik niet doen. Upgrade- en draagbaarheidsproblemen treden op.)
Voor uitdrukkingen met ten minste één operand van het type integer[]
, Postgres weet welke operator hij moet kiezen:de intarray-operator. Maar dan is de index niet van toepassing , omdat de intarray-operator alleen werkt op integer
(int4
) niet int2
. En indexen zijn strikt gebonden aan operators:
- Kunnen PostgreSQL matrixkolommen indexeren?
- PostgreSQL-gedrag in aanwezigheid van twee verschillende typen indexen in dezelfde kolom
Maar voor int2[] @> int2[]
, Postgres kan niet beslissen wat de beste operator is. Beide lijken even toepasselijk. Aangezien de standaardoperator is opgegeven in de pg_catalog
schema en de intarray-operator wordt gegeven in de public
schema (standaard - of waar u de extensie ook hebt geïnstalleerd), kunt u het raadsel helpen oplossen door de operator schema-kwalificatie te geven met de OPERATOR()
bouwen. Gerelateerd:
- Vergelijk arrays voor gelijkheid, negeer de volgorde van elementen
De foutmelding die je krijgt is een beetje misleidend. Maar als je goed kijkt, is er een HINT
regel toegevoegd die hints (tada!) in de goede richting:
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.
U kunt bestaande operatorkandidaten onderzoeken voor @>
met:
SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM pg_operator o
JOIN pg_namespace n ON n.oid = o.oprnamespace
WHERE oprname = '@>';
Een andere alternatieve oplossing zou zijn om tijdelijk(!) een ander zoekpad in te stellen, zodat alleen de gewenste operator wordt gevonden. In dezelfde transactie:
SET LOCAL search_path = pg_catalog;
SELECT ...
Maar dan moet je alle tabellen in de query schema-kwalificeren.
Over cast-context:
- Genereer een reeks datums - gebruik het datumtype als invoer
Je zou verander de castcontext
van int2
-> int4
. Maar ik raad het ten zeerste af. Te veel mogelijke bijwerkingen:
- Is er een manier om het postgresql 9.3-gegevenstype te casten, zodat het slechts één kant kan beïnvloeden