inner pathkeys do not match mergeclause

2010/11/27

PostgreSQL

PostgreSQLでテーブルを結合するSQLを投げると、タイトルのようなERRORが吐かれるというお話。今さら感たっぷりなのだが、ちょっと調べてみたので残しておく。

原因は、PostgreSQLのバグ。

8.4.1および8.3.8で修正されているので、それ以降のバージョンを使えば解決。まぁ、それぞれのメジャーバージョンの最新版を使ってください、と。8.4系なら8.4.5に入れ替えればOKということですな。


どんなバグかというと、プランナの中で結合条件をチェックする処理がグダグダだったというもの、らしい。

問題の箇所はMerge Joinを処理するところなので、「set enable_mergejoin = off」とかやってMerge Joinを使わなくすれば逃げられるけど、おすすめはしません。代わりに、Nested Loopが使われると、目も当てられないことになります。たぶん。

「PostgreSQL のバージョンアップなんか許さん!」という状況に陥ったらどうするか...

SQLを書き換えると逃げられるかもしれません。

例えば、JOIN ... ONの後に、1つの列名を複数回記述する場合、それらを連続して書くようにします。
...なんだかよく分かりませんね。というわけで、例。
testdb=# CREATE TABLE t_i (x int, y int, z int);
CREATE TABLE
testdb=# CREATE TABLE t_o (a int, b int, c int);
CREATE TABLE
testdb=# SELECT * FROM t_i LEFT OUTER JOIN t_o
            ON x=a
           AND y=b
           AND y=a
           AND z=c;
ERROR:  inner pathkeys do not match mergeclause
testdb=# SELECT * FROM t_i LEFT OUTER JOIN t_o
            ON x=a
           AND y=a
           AND y=b
           AND z=c;
 x | y | z | a | b | c
---+---+---+---+---+---
(0 rows)

うまくやらないと、「too few pathkeys for mergeclauses」というERRORになることもあります。めんどくさいですね。

以下、英語の情報とか。

QooQ