[groonga-dev,01729] Re: grn_str_charlen_utf8のwarningメッセージの影響について

Back to archive index

Naoya Murakami visio****@gmail*****
2013年 8月 30日 (金) 07:11:55 JST


お世話になっております。村上です。

1.grn_str_charlen_utf8(): imcomplete character

このメッセージが出力されるケースが特定できました。
ベクターカラムに対して、"区切り文字データなし"をinsertした後に、
selectすると、うまくデータを取得できません(NULLが入るんですかね)。
これをinsert into A select * from Bすると、このメッセージが発生します。

ベクターカラムに投入したデータに問題があったようです。

既存のテーブルをgroup_concatしただけで、結構、
"データ1区切り文字区切り文字データ2"となっているケースがあったので、
投入するデータをチェックして、区切り文字の後にデータがない状態が
発生しないようにしてベクターカラムに投入したいと思います。

"データ1区切り文字区切り文字データ2"をinsertとすると、
データ2(下のケースだと"ぐるんが")が無視されますが、
この挙動が正しいのかどうかよくわかりません。よければ、ご検討ください。

投入の仕方に問題があると思うので、mroonga,groongaでどういう挙動させる
かは、ご判断次第かと思います。
データなしを無視して、データ1とデータ2だけを入れることができるとあまり
投入仕方を意識しなくてよいので楽ですが、この挙動が正しいかといわれる
とよくわかりません。

mysql> INSERT INTO Bugs (id, tags) VALUES (1, "りなっくす  ぐるんが");
mysql> INSERT INTO Bugs (id, tags) VALUES (2, "ユニックス  ");
mysql> INSERT INTO Bugs (id, tags) VALUES (3, "ウィンドウズ ポルンガ タッカラプトプピリットパロ");
mysql> select * from Bugs;
+----+-------------------------------------------------------------------------+
| id |
tags                                                                    |
+----+-------------------------------------------------------------------------+
|  1 | りなっくす ・                                                      |
|  2 | ユニックス ・                                                      |
|  3 | ウィンドウズ ポルンガ タッカラプトプピリットパロ |
+----+-------------------------------------------------------------------------+

mysql> select mroonga_command('select --table Bugs');
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| mroonga_command('select --table
Bugs')
|
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|
[[[3],[["_id","UInt32"],["_key","UInt32"],["id","UInt32"],["tags","Tags"]],[1,1,1,["りなっくす",""]],[2,2,2,["ユニックス",""]],[3,3,3,["ウィンドウズ","ポルンガ","タッカラプトプピリットパロ"]]]]
|
+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> insert ignore into Bugs2 select * from Bugs;

・groonga.log
2013-08-30 03:21:39.277841|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.277965|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278492|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278522|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278642|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278665|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278685|w|20388700|grn_str_charlen_utf8(): imcomplete
character
2013-08-30 03:21:39.278697|w|20388700|grn_str_charlen_utf8(): imcomplete
character

2. grn_str_charlen_utf8(): first byte is invalid

こちらについては、多数の自然文書を喰わせている以上、稀に不正な文字が
含まれるのも仕方のないことかなぁと考えています。

逐一調べて、前処理で不正な文字を処理するのもあまり現実的ではないかな
と考えています。どんな不正な文字が含まれているのかを特定するのも大変
そうです。

>例えば、以下のように不正なUTF-8文字を含んでいる場合、
>  Hel${不正なUTF-8文字}lo World
>「lo World」以降は無視される処理になっていることがほとんどなはずです。

このような不正文字は、おそらく文章の途中で区切られているケースはあまり
ないと思われます。
なので、以下のようにトークナイズしてくれていたら影響が少なくうれしいなと
思っています。それとも、やはり後ろに続くHello World.まで無視されてしまう
のですかね。。

Good Bye World.${不正なUTF-8文字}Hello World.
↓
Good | Bye | World | . | Hello | World | .

トークンを切り出した後に無視されるのか、それとも文章に不正文字が1つでも
含まれていたら、不正文字の後の全部が無視されるのかで影響度がかなり違うので、
このあたりを知りたいなぁと思ってます。
たとえば、数千文字の文章で先頭1文字目で不正文字がでてきたら、文章全体が
無視されてしまう?

このメッセージがでる文章を特定できたら、実際のトークナイズされ方を見ることが
できると思いますが、オフラインインデックス構築中に稀に見かける程度なので、
どの文章でこのメッセージがでているのかを特定するのが大変なのですよね。

この警告メッセージが出力される文章および不正文字の出現位置を簡単に
特定する方法はありますか?
ソースを一時的に書き換えてこのメッセージをエラーにしておけば、処理がとまって
特定できますかね?
それか、前に教えていただいたようにして、gdbでbreak str.c:44とかしておけば、
ブレークしてとまってくれるのですかね?

https://github.com/groonga/groonga/blob/b6f34484726019881d2466d979cc45cd3afd2c12/lib/str.c#L44

なお、照合順序をバイナリにすれば、大丈夫かもしれませんが、
レアケースのために、照合順序をバイナリにすることは考えていません。

---------------------------------------------
以下でgrn_str_charlen_utf8(): imcomplete characterを再現することができます。
ご参考まで。

CREATE TABLE Tags (
  name VARCHAR(64) PRIMARY KEY
) DEFAULT CHARSET=utf8
  COLLATE=utf8_bin
  COMMENT='default_tokenizer "TokenDelimit"';

CREATE TABLE Bugs (
  id INT UNSIGNED PRIMARY KEY,
  tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "Tags"',
  FULLTEXT INDEX tags (tags) COMMENT 'table "Tags"'
) DEFAULT CHARSET=utf8;


CREATE TABLE Tags2 (
  name VARCHAR(64) PRIMARY KEY
) DEFAULT CHARSET=utf8
  COLLATE=utf8_bin
  COMMENT='default_tokenizer "TokenDelimit"';

CREATE TABLE Bugs2 (
  id INT UNSIGNED PRIMARY KEY,
  tags TEXT COMMENT 'flags "COLUMN_VECTOR", type "Tags2"',
  FULLTEXT INDEX tags (tags) COMMENT 'table "Tags2"'
) DEFAULT CHARSET=utf8;

INSERT INTO Bugs (id, tags) VALUES (1, "りなっくす  ぐるんが");
INSERT INTO Bugs (id, tags) VALUES (2, "ユニックス  ");
INSERT INTO Bugs (id, tags) VALUES (3, "ウィンドウズ ポルンガ タッカラプトプピリットパロ");

insert ignore into Bugs2 select * from Bugs;


以上、よろしくお願いします。



groonga-dev メーリングリストの案内
Back to archive index