複数行を返すかもしれないサブクエリー
SQLのサブクエリーが複数行を返すからどうとかいうエラーは型と型の演算結果がどんな型になるかのデータを入れたテーブルを検索するサブクエリーで起こっていることまで絞り込めた。そのサブクエリーと=で比較しているからだな。でも他にも同じようにやってるところがあるけどなんでここだけ? とりあえず=をINに変えれば解決はするけど、気になるのでちょっと考えてみた。
ていうか、特定のテーブルだけで起こってたのですぐにピンと来て実際は考えてない。
SELECT * FROM foo WHERE result_type = ( SELECT result FROM type_promotion WHERE operator = '+' AND lhs = 1 AND rhs = 2);
原因はサブクエリーのWHERE句で使ってる三つのカラム(operator, lhs, rhs)がユニークじゃないからだ。その結果条件がユニークにならないから複数行返す可能性があると判断されてたんだな。WHERE句で使ってる三つのカラムをまとめてユニークにしてやれば=にしてもエラーがでなくなった。PostgreSQLは賢いな、実際1行しか返らないデータであっても実行する前からエラーにされるのは余計なお世話な気もするけど。
CREATE TABLE type_promotion ( id SERIAL, operator TEXT NOT NULL, lhs INTEGER NOT NULL, rhs INTEGER NOT NULL, result INTEGER NOT NULL, CONSTRAINT pk_type_promotion_id PRIMARY KEY(id), CONSTRAINT uq_lhs_operator_rhs UNIQUE(operator, lhs, rhs) );
でもなんてpsql上ではエラーにならないんだろう?
このテーブル後から追加してデバッグが終わってなかったみたいだな。DROPするSQLにも書かれてないし、一昨年の最後にやりかけてたのはこれか。
これ書いててlhsとrhsとresultを外部キーにすべきことにも気がついた。typesテーブルのidが入るので。