词法结构

编辑

本节介绍 SQL 的主要词法结构,大部分与 ANSI SQL 本身相似,因此不深入讨论底层细节。

Elasticsearch SQL 目前一次只接受一个命令。命令是由输入流结束符终止的标记序列。

标记可以是关键字标识符带引号的不带引号的)、字面量(或常量)或特殊字符符号(通常是分隔符)。标记通常用空格(空格、制表符)分隔,但在某些情况下,如果没有歧义(通常是由于字符符号),则不需要分隔 - 但为了提高可读性,应避免这种情况。

关键字

编辑

以下面的例子为例:

SELECT * FROM table

此查询有四个标记:SELECT*FROMtable。前三个,即 SELECT*FROM关键字,表示在 SQL 中具有固定含义的单词。标记 table 是一个标识符,表示它(通过名称)标识 SQL 中的实体,例如表(在本例中)、列等……​

可以看出,关键字和标识符都具有相同的词法结构,因此,如果不了解 SQL 语言,就无法知道标记是哪一种;完整的关键字列表可在保留附录中找到。请注意,关键字不区分大小写,这意味着之前的示例可以写成:

select * fRoM table;

但是标识符区分大小写,因为 Elasticsearch 区分大小写,Elasticsearch SQL 会逐字使用接收到的值。

为了帮助区分两者,在整个文档中,SQL 关键字都使用大写字母,我们发现这种约定提高了可读性,因此建议其他人也这样做。

标识符

编辑

标识符可以分为两种类型:带引号的不带引号的

SELECT ip_address FROM "hosts-*"

此查询有两个标识符,ip_addresshosts-*(一个索引模式)。由于 ip_address 不与任何关键字冲突,因此可以直接使用,而 hosts-* 则不能,因为它与 -(减号运算)和 * 冲突,因此需要使用双引号。

另一个例子

SELECT "from" FROM "<logstash-{now/d}>"

第一个标识符 from 需要用引号引起来,否则会与 FROM 关键字冲突(该关键字不区分大小写,因此可以写成 from),而第二个标识符使用 Elasticsearch 索引和索引别名名称中的日期数学支持,否则会使解析器感到困惑。

因此,一般来说,尤其在处理用户输入时,强烈建议对标识符使用引号。这只会给查询增加极少的负担,但会提高清晰度和消除歧义。

字面量(常量)

编辑

Elasticsearch SQL 支持两种隐式类型的字面量:字符串和数字。

字符串字面量
编辑

字符串字面量是由单引号 ' 括起来的任意数量的字符:'Giant Robot'。要在字符串中包含单引号,请使用另一个单引号转义它:'Captain EO''s Voyage'

转义的单引号不是双引号 ("),而是重复的单引号 ' ('')。

数字字面量
编辑

数字字面量可以接受十进制表示法和科学计数法,带有指数标记 (eE),并以数字或小数点 . 开头。

1969    -- integer notation
3.14    -- decimal notation
.1234   -- decimal notation starting with decimal point
4E5     -- scientific notation (with exponent marker)
1.2e-3  -- scientific notation with decimal point

包含小数点的数字字面量始终被解释为 double 类型。不包含小数点的数字字面量,如果符合条件则被视为 integer 类型,否则其类型为 long(或 ANSI SQL 类型中的 BIGINT)。

通用字面量
编辑

在处理任意类型的字面量时,可以通过转换(通常是将字符串表示形式转换为所需的类型)来创建对象。这可以通过专用的转换运算符函数来实现

123::LONG                                   -- cast 123 to a LONG
CAST('1969-05-13T12:34:56' AS TIMESTAMP)    -- cast the given string to datetime
CONVERT('10.0.0.1', IP)                     -- cast '10.0.0.1' to an IP

请注意,Elasticsearch SQL 提供了开箱即用的返回常用字面量(如 E())或为某些字符串提供专用解析的函数。

单引号与双引号

编辑

值得指出的是,在 SQL 中,单引号 ' 和双引号 " 具有不同的含义,并且不能互换使用。单引号用于声明字符串字面量,而双引号用于标识符

例如:

SELECT "first_name" 
  FROM "musicians"  
 WHERE "last_name"  
     = 'Carroll'    

双引号 " 用于列和表标识符

单引号 ' 用于字符串字面量

要转义单引号或双引号,需要再次使用该特定引号。例如,字面量 John's 可以像 SELECT 'John''s' AS name 这样转义。双引号转义也是如此 - SELECT 123 AS "test""number" 将显示一个名称为 test"number 的列。

特殊字符

编辑

一些非字母数字字符具有不同于运算符的专用含义。为完整起见,下面列出了这些字符:

字符

描述

*

星号(或通配符)在某些上下文中用于表示表的所有字段。也可以用作某些聚合函数的参数。

,

逗号用于枚举列表的元素。

.

在数字常量中使用,或用于分隔标识符限定符(目录、表、列名等……)。

()

圆括号用于特定的 SQL 命令、函数声明或强制执行优先级。

运算符

编辑

Elasticsearch SQL 中的大多数运算符具有相同的优先级,并且是左结合的。由于这是在解析时完成的,因此需要使用圆括号来强制执行不同的优先级。

下表指出了支持的运算符及其优先级(从高到低);

运算符/元素

结合性

描述

.

限定符分隔符

::

PostgreSQL 样式的类型转换

+ -

一元加号和减号(数字字面量符号)

* / %

乘法、除法、取模

+ -

加法、减法

BETWEEN IN LIKE

范围包含、字符串匹配

< > <= >= = <=> <> !=

比较

NOT

逻辑非

AND

逻辑与

OR

逻辑或

注释

编辑

Elasticsearch SQL 允许注释,注释是解析器忽略的字符序列。

支持两种样式

单行
注释以双破折号 -- 开头,并持续到行尾。
多行
/* 开头并以 */ 结尾的注释(也称为 C 样式)。
-- single line comment
/* multi
   line
   comment
   that supports /* nested comments */
   */