解決策
おそらく、解決策 演算子をスキーマ修飾することです:
SELECT *
FROM test
WHERE tagged OPERATOR([email protected]>) '{11}'::int2[]
ORDER BY id
LIMIT 100;
なぜですか?
これはオペレーターの解決の問題です (タイプ解決とキャストコンテキストとの組み合わせ)
標準のPostgresでは、候補演算子anyarray @> anyarray
は1つだけです。 、それはあなたが望むものです。
追加のモジュールintarrayをインストールしていなければ、セットアップは問題なく機能します。 (私の仮定)、これはinteger[] @> integer[]
の別の演算子を提供します 。
したがって、別の解決策はinteger[]
を使用することです。 代わりに、gin__int_ops
のGINインデックスを作成します 演算子クラス。または、(intarrayのデフォルト)gist__int_ops
を試してください 索引。どちらかが速いかもしれませんが、どちらもNULL値を許可していません。
または、intarray
の名前を変更することもできます 演算子@>
明確にする。 (私はそうしません。アップグレードと移植性の問題が発生します。)
タイプinteger[]
のオペランドを少なくとも1つ含む式の場合 、Postgresはどの演算子を選択するかを知っています:intarray演算子。ただし、インデックスは適用されません 、intarray演算子はinteger
でのみ動作するため (int4
)int2
ではありません 。また、インデックスは厳密に演算子にバインドされています:
- PostgreSQLは配列列にインデックスを付けることができますか?
- 同じ列に2つの異なるタイプのインデックスが存在する場合のPostgreSQLの動作
ただし、int2[] @> int2[]
の場合 、Postgresは最適な演算子を決定できません。どちらも同じように適用できるようです。デフォルトの演算子はpg_catalog
で提供されているため スキーマとintarray演算子は、public
で提供されます。 スキーマ(デフォルト-または拡張機能をインストールした場所)では、OPERATOR()
を使用して演算子をスキーマ修飾することにより、難問を解決するのに役立ちます。 構築します。関連:
- 要素の順序を無視して、配列が等しいかどうかを比較します
表示されるエラーメッセージは少し誤解を招く可能性があります。しかし、よく見ると、HINT
があります。 正しい方向へのヒント(tada!)を追加した行:
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.
@>
の既存の演算子候補を調査できます と:
SELECT o.oid, *, oprleft::regtype, oprright::regtype, n.nspname
FROM pg_operator o
JOIN pg_namespace n ON n.oid = o.oprnamespace
WHERE oprname = '@>';
別の代替ソリューションは、一時的に(!)別のsearch_pathを設定して、目的の演算子のみが見つかるようにすることです。同じトランザクションで:
SET LOCAL search_path = pg_catalog;
SELECT ...
ただし、クエリ内のすべてのテーブルをスキーマ修飾する必要があります。
キャストコンテキストについて:
- 一連の日付を生成します-入力として日付タイプを使用します
あなたはできた castcontext
を変更します int2
の -> int4
。しかし、私はそれに対して強くお勧めします。考えられる副作用が多すぎます:
- postgresql9.3データ型をキャストして片側だけに影響を与える方法はありますか