druid sql part-13

This commit is contained in:
liujianhuan 2020-06-22 15:25:10 +08:00
parent 708897f8f8
commit 4fdd5daf92
3 changed files with 140 additions and 4 deletions

View File

@ -3,4 +3,5 @@
### `table` ### `table`
### `lookup` ### `lookup`
### `union` ### `union`
### `inline`
### `join` ### `join`

View File

@ -497,12 +497,144 @@ SQL中的子查询一般被转换为原生的查询数据源。有关如何执
> [!WARNING] > [!WARNING]
> WHERE子句中的子查询`WHERE col1 IN (SELECT foo FROM ...)`,被转化为内连接 > WHERE子句中的子查询`WHERE col1 IN (SELECT foo FROM ...)`,被转化为内连接
#### 近似 #### 近似
#### 不支持的特征
Druid SQL在一些场景中使用近似算法
* 默认情况下,`COUNT(DISTINCT col)` 聚合函数使用 [HyperLogLog](http://algo.inria.fr/flajolet/Publications/FlFuGaMe07.pdf) 的变体HyperLogLog是一种快速近似的DISTINCT计数算法。如果通过查询上下文或通过Broker配置将"useApproximateCountDistinct"设置为"false"Druid SQL将切换到精确计数
* 对于具有ORDER BY和LIMIT的单列GROUP BY查询可以采用使用了近似算法的TopN引擎执行查询。如果通过查询上下文或通过Broker配置将"useApproximateTopN"设置为"false"Druid SQL将切换到精确的分组算法
* 标记为使用草图或近似(例如近似计数不同)的聚合函数不管配置如何,始终是近似的
#### 不支持的特性
Druid SQL并非支持所有的SQL特性。 以下特性不支持:
* 原生数据源table, lookup, subquery与系统表的JOIN操作
* 左侧和右侧的表达式之间不相等的JOIN条件
* OVER子句`LAG``LEAD` 等分析型函数
* OFFSET子句
* DDL和DML
* 在 [元数据表](#元数据表) 上使用Druid特性的函数比如 `TIME_PARSE``APPROX_QUANTILE_DS`
另外一些Druid原生查询中的特性目前还不被SQL支持。 不支持的特性如下:
* [UNION数据源](datasource.md#union)
* [INLINE数据源](datasource.md#inline)
* [空间过滤器](spatialfilter.md)
* [查询取消](makeNativeQueries.md#查询取消)
### 客户端API ### 客户端API
#### HTTP #### HTTP POST
在Druid SQL查询中可以通过HTTP方式发送POST请求到 `/druid/v2/sql` 来执行SQL查询。该请求应该是一个带有 "query" 字段的JSON对象例如 `{"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar'"}`
**Request**
| 属性 | 描述 | 默认值 |
|-|-|-|
| `query` | SQL | 必填,无 |
| `resultFormat` | 查询结果的格式详情查看下边的response部分 | object |
| `header` | 是否包含一个请求头详情查看下边的response部分 | false |
| `context` | 包括 [连接上下文](#连接上下文) 参数JSON对象 | {}(空) |
| `parameters` | 参数化查询的查询参数列表。列表中的每个参数都应该是一个JSON对象比如 `{"type""VARCHAR""value""foo"}``type` 应为SQL类型有关支持的SQL类型的列表请参见 [数据类型](#数据类型) | [](空) |
可以在命令行中使用 *curl* 来发送SQL查询
```json
$ cat query.json
{"query":"SELECT COUNT(*) AS TheCount FROM data_source"}
$ curl -XPOST -H'Content-Type: application/json' http://BROKER:8082/druid/v2/sql/ -d @query.json
[{"TheCount":24433}]
```
可以提供一个"context"的参数来添加 [连接上下文](#连接上下文) 变量,例如:
```json
{
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
"context" : {
"sqlTimeZone" : "America/Los_Angeles"
}
}
```
参数化SQL查询也是支持的
```json
{
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = ? AND __time > ?",
"parameters": [
{ "type": "VARCHAR", "value": "bar"},
{ "type": "TIMESTAMP", "value": "2000-01-01 00:00:00" }
]
}
```
通过对 [元数据表](#元数据表) 进行HTTP POST请求可以获得元数据
**Responses**
Druid SQL的HTTP POST API支持一个可变的结果格式可以通过"resultFormat"参数来指定,例如:
```json
{
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
"resultFormat" : "object"
}
```
支持的结果格式为:
| 格式 | 描述 | Content-Type |
|-|-|-|
| `object` | 默认值JSON对象的JSON数组。每个对象的字段名都与SQL查询返回的列匹配并且按与SQL查询相同的顺序提供。| application/json |
| `array` | JSON数组的JSON数组。每个内部数组按顺序都有与SQL查询返回的列匹配的元素。 | application/json |
| `objectLines` | 与"object"类似但是JSON对象由换行符分隔而不是包装在JSON数组中。如果您没有流式JSON解析器的现成访问权限这可以使将整个响应集解析为流更加容易。为了能够检测到被截断的响应此格式包含一个空行的尾部。 | text/plain |
| `arrayLines` | 与"array"类似但是JSON数组由换行符分隔而不是包装在JSON数组中。如果您没有流式JSON解析器的现成访问权限这可以使将整个响应集解析为流更加容易。为了能够检测到被截断的响应此格式包含一个空行的尾部。 | text/plain |
| `csv` | 逗号分隔的值,每行一行。单个字段值可以用双引号括起来进行转义。如果双引号出现在字段值中,则通过将它们替换为双引号(如`""this""`)来对其进行转义。为了能够检测到被截断的响应,此格式包含一个空行的尾部。 | text/csv |
您还可以通过在请求中将"header"设置为true来请求头例如
```json
{
"query" : "SELECT COUNT(*) FROM data_source WHERE foo = 'bar' AND __time > TIMESTAMP '2000-01-01 00:00:00'",
"resultFormat" : "arrayLines",
"header" : true
}
```
在这种情况下,返回的第一个结果将是头。对于 `csv``array``arrayline` 格式,标题将是列名列表。对于 `object``objectLines` 格式,头将是一个对象,其中键是列名,值为空。
在发送响应体之前发生的错误将以JSON格式报告状态代码为HTTP 500格式与 [原生Druid查询错误](makeNativeQueries.md#查询错误) 相同。如果在发送响应体时发生错误此时更改HTTP状态代码或报告JSON错误已经太迟因此响应将简单地结束流并且处理您的请求的Druid服务器将记录一个错误。
作为调用者,正确处理响应截断非常重要。这对于"object"和"array"格式很容易因为的截断响应将是无效的JSON。对于面向行的格式您应该检查它们都包含的尾部结果集末尾的一个空行。如果通过JSON解析错误或缺少尾随的换行符检测到截断的响应则应假定响应由于错误而未完全传递。
#### JDBC #### JDBC
您可以使用 [Avatica JDBC Driver](https://calcite.apache.org/avatica/downloads/) 来进行Druid SQL查询。 下载Avatica客户端jar包后加到类路径下使用如下连接串 `jdbc:avatica:remote:url=http://BROKER:8082/druid/v2/sql/avatica/`
示例代码为:
```java
// Connect to /druid/v2/sql/avatica/ on your Broker.
String url = "jdbc:avatica:remote:url=http://localhost:8082/druid/v2/sql/avatica/";
// Set any connection context parameters you need here (see "Connection context" below).
// Or leave empty for default behavior.
Properties connectionProperties = new Properties();
try (Connection connection = DriverManager.getConnection(url, connectionProperties)) {
try (
final Statement statement = connection.createStatement();
final ResultSet resultSet = statement.executeQuery(query)
) {
while (resultSet.next()) {
// Do something
}
}
}
```
表的元数据信息在JDBC中也是可以查询的通过 `connection.getMetaData()` 或者查询 [信息Schema](#信息Schema)
**连接粘性**
Druid的JDBC服务不在Broker之间共享连接状态。这意味着如果您使用JDBC并且有多个Druid Broker您应该连接到一个特定的Broker或者使用启用了粘性会话的负载平衡器。Druid Router进程在平衡JDBC请求时提供连接粘性即使使用普通的非粘性负载平衡器也可以用来实现必要的粘性。请参阅 [Router文档](../Design/Router.md) 以了解更多详细信息
#### 动态参数 #### 动态参数
#### 连接上下文 #### 连接上下文
### 元数据表 ### 元数据表

View File

@ -1 +1,4 @@
<!-- toc --> <!-- toc -->
## 原生查询
### 查询取消
### 查询错误