下面开始分析
@POST
@Produces(MediaType.APPLICATION_JSON)
public Response createQuery(String statement, @HeaderParam(PRESTO_USER) String user,
@HeaderParam(PRESTO_SOURCE) String source, @HeaderParam(PRESTO_CATALOG) String catalog,
@HeaderParam(PRESTO_SCHEMA) String schema, @HeaderParam(USER_AGENT) String userAgent,
@Context HttpServletRequest requestContext, @Context UriInfo uriInfo) throws InterruptedException {
assertRequest(!isNullOrEmpty(statement), "SQL statement is empty");
assertRequest(!isNullOrEmpty(user), "User (%s) is empty", PRESTO_USER);
assertRequest(!isNullOrEmpty(catalog), "Catalog (%s) is empty", PRESTO_CATALOG);
assertRequest(!isNullOrEmpty(schema), "Schema (%s) is empty", PRESTO_SCHEMA);
String remoteUserAddress = requestContext.getRemoteAddr();
Session session = new Session(user, source, catalog, schema, remoteUserAddress, userAgent);
ExchangeClient exchangeClient = exchangeClientSupplier.get();
Query query = new Query(session, statement, queryManager, exchangeClient);
queries.put(query.getQueryId(), query);
return Response.ok(query.getNextResults(uriInfo, new Duration(1, TimeUnit.MILLISECONDS))).build();
}
很好,看看收到HTTP请求后,究竟做了什么事情!
首先是校验数据是否OK,不赘述!
===========
String remoteUserAddress = requestContext.getRemoteAddr();
这里的requestContext的类为javax.servlet.http.HttpServletRequest,是不是很熟悉!
获取远程客户端的地址
然后创建一个session
Session session = new Session(user, source, catalog, schema, remoteUserAddress, userAgent);
类型为: com.facebook.presto.sql.analyzer.Session.Session,这个类比较简单,就不分析了。
大致就是存了一些变量的值
@JsonCreator
public Session(
@JsonProperty("user") @Nullable String user,
@JsonProperty("source") String source,
@JsonProperty("catalog") String catalog,
@JsonProperty("schema") String schema,
@JsonProperty("remoteUserAddress") String remoteUserAddress,
@JsonProperty("userAgent") String userAgent,
@JsonProperty("startTime") long startTime)
{
this.user = user;
this.source = source;
this.catalog = checkNotNull(catalog, "catalog is null");
this.schema = checkNotNull(schema, "schema is null");
this.remoteUserAddress = remoteUserAddress;
this.userAgent = userAgent;
this.startTime = startTime;
}
---继续执行,
ExchangeClient exchangeClient = exchangeClientSupplier.get();
然后执行
Query query = new Query(session, statement, queryManager, exchangeClient);
代码如下:
public Query(Session session, String query, QueryManager queryManager, ExchangeClient exchangeClient) {
//校验
checkNotNull(session, "session is null");
checkNotNull(query, "query is null");
checkNotNull(queryManager, "queryManager is null");
checkNotNull(exchangeClient, "exchangeClient is null");
this.queryManager = queryManager;//保留句柄
QueryInfo queryInfo = queryManager.createQuery(session, query);//这个比较重要
queryId = queryInfo.getQueryId();
this.exchangeClient = exchangeClient;
}
===下面来重点分析QueryInfo queryInfo = queryManager.createQuery(session, query);
代码如下:
@Override
public QueryInfo createQuery(Session session, String query) {
//校验
checkNotNull(query, "query is null");
//校验
Preconditions.checkArgument(!query.isEmpty(), "query must not be empty string");
//ID生成器生成了一个ID
QueryId queryId = queryIdGenerator.createNextQueryId();
//这里就是解析了
Statement statement;
try {
statement = SqlParser.createStatement(query);//这部分恕我才疏学浅,
只能直接打出来结果,用antlr生成的
} catch (ParsingException e) {
return createFailedQuery(session, query, queryId, e);
}
QueryExecutionFactory<?> queryExecutionFactory = executionFactories.get(statement.getClass());---取出对应的工厂对象
对应的类为queryExecutionFactory = "com.facebook.presto.execution.SqlQueryExecution$SqlQueryExecutionFactory@d83cc76"
注意:这个是之前生成的,此时拿出来用即可。
PS:这个工厂比较重要,所以新开了一节,传送门: http://my.oschina.net/qiangzigege/blog/649859
Preconditions.checkState(queryExecutionFactory != null, "Unsupported statement type %s",
statement.getClass().getName());---校验下,确保类型正确!
final QueryExecution queryExecution = queryExecutionFactory.createQueryExecution(queryId, query, session,
statement);
queryMonitor.createdEvent(queryExecution.getQueryInfo());
queryExecution.addStateChangeListener(new StateChangeListener<QueryState>() {
@Override
public void stateChanged(QueryState newValue) {
if (newValue.isDone()) {
QueryInfo info = queryExecution.getQueryInfo();
stats.queryFinished(info);
queryMonitor.completionEvent(info);
}
}
});
queries.put(queryId, queryExecution);
// start the query in the background
queryExecutor.submit(new QueryStarter(queryExecution, stats));
return queryExecution.getQueryInfo();
}