Lösung
Höchstwahrscheinlich die Lösung soll den Operator schemaqualifizieren:
SELECT *
FROM test
WHERE tagged OPERATOR([email protected]>) '{11}'::int2[]
ORDER BY id
LIMIT 100;
Warum?
Es ist ein Problem der Operatorauflösung (in Kombination mit Typauflösung und Umwandlungskontext).
In Standard-Postgres gibt es nur einen einzigen Kandidatenoperator anyarray @> anyarray
, das ist es, was Sie wollen.
Ihr Setup würde problemlos funktionieren, wenn Sie das zusätzliche Modul intarray nicht installiert hätten (meine Vermutung), die einen weiteren Operator für integer[] @> integer[]
bereitstellt .
Daher wäre eine andere Lösung die Verwendung von integer[]
stattdessen und haben einen GIN-Index mit dem gin__int_ops
Betreiberklasse. Oder versuchen Sie es mit (Standard für Intarray) gist__int_ops
Index. Beide könnten schneller sein, aber beide erlauben keine NULL-Werte.
Oder Sie könnten das intarray
umbenennen Operator @>
zu disambiguieren. (Das würde ich nicht tun. Es entstehen Upgrade- und Portabilitätsprobleme.)
Für Ausdrücke mit mindestens einem Operanden vom Typ integer[]
, Postgres weiß, welchen Operator es auswählen muss:den Intarray-Operator. Aber dann ist der Index nicht anwendbar , da der Intarray-Operator nur mit integer
arbeitet (int4
) nicht int2
. Und Indizes sind strikt an Operatoren gebunden:
- Kann PostgreSQL Array-Spalten indizieren?
- Verhalten von PostgreSQL bei Vorhandensein von zwei verschiedenen Arten von Indizes für dieselbe Spalte
Aber für int2[] @> int2[]
, Postgres ist nicht in der Lage, den besten Operator zu bestimmen. Beide scheinen gleichermaßen anwendbar zu sein. Da der Standardoperator in pg_catalog
bereitgestellt wird Schema und der Intarray-Operator wird in public
bereitgestellt Schema (standardmäßig - oder wo auch immer Sie die Erweiterung installiert haben), können Sie helfen, das Rätsel zu lösen, indem Sie den Operator mit OPERATOR()
schemaqualifizieren bauen. Verwandte:
- Arrays auf Gleichheit vergleichen, Reihenfolge der Elemente ignorieren
Die Fehlermeldung, die Sie erhalten, ist etwas irreführend. Aber wenn Sie genau hinsehen, gibt es einen HINT
Zeile hinzugefügt, die Hinweise (Tada!) in die richtige Richtung:
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.
Sie können vorhandene Operatorkandidaten für @>
untersuchen mit:
SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM pg_operator o
JOIN pg_namespace n ON n.oid = o.oprnamespace
WHERE oprname = '@>';
Eine andere alternative Lösung wäre, vorübergehend (!) einen anderen Suchpfad festzulegen, sodass nur der gewünschte Operator gefunden wird. In derselben Transaktion:
SET LOCAL search_path = pg_catalog;
SELECT ...
Aber dann müssen Sie alle Tabellen in der Abfrage schemaqualifizieren.
Über den Besetzungskontext:
- Generieren Sie eine Reihe von Datumsangaben - verwenden Sie den Datumstyp als Eingabe
Sie könnten Ändern Sie den castcontext
von int2
-> int4
. Aber ich rate dringend davon ab. Zu viele mögliche Nebenwirkungen:
- Gibt es eine Möglichkeit, den Datentyp von postgresql 9.3 so umzuwandeln, dass er nur eine Seite betrifft