この記事は 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.
ただ、それまではちょっと注意が必要なので、念のため。