function explain() { //ajaxリクエスト以外 if( !$this->RequestHandler->isAjax() ) { $this->set("result" , array("result" => "not ajax")); return; } //パラメータ解析 $u_userid=$this->params['form']['u']; $u_database=$this->params['form']['d']; $u_query=htmlspecialchars_decode($this->params['form']['q'], ENT_QUOTES); if ( $u_database == "" or $u_userid == "" or $u_query == "" ){ $this->set("result" , array("result" => "parameter error")); return; } //事前処理 list($res,$hive_database)=CommonComponent::HiveBefore($u_userid,$u_query); if ( $res != 0 ){ $this->set("result" , array("result" => "許可されていないクエリです")); return; } //リクエストID発行 if ( CommonComponent::MakeDirectory($u_userid) != 0 ){ $this->set("result" , array("result" => "create directory error")); return; } $u_id=sprintf("%s_%05d",date("YmdHis"),getmypid()); $hql_file=DIR_REQUEST."/${u_userid}/${u_id}.hql"; $chk_file=DIR_REQUEST."/${u_userid}/${u_id}.chk"; $exp_file=DIR_RESULT."/${u_userid}/${u_id}.exp"; //コメント行変換処理 $arr=preg_split("/[\r\n]/",$u_query); $u_query2=""; for ($i=0; $i<count($arr); $i++){ if ( eregi('^--',$arr[$i]) ){ $u_query2.="$arr[$i];\n"; }else{ $u_query2.="$arr[$i]\n"; } } //リクエストファイル作成 if ( !($fp=fopen($hql_file,"w")) ){ $this->set("result" , array("result" => "file open error", "id" => "$u_id")); return; } fputs($fp,"use ${u_database};\n"); $arr=preg_split("/;/",$u_query2); for ($i=0; $i<count($arr); $i++){ $arr[$i]=str_replace(array("\r\n","\n","\r","\t"), ' ', $arr[$i]); $arr[$i]=ltrim($arr[$i]); if ( $arr[$i] == "" ){ continue; } $ret=fputs($fp,"$arr[$i];\n"); } fclose($fp); //EXPLAINファイル作成 if ( !($fp=fopen($chk_file,"w")) ){ $this->set("result" , array("result" => "file open error", "id" => "$u_id")); return; } fputs($fp,"use ${u_database};\n"); $arr=preg_split("/;/",$u_query2); for ($i=0; $i<count($arr); $i++){ $arr[$i]=str_replace(array("\r\n","\n","\r","\t"), ' ', $arr[$i]); $arr[$i]=ltrim($arr[$i]); if ( $arr[$i] == "" ){ continue; } if ( eregi('^--',$arr[$i]) ){ $ret=fputs($fp,"$arr[$i]\n"); continue; } if ( eregi(SQL_EXPLAIN_EXCLUDE,$arr[$i]) ){ $ret=fputs($fp,"$arr[$i];\n"); }else{ $ret=fputs($fp,"explain $arr[$i];\n"); } } fclose($fp); // explainによるHiveQLチェック $cmd = CMD_HIVE . " -v -f $chk_file > $exp_file 2>&1"; $this->log("CMD=$cmd",LOG_DEBUG); exec($cmd,$result,$retval); $this->log("CMD=$cmd => $retval",LOG_DEBUG); if ( !file_exists($exp_file) ){ $this->set("result" , array("result" => "explain error", "id" => "$u_id")); return; } if ( $retval != 0 ){ $this->set("result" , array("result" => "query error", "id" => "$u_id")); return; } // explain結果判定 list($stage_cnt,$mapreduce_cnt,$line_cnt)=CommonComponent::CheckSQLexplain($u_userid,$u_id); if ( $stage_cnt < 0 ){ $this->set("result" , array("result" => "unknown", "id" => "$u_id")); return; } // データベース実行権限チェック $u_databases=DATABASE_PERMISSION; $u_user=$this->Users->find('all', array( "conditions" => "username='******'", "limit"=>1)); if(!empty($u_user[0]['Users']['hive_database'])){ $u_databases=$u_user[0]['Users']['hive_database']; } $chk_result=CommonComponent::CheckExplainDatabase($u_userid,$u_id,$u_databases); if ( $chk_result != 0 ){ $this->set("result" , array("result" => "指定されたデータベースへのアクセスが許可されていません", "id" => "$u_id")); return; } //時間がかかりそうな場合は結果確認画面を出す if ( $stage_cnt > 3 or $mapreduce_cnt > 0 or $line_cnt > 35 ){ $msg="処理数=$stage_cnt MapReduce数=$mapreduce_cnt コスト=$line_cnt"; $this->set("result" , array("result" => "check", "id" => "$u_id", "msg"=>"$msg")); }else{ $this->set("result" , array("result" => "ok", "id" => "$u_id")); } }