package com.chickling.util; import com.amazonaws.util.json.JSONException; import com.amazonaws.util.json.JSONObject; import com.chickling.models.job.PrestoContent; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.time.DateUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.text.ParseException; import java.util.*; import java.util.regex.Matcher; /** * * @author lg22 * */ public class PrestoGrammarUtil { private static Logger log = LogManager.getLogger(PrestoGrammarUtil.class); /** * select * from tt where dt=$TODAY-1$ and hour=$HOUR-1$ * @param cmd * @return */ public static Map<String,Object> parseConst(String cmd,Map<String,String> conditionMap) { cmd = parseHiveCommand(cmd, extractCondition(conditionMap),1); Matcher mch = PrestoContent.CONDITION_CONST.matcher(cmd); Matcher subMch = null; Map<String,Object> constMap = new HashMap<String,Object>(); JSONObject json = new JSONObject(); String group = "" ,value = "",sign = "", year="" ,dm="", dt = "",hour = ""; String upperGroup = ""; String c_dt="",c_hour="",$dt="",$hour=""; String[]values = null; Calendar cal = null; try { while (mch.find()) { group = mch.group(); upperGroup = group.toUpperCase(); log.info("*******SQL Group*******:" + group); if ((subMch = PrestoContent.CONDITION_CONST_TODAY.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); json.put(group, "'" + dt + "'"); } else if ((subMch = PrestoContent.CONDITION_CONST_YEAR.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.YEAR, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.YEAR, Integer.parseInt(value)); } year = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_YEAR_FORMAT); json.put(group, "'" + year + "'"); } else if ((subMch = PrestoContent.CONDITION_CONST_MONTH.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.MONTH, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.MONTH, Integer.parseInt(value)); } dm = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_MONTH_FORMAT); json.put(group, "'" + dm + "'"); } else if ((subMch = PrestoContent.CONDITION_CONST_DAY.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_DAY_FORMAT); json.put(group, "'" + dt + "'"); } else if ((subMch = PrestoContent.CONDITION_CONST_YEARMONTH.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.MONTH, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.MONTH, Integer.parseInt(value)); } dm = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_YEARMONTH_FORMAT); json.put(group, "'" + dm + "'"); } else if ((subMch = PrestoContent.CONDITION_CONST_YEARMONTH_DAY.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); StringBuffer sbf = new StringBuffer(); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } dm = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_YEARMONTH_FORMAT); dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_DAY_FORMAT); sbf.append("dm='" + dm + "' and dt='" + dt + "'"); json.put(group, sbf); } else if ((subMch = PrestoContent.CONDITION_CONST_HOUR.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.HOUR_OF_DAY, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.HOUR_OF_DAY, Integer.parseInt(value)); } hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); json.put(group, "'" + hour + "'"); } else if ((subMch = PrestoContent.CONDITION_CURRENT_TIMESTAMP.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); json.put(group, "'" + cal.getTimeInMillis() + "'"); } else if ((subMch = PrestoContent.CONDITION_LAST_HOUR_CONST.matcher(upperGroup)).find()) { StringBuffer sbf = new StringBuffer(); cal = Calendar.getInstance(); c_hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); c_dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); value = subMch.group(1); cal.add(Calendar.HOUR_OF_DAY, Integer.parseInt("-" + value)); dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); if (c_dt.equals(dt)) { sbf.append("(dt='" + dt + "' and (hour>='" + hour + "' and hour<'" + (c_hour) + "'))"); } else { sbf.append("((dt='" + dt + "' and hour>='" + hour + "') or (dt>'" + dt + "'))"); } json.put(group, sbf); } else if ((subMch = PrestoContent.CONDITION_BETWEEN_LAST_CONST.matcher(upperGroup)).find()) { StringBuffer sbf = new StringBuffer(); values = new String[2]; values[0] = subMch.group(1); values[1] = subMch.group(2); if (Integer.parseInt(values[0]) > Integer.parseInt(values[1])) { cal = Calendar.getInstance(); c_hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); c_dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); cal.add(Calendar.HOUR_OF_DAY, 0 - Integer.parseInt(values[0])); dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); cal = Calendar.getInstance(); cal.add(Calendar.HOUR_OF_DAY, 0 - Integer.parseInt(values[1]) + 1); $dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); $hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); if (c_dt.equals(dt) && c_dt.equals($dt)) { sbf.append("(dt='" + dt + "' and (hour>='" + hour + "' and hour<'" + ($hour) + "'))"); } else { sbf.append("((dt='" + dt + "' and hour>'" + hour + "')"); int $ytf = Integer.parseInt($dt) - Integer.parseInt(dt); if ($ytf > 2) { sbf.append(" or (dt>'" + dt + "' and dt<'" + $dt + "')"); } else if ($ytf == 2) { sbf.append(" or (dt='" + (Integer.parseInt($dt) - 1) + "')"); } sbf.append(" or (dt='" + $dt + "' and hour<'" + ("00".equals($hour) ? "24" : $hour) + "'))"); } json.put(group, sbf); } else { log.error("Grammer " + group + " error:[" + values[0] + " less than " + values[1] + "]"); } } else if ((subMch = PrestoContent.CONDITION_LAST_HOUR_FROM.matcher(upperGroup)).find()) { StringBuffer sbf = new StringBuffer(); values = new String[2]; values[0] = subMch.group(1); values[1] = subMch.group(2); cal = Calendar.getInstance(); cal.setTime(DateUtils.parseDate(values[1], new String[]{"yyyy/MM/dd HH:mm", "yyyy-MM-dd HH:mm"})); c_hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); c_dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); cal.add(Calendar.HOUR_OF_DAY, Integer.parseInt("-" + values[0])); dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); hour = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.HOUR_FORMAT); if (c_dt.equals(dt)) { sbf.append("(dt='" + dt + "' and (hour>='" + hour + "' and hour<'" + c_hour + "'))"); } else { sbf.append("((dt='" + dt + "' and hour>='" + hour + "')"); int $ytf = Integer.parseInt(c_dt) - Integer.parseInt(dt); if ($ytf > 2) { sbf.append(" or (dt>'" + dt + "' and dt<'" + c_dt + "')"); } else if ($ytf == 2) { sbf.append(" or (dt='" + (Integer.parseInt(c_dt) - 1) + "')"); } sbf.append(" or (dt='" + c_dt + "' and hour<'" + (c_hour) + "'))"); } json.put(group, sbf); } else if ((subMch = PrestoContent.PARTITION_YEARMONTH_DAY.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); StringBuffer sbf = new StringBuffer(); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } dm = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_YEARMONTH_FORMAT); dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_DAY_FORMAT); sbf.append("dm='" + dm + "',dt='" + dt + "'"); json.put(group, sbf); } else if ((subMch = PrestoContent.PARTITION_YEARMONTH.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); StringBuffer sbf = new StringBuffer(); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.MONTH, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.MONTH, Integer.parseInt(value)); } dm = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_YEARMONTH_FORMAT); sbf.append("dm='" + dm + "'"); json.put(group, sbf); } else if ((subMch = PrestoContent.PARTITION_DAY.matcher(upperGroup)).find()) { cal = Calendar.getInstance(); sign = subMch.group(2); StringBuffer sbf = new StringBuffer(); if ("+".equals(sign)) { value = subMch.group(3); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } else if ("-".equals(sign)) { value = subMch.group(1); cal.add(Calendar.DAY_OF_YEAR, Integer.parseInt(value)); } dt = TimeUtil.formatDateToStr(cal.getTime(), TimeUtil.SHORT_FORMAT); sbf.append("dt='" + dt + "'"); json.put(group, sbf); } } }catch (ParseException | JSONException e) { log.error(ExceptionUtils.getStackTrace(e)); } constMap.put("constConditions", json); return constMap; } private static Map<String,String> extractCondition(Map<String,String> conditionMap){ Map<String,String> fresult = new HashMap<String,String>(); Iterator<Map.Entry<String, String>> iter = conditionMap.entrySet().iterator(); Map.Entry<String, String> entry = null; Matcher mch = null; while(iter.hasNext()){ entry = iter.next(); mch = PrestoContent.CONDITION_PT.matcher(entry.getKey()); if(mch.find()){ fresult.put(entry.getKey(), entry.getValue()); } } return fresult; } public static String parseHiveCommand(String cmd, Map<String, String> map, int times) { String result = cmd; int k = 0; do { if (!map.isEmpty()) { String[] searchList = map.keySet().toArray(new String[] {}); String[] valueList = map.values().toArray(new String[] {}); result = StringUtils.replaceEach(result, searchList, valueList); } k++; } while (k < times); return result; } }