package com.bytedance.kunlun.interpreter.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextUtil implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name)throws BeansException {
return applicationContext.getBean(name);
}
}
PS: @Component 注解.
从容器中主动获取Bean的使用方式
package com.bytedance.kunlun.interpreter;
import com.bytedance.kunlun.interpreter.parser.SpecificationParser;
import com.bytedance.kunlun.interpreter.spec.IQuerySpecification;
import com.bytedance.kunlun.interpreter.util.JsonUtil;
import com.bytedance.kunlun.interpreter.util.SpringContextUtil;
import com.bytedance.kunlun.sdk.drivermanager.model.DriverType;
import com.bytedance.kunlun.sdk.drivermanager.model.EngineType;
import com.bytedance.kunlun.sdk.interpreter.api.KunlunInterpreter;
import com.bytedance.kunlun.sdk.interpreter.model.*;
import org.springframework.stereotype.Service;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
/**
* Kunlun 编译器实现类
*/
@Service
public class KunlunInterpreterImpl implements KunlunInterpreter {
SpecificationParser specificationParser;
@Override
public Statement interpret(KunlunRule rule)throws Exception {
// 选择引擎
selectEngine(rule);
KunlunExpression expression = rule.getExpression();
// BFS 解析嵌套子句
bfsParseExpression(expression);
// 解析构建 ASTQuery 抽象语法树
IQuerySpecification specification =specificationParser.parse(rule);
// 物理资源映射,生成真正执行的物理 SQL Statement
Statement statement =new Statement();
if (specification !=null) {
statement.setSelectSql(specification.genSelectSql());
statement.setCountSql(specification.genSelectCountSql());
statement.setGroupBySql(specification.genSelectGroupBySql());
statement.setKvSql(specification.genSelectSqlForKV());
}
return statement;
}
private void selectEngine(KunlunRule rule) {
// 引擎选择
if (EngineType.OLAP.equals(rule.getEngineSelector().getEngineType())
&&DriverType.CLICKHOUSE.equals(rule.getEngineSelector().getDriverType())) {
specificationParser = (SpecificationParser)SpringContextUtil.getBean("specificationParserClickHouse");
}else if (EngineType.OLAP.equals(rule.getEngineSelector().getEngineType())
&&DriverType.HIVE.equals(rule.getEngineSelector().getDriverType())) {
specificationParser = (SpecificationParser)SpringContextUtil.getBean("specificationParserHive");
}else {
throw new IllegalArgumentException("engine not supported yet!");
}
}
/**
* BFS 遍历表达式树
*
* @param kunlunExpression
* @throws Exception
*/
private void bfsParseExpression(KunlunExpression kunlunExpression)throws Exception {
Queuequeue =new ArrayDeque<>();
ListexpressionList =new ArrayList<>();
// 根节点入队列
queue.offer(kunlunExpression);
while (!queue.isEmpty()) {
// 出队列
KunlunExpression expr =queue.poll();
ListsubExpressionList =expr.getSubExpression();
if (subExpressionList !=null && !subExpressionList.isEmpty()) {
for (KunlunExpression e :subExpressionList) {
// 子节点入队列
queue.offer(e);
}
}
expressionList.add(expr);
}
for (KunlunExpression e :expressionList) {
System.out.println(e);
// 解析
parseExpression(e);
}
}
/**
* 解析表达式
*
* @param kunlunExpression
* @throws Exception
*/
private void parseExpression(KunlunExpression kunlunExpression)throws Exception {
ExpressionLogicOperatorEnum logic = kunlunExpression.getLogic();
if (logic ==null) {
throw new RuntimeException("can't get operator from kunlunExpression:" +JsonUtil.toString(kunlunExpression));
}
FieldCondition fieldCondition = kunlunExpression.getFilterField();
if (fieldCondition !=null) {
// 获取特征值运算符
this.processFieldFeature(specificationParser, kunlunExpression);
}else {
specificationParser.compose(kunlunExpression);
}
}
private void processFieldFeature(SpecificationParser specificationParser,KunlunExpression kunlunExpression)throws Exception {
FieldCondition fieldCondition = kunlunExpression.getFilterField();
FieldArithmeticOperatorEnum operator =fieldCondition.getOperator();
switch (operator) {
case GREATER_THAN:
specificationParser.greaterThan(kunlunExpression);
break;
case GREATER_EQUAL_THAN:
specificationParser.greaterEqualThan(kunlunExpression);
break;
case LESS_THAN:
specificationParser.lessThan(kunlunExpression);
break;
case LESS_EQUAL_THAN:
specificationParser.lessEqualThan(kunlunExpression);
break;
case EQUAL:
specificationParser.equals(kunlunExpression);
break;
case IN:
specificationParser.in(kunlunExpression);
break;
case BETWEEN:
specificationParser.between(kunlunExpression);
break;
case LIKE:
specificationParser.like(kunlunExpression);
break;
default:
throw new RuntimeException("unsupported operator.");
}
}
}
网友评论