改行コード (CRLF) に注意

この記事は Apache Drill Advent Calendar 2015 の7日目の記事です。

改行コードの取り扱いは、現時点での Drill の注意事項の一つです。Linux/Mac の環境で生成されたテキストデータであれば問題は起きませんが、Windows 環境で生成されたテキストデータ(もしくは Windows 環境で処理されることを前提としたデータ)を処理するときに、問題になるケースがあります。

例えば、Windows マシンで次のような CSV ファイルを作成します。

1,尾形金弥,オガタキンヤ,0582958162
2,三橋佑奈,ミハシユウナ,0987381855
3,鮫島憲司,サメジマケンジ,0982675562
4,宮野久寛,ミヤノヒサヒロ,0477707528

これを拡張子 .csv をつけて Drill で SELECT * してみると次のようになります。

0: jdbc:drill:zk=local> SELECT * FROM dfs.`/tmp/phone.csv`;
+----------------------------------------+
|                columns                 |
+----------------------------------------+
| ["1","尾形金弥","オガタキンヤ","0582958162\r"]   |
| ["2","三橋佑奈","ミハシユウナ","0987381855\r"]   |
| ["3","鮫島憲司","サメジマケンジ","0982675562\r"]  |
| ["4","宮野久寛","ミヤノヒサヒロ","0477707528\r"]  |
+----------------------------------------+
5 rows selected (0.325 seconds)

各行の配列の最後の要素に改行コード「\r」が含まれてしまっているのが見えます。さらに、配列要素をカラムに分解して表示してみると、

0: jdbc:drill:zk=local> SELECT columns[0] AS id,
. . . . . . . . . . . >        columns[1] AS name,
. . . . . . . . . . . >        columns[2] AS kana,
. . . . . . . . . . . >        columns[3] AS phone
. . . . . . . . . . . > FROM dfs.`/tmp/phone.csv`;
+-----+-------+-----------+--------------+
| id  | name  |   kana    |    phone     |
+-----+-------+-----------+--------------+
  |   | 尾形金弥  | オガタキンヤ    | 0582958162 ← 右端の「|」が無くなって左端のカラムを上書きしている
  |   | 三橋佑奈  | ミハシユウナ    | 0987381855
  |   | 鮫島憲司  | サメジマケンジ   | 0982675562
  |   | 宮野久寛  | ミヤノヒサヒロ   | 0477707528
+-----+-------+-----------+--------------+
5 rows selected (0.667 seconds)

このように改行(CR)のせいで表示がおかしくなる上、次のようなクエリは期待した結果を返さなくなってしまいます。

0: jdbc:drill:zk=local> SELECT columns[1] AS name
. . . . . . . . . . . > FROM dfs.`/tmp/phone.csv`
. . . . . . . . . . . > WHERE columns[3] LIKE '0987381855%';
+-------+
| name  |
+-------+
+-------+
No rows selected (0.373 seconds)

原因は、Windows 環境では改行コードが「\r\n」にもかかわらず、Drill が「\n」のみを改行コードとして扱っているためです。これを回避する単純な方法は tr の利用でしょう。

$ tr -d '\r' < /tmp/phone.csv > /tmp/phone_modified.csv

Drill コミュニティでもこの問題は認識されていて、修正されるまでにはそれほど長くはかからないはずです。

[DRILL-3149] TextReader should support multibyte line delimiters

[DRILL-3726] Drill is not properly interpreting CRLF (0d0a). CR gets read as content.

ただ、それまではちょっと注意が必要なので、念のため。