链式数据分析引擎解析(二)

117 阅读1分钟

接上篇,本篇说下SQL转换

// where 实现没那么智能
select 5,max(8) from a where 5 not like '%css%' group by 5 order by 1 desc

SQL拆单词有点复杂这里就不说了

接着说下初始代码,目的是把sql变为上面的链式

//关键词节点的链式(类似状态机)
//默认是start->select(from where group ...)-from(where group ...)
private StatusNode currentStatus = null;
//SQL语句解析词放在list里面
private Iterator<String> words = null;

public void start() throws Exception {
		while(words.hasNext()) {
			String word = null;
		//给状态节点一直喂word
  //当前节点是否完成了,默认第一次start不走		
  while (words.hasNext() && !currentStatus.isSaturated()) {
				word = words.next();
				try {
					log.info("feed :" + currentStatus + " with '" + word + "'");
   //feed里有数据校验的
   //然后设置到对应的链式中
					currentStatus.feed(word, this);
				} catch (FeedException e) {
					String error = ExceptionUtil.makeLQLErrorMsgForStateMachine(lql, word, e.getMessage());
					throw new InvalidLQLException(error);
				}
			}
			//喂饱之后 指的是当前的节点 切换到下一个节点
			if (words.hasNext()) {
				if (!currentStatus.isWordOverflow()) {
					word = words.next();
				}
                //当前的关键字语句;完成一个后获取下一个关键字语句
				currentStatus = currentStatus.next(word);
				log.info("switch by '" + word + "' to :" + currentStatus);
				if(currentStatus==null){
					throw new InvalidLQLException("unexpected '"+word+"'");
				}
			}
		}
  //结束解析
		currentStatus.endup(this);
		//判断节点完整性 例如必须有 select from
		if(!currentStatus.isSaturated()){
			throw new InvalidLQLException("uncompleted value for " + currentStatus);
		}
		if(!this.getResult().isSaturated()){
			throw new InvalidLQLException("uncompleted lql!");
		}
	}

分析下select关键字

public class SelectNode extends AbstractNode<LogQueryLanguageParserStateMachine> {
    static Logger log = Logger.getLogger(SelectNode.class.getName());
    public SelectNode() {
        super("select");
    }
    @Override
    public void feed(String word, StateMachine<LogQueryLanguageParserStateMachine> stateMachine) throws FeedException {
        LogQueryLanguageParserStateMachine machine = stateMachine.get();
       //得到数据并且校验内容
        word = getInnerString(word);
        for(String prop : word.split(",")){
            prop = getInnerString(prop);
            //assertNumber(prop);
        }
        //格式OK,将select的字段设置到解析结果中
        //设置到链式中
        machine.getResult().setSelect(word);
        //表明当前节点已经处理完毕
        saturated = true;
        log.info("set SELECT as " + word);
    }
}