CDH5.4 Hiveでwhere句が効かない現象について
うるう秒が迫ってきてビクビクしているにいやんです。こんばんわ。
とりあえず、うるう秒の時はHadoopクラスタ止めておくかな、どうしよかな・・・
前回CDH5.4でカラムずれが起きるバグの事を書いたのですが、同じようにleft outer joinを使った際にwhere句が効かないというか、where句が代入になるというか、なんといえば良いかわからないバグに遭遇したので、まとめてみました。
以下のような4つのテーブルを作成します。
create table t_1 ( aid int, bid int, t_1name string); create table t_2 ( aid int, bid int, t_2name string); create table t_3 ( aid int, bid int, t_3name string); create table t_4 ( aid int, bid int, t_4name string);
t-1からt-3までには以下のデータを
1 2 1 2 1 2
t-4には以下のデータを入れます
1 2 1 2 1 2 moge
それで以下のSQLでselect
select d.aid, d.bid, d.t_4name from t_1 a left outer join t_2 b on (a.aid = b.aid and b.t_2name = "test") left outer join t_3 c on a.bid = c.bid left outer join t_4 d on a.aid = d.aid where d.t_4name = "hoge";
d.t_4name = "hoge"にはどのデータもひっかからないので、このselect文の期待値は何も表示されないですが、このSQLの結果は・・・・
1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge 1 2 hoge
hoge キタ━━━(゚∀゚).━━━!!!
d.t_4nameに入ってるデータは「moge」なのですが、なぜかそれが「hoge」にかわり、結果が返されました・・・orz
explainも取ってみたいのですが、以下のようになってました。
STAGE DEPENDENCIES: Stage-8 is a root stage Stage-6 depends on stages: Stage-8 Stage-0 depends on stages: Stage-6 STAGE PLANS: Stage: Stage-8 Map Reduce Local Work Alias -> Map Local Tables: b Fetch Operator limit: -1 c Fetch Operator limit: -1 d Fetch Operator limit: -1 Alias -> Map Local Operator Tree: b TableScan alias: b Statistics: Num rows: 1 Data size: 15 Basic stats: COMPLETE Column stats: NONE Filter Operator predicate: (t_2name = 'test') (type: boolean) Statistics: Num rows: 0 Data size: 0 Basic stats: NONE Column stats: NONE HashTable Sink Operator keys: 0 aid (type: bigint) 1 aid (type: bigint) 2 aid (type: bigint) c TableScan alias: c Statistics: Num rows: 1 Data size: 15 Basic stats: COMPLETE Column stats: NONE HashTable Sink Operator keys: 0 _col1 (type: bigint) 1 bid (type: bigint) d TableScan alias: d Statistics: Num rows: 1 Data size: 19 Basic stats: COMPLETE Column stats: NONE HashTable Sink Operator keys: 0 aid (type: bigint) 1 aid (type: bigint) 2 aid (type: bigint) Stage: Stage-6 Map Reduce Map Operator Tree: TableScan alias: a Statistics: Num rows: 0 Data size: 15 Basic stats: PARTIAL Column stats: NONE Map Join Operator condition map: Left Outer Join0 to 1 Left Outer Join0 to 2 keys: 0 aid (type: bigint) 1 aid (type: bigint) 2 aid (type: bigint) outputColumnNames: _col1, _col12, _col13 Statistics: Num rows: 2 Data size: 41 Basic stats: COMPLETE Column stats: NONE Map Join Operator condition map: Left Outer Join0 to 1 keys: 0 _col1 (type: bigint) 1 bid (type: bigint) outputColumnNames: _col12, _col13 Statistics: Num rows: 2 Data size: 45 Basic stats: COMPLETE Column stats: NONE Select Operator expressions: _col12 (type: bigint), _col13 (type: bigint), 'hoge' (type: string) outputColumnNames: _col0, _col1, _col2 Statistics: Num rows: 2 Data size: 45 Basic stats: COMPLETE Column stats: NONE File Output Operator compressed: false Statistics: Num rows: 2 Data size: 45 Basic stats: COMPLETE Column stats: NONE table: input format: org.apache.hadoop.mapred.TextInputFormat output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat serde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe Local Work: Map Reduce Local Work Stage: Stage-0 Fetch Operator limit: -1 Processor Tree: ListSink
explainを見ると「d.t_4name = "hoge";」のwhere条件がなくなっています。
そして
「expressions: col12 (type: bigint), col13 (type: bigint), 'hoge' (type: string)」
ここを見てもらえればわかるように「d.t_4name」をselectした場所が「hoge」に変わってしまってます。
この現象が起きる条件としてわかってる範囲では以下の5つの条件が必要になるようです。
4つ以上のテーブルをleft outer joinでつなぐ
複数のkeyでjoinする(今回ではaidとbid)
複数のkeyのjoinを入れ子にする。(aidでjoinの後にbidでjoinしてからaidでjoinの様に)
どこかのon句にkeyのjoin以外の条件を追加(今回では「b.t_2name = "test"」)
入れ子にした後のテーブルのカラムでwhere句を生成
HiveのJIRAも検索したのですが、同じ様な現象は発見出来ませんでした。(どなたか知ってたら教えてください)
前回に紹介したカラムずれといい、今回の紹介のバグといい、left outer joinちょっと怖いですね・・・
早く治ります様に(ー人ー)
-- 2015/07/08 追記
CDH5.4.3では直っている事を確認出来ました。