1. 序言
-  作为Presto的客户端之一,Presto CLI是一个基于终端的交互式shell,对应presto源码中的presto-cli模块 
-  Presto CLI的本质是一个self-executing jar —— presto-cli-version-executable.jar,就像一个普通的UNIX可执行文件
-  因此,可以像下面这样使用presto cli ./presto --server localhost:8080 --user adhoc_user --catalog hive
-  Presto CLI依赖Presto client向Presto server提交查询,获取查询执行进度、执行结果等。 
-  Presto使用Master-Slave架构,对外提供服务的接口都在coordinator中,上面的描述可以改写为:Pressto client向coordinator提交查询 
-  笔者认为,在学习Presto CLI前,了解Presto client与coordinator之间如何进行HTTP通信是极有必要的 
-  官网有Presto Client的相关文档:Presto Client REST API,本文对Presto client的介绍也会参考该文档,并辅以Presto 0.279的源码 
1.1 StatementClientV1.advance()方法,获取下一批查询结果(简称response)
 
- 成功创建StatementClientV1后,上层调用者将根据StatementClientV1的状态,决定是否发起更多的请求以获取查询结果
- 注意: 查询结果是广义的,它包括查询执行进度和执行结果。
response为查询执行进度
- response中的QueryResults.data为null,只有查询的状态信息(QueryResults.stats)client.currentData().getData() != null
- 此时,上层调用会打印执行进度,并继续调用StatementClientV1.advance()方法获取下一批查询结果
- 例如,非交互式查询下的presto.cli.Query.processInitialStatusUpdates()方法,则负责获取并打印执行进度private void processInitialStatusUpdates(WarningsPrinter warningsPrinter) {while (client.isRunning() && (client.currentData().getData() == null)) {warningsPrinter.print(client.currentStatusInfo().getWarnings(), true, false);client.advance();}... // 其他代码省略 }
response为查询执行结果
-  response中的QueryResults.data不为 null,这时可以进入执行结果打印阶段
-  presto.cli.Query.renderResults()方法负责查询结果的打印,该方法最终将调用OutputHandler.processRows()方法构建并打印行数据
-  由于QueryResults.data中可能只是部分执行结果,可能还需要多次调用advance()方法获取剩余的执行结果 public void processRows(StatementClient client)throws IOException {while (client.isRunning()) {Iterable<List<Object>> data = client.currentData().getData();if (data != null) {for (List<Object> row : data) {processRow(unmodifiableList(row)); // 超过MAX_BUFFERED_ROWS(10_000)则刷新输出}}// 超过MAX_BUFFER_TIME,也会刷新输出if (nanosSince(bufferStart).compareTo(MAX_BUFFER_TIME) >= 0) {flush(false);}// 访问nextUri,获取新的执行结果client.advance();} }
1.2 关于nextUri
- new StatementClientV1()时,以POST方式向/v1/statement接口发送查询请求,这时只是提交一个查询
- 因为查询具有lazy execution特征,需要以GET方式、多次访问response中的nextUri,才能触发查询的执行、获取查询执行进度以及查询结果
- advance()方法就是访问nextUri的关键方法,每次访问nexrUri都将返回一个response;若response中的nexrUri为null,说明查询结束
- nextUri不停变化,意味着查询处于不同的阶段,如/v1/statement/queued/、/v1/statement/executing/等
- 具体的nextUri的变化,可以参考之前的博客《结合Presto CLI,Presto Client学习》的4.3小节
2. 取消正在运行的查询
 # 3. 非交互式查询的执行流程
 # 3. 非交互式查询的执行流程 
 # 4. 交互式查询的执行流程
 # 4. 交互式查询的执行流程 
 # 5. 单个查询的执行流程
 # 5. 单个查询的执行流程 
