CoreData:SUBQUERY() でSQLite error code:1, ‘no such column:…のエラーへの対処


例えば、データベースのように1つのレコード(record エントリー)に複数のフィールドがあって、フィールドは別のエントリー(fieldエントリー)にして親であるレコードから1対多でリレーションする。フィールドにはカラム番号(colNumber属性)とテキスト(text属性)があるとする。
この場合に、カラム番号とテキストの一部一致をAND条件で指定して検索したい場合は、SUBQUERYを使うやり方がある。SUBQUERY()は @count をとって0でなければヒットしたということで記述するようにするようだ。

そこで、以下のように書いてみた。

NSPredicate*p = [NSPredicate predicateWithFormat:@"SUBQUERY(record.fields, $x, $x.text contains[cd] %@ AND $x.colNumber == %@).@count > 0",searchText, searchColNumber]

ところが、
SQLite error code:1, ‘no such column:…
というエラーが発生してしまう。

どうも、元になるセットの記述にrecord.fieldsのようにドット演算子でつないだものを使えないようだ。
以下のサイトにヒントがあった。
objective c – CoreData many-to-many relation (sub)query – Stack Overflow

以下のように修正して解決。

NSPredicate*p = [NSPredicate predicateWithFormat:@"SUBQUERY(record, $r, (SUBQUERY($r.fields, $x, $x.text contains[cd] %@ AND $x.colNumber == %@)).@count > 0) != NULL",searchText, searchColNumber]

SUBQUERYを二重に記述することもそうだが、それより最後を != NULL にすればよいということが分かるまでが僕にはかなり大変だったのでメモ。