0.51版本的Server端: 6) StatementResource.createQuery原理

下面开始分析

@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(sessionquery);

代码如下:

@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();

}






你可能感兴趣的:(presto)