【秘密】関係者外秘 To:堀本様 渡部@国際ソフトウェアと申します。 ご報告ありがとうございます。 原因が判明して安堵いたしました。 ご丁寧に調査いただき感謝申し上げます。 Mroongaの修正については、引き続きご対応よろしくお願いいたします。 On 2021/07/07 12:00, groon****@lists***** wrote: > groonga-dev > メーリングリストへの投稿は以下のアドレスに送ってください. > > groon****@lists***** > > Webブラウザを使って入退会するには以下のURLにどうぞ. > > https://lists.osdn.me/mailman/listinfo/groonga-dev > メールを使う場合,件名(Subject:)または本文に help > と書いて以下の アドレスに送信してください. > groon****@lists***** > > メーリングリストの管理者への連絡は,以下のアドレスにお願いします. > > groon****@lists***** > > 返信する場合,件名を書き直して内容がわかるようにしてください. > そのままだと,以下のようになってしまいます. > "Re: groonga-dev まとめ読み, XX 巻 XX 号" > > > 本日の話題: > > 1. [groonga-dev,04876] Re: Mroongaバグ報告(6) (Horimoto Yasuhiro) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Tue, 06 Jul 2021 16:28:20 +0900 (JST) > From: Horimoto Yasuhiro <horim****@clear*****> > To: groon****@lists***** > Subject: [groonga-dev,04876] Re: Mroongaバグ報告(6) > Message-ID: > <20210****@clear*****> > Content-Type: Text/Plain; charset=utf-8 > > 堀本です。 > > 原因と対処方法がわかったので、報告いたします。 > 原因はMroongaのバグでした。 > > 以下の提示いただいたクエリーを実行した際 > MariaDBのオプティマイザーは、IN句内のサブクエリーを実行した結果のテーブルと > IN句の外側のテーブル(Posts)テーブルをSEMI JOINで結合します。 > > SELECT Id, ChannelId, RootId > FROM Posts p3 > WHERE Id IN ( > SELECT * FROM > (SELECT RootId > FROM Posts > WHERE UpdateAt > 1617352409099 AND > ChannelId = 'i9rsh6im4ffepfpdgm51hjze3a' > LIMIT 1000) > temp_tab); > > IN句の中のサブクエリーの結果は以下のようになり、 > 以下の表の値と、Posts.Idの値が同じレコードを抽出します。 > > つまり、''(空文字)と"twn3smcaei8wjbqsm8bcmo8qah"と一致する > Posts.Idを持つレコードを抽出します。 > > +----------------------------+ > | RootId | > +----------------------------+ > | | > | | > | | > | | > | | > | | > | twn3smcaei8wjbqsm8bcmo8qah | > | | > | | > | | > | | > | | > | | > | | > | | > | | > | | > | | > | | > | | > +----------------------------+ > 20 rows in set (0.001 sec) > > この時、Mroongaを使用していると、''と一致するレコードとして > 任意のIDを持つレコードを抽出してしまい、意図しないIDのレコードが結果に含まれてしまいます。 > InnoDBでは、再現しないため、Mroonga特有の問題です。 > > Mroongaを修正しますが、さしあたっては以下の対処方法で > 正しい結果が得られます。 > > 今回の問題は、''のような空文字のレコードを持つ表との結合 > で発生します。したがって、''のようなレコードが含まれないように > することで現象の発生を防げます。 > > RootIdはIdと比較しており、IdはNOT NULL属性なので、RootIdが''なレコード > は除外しても問題ないと考えます。 > > そのため、問題のクエリーのIN句の中のサブクエリーに > 以下のように、RootId <> ''を追加してRootIdが''なレコードを除外します。 > このようにすることで、期待する結果が得られます。 > > SELECT Id, ChannelId, RootId > FROM Posts p3 > WHERE Id IN ( > SELECT * FROM > (SELECT RootId > FROM Posts > WHERE UpdateAt > 1617352409099 AND > ChannelId = 'i9rsh6im4ffepfpdgm51hjze3a' AND > RootId <> '' > LIMIT 1000) > temp_tab); > > Mroongaの修正が完了しましたら、また改めて連絡します。 > > 以上です。失礼いたします。 >