Beam ZetaSQL 词法结构
Beam ZetaSQL 语句由一系列标记组成。标记包括标识符、带引号的标识符、字面量、关键字、运算符和特殊字符。标记可以用空格(空格、退格键、制表符、换行符)或注释分隔。
标识符
标识符是与列、表和其他数据库对象相关联的名称。
有两种方法可以指定标识符:不带引号或带引号
- 不带引号的标识符必须以字母或下划线开头。后续字符可以是字母、数字或下划线。
- 带引号的标识符用反引号 (`) 字符括起来,可以包含任何字符,例如空格或符号。但是,带引号的标识符不能为空。 保留关键字 只能在用反引号括起来的情况下用作标识符。
语法(作为具有正则表达式的语法呈现,忽略空格)
identifier: { quoted_identifier | unquoted_identifier } unquoted_identifier:[A-Za-z_][A-Za-z_0-9]*
quoted_identifier:\`[^\\\`\r\n]
any_escape*\`
any_escape:\\(. | \n | \r | \r\n)
示例
Customers5
_dataField1
ADGROUP
无效示例
5Customers
_dataField!
GROUP
5Customers
以数字开头,而不是字母或下划线。_dataField!
包含特殊字符 "!",它不是字母、数字或下划线。GROUP
是保留关键字,因此不能用作标识符,除非用反引号括起来。
标识符和带引号的标识符都不区分大小写,但也有一些细微差别。有关更多详细信息,请参阅 大小写敏感性。
带引号的标识符与字符串字面量的转义序列相同,定义如下。
字面量
字面量表示内置数据类型的常量值。某些(但并非所有)数据类型可以用字面量表示。
字符串和字节字面量
字符串和字节字面量都必须带引号,可以使用单引号 ('
) 或双引号 ("
) 括起来,或者用三组单引号 ('''
) 或三组双引号 ("""
) 括起来三引号。
带引号的字面量
字面量 | 示例 | 描述 |
---|---|---|
带引号的字符串 |
| 用单引号 (' ) 括起来的带引号的字符串可以包含未转义的双引号 (" ),反之亦然。反斜杠 ( \ ) 引入转义序列。请参阅下面的转义序列表。带引号的字符串不能包含换行符,即使在反斜杠 ( \ ) 之前也是如此。 |
三引号字符串 |
| 允许嵌入换行符和引号,无需转义 - 请参阅第四个示例。 反斜杠 ( \ ) 引入转义序列。请参阅下面的转义序列表。行尾的未转义反斜杠 ( \ ) 不允许。三个连续的未转义引号将与起始引号匹配,这将结束字符串。 |
原始字符串 |
| 带引号的或三引号的字面量具有原始字符串字面量前缀 (r 或 R ),被解释为原始/正则表达式字符串。反斜杠字符 ( \ ) 不充当转义字符。如果字符串字面量中出现反斜杠后跟另一个字符,则会保留这两个字符。原始字符串不能以奇数个反斜杠结尾。 原始字符串对于构建正则表达式非常有用。 |
前缀字符 (r
、R
、b
、B)
对带引号的或三引号的字符串是可选的,分别表示该字符串是原始/正则表达式字符串或字节序列。例如,b'abc'
和 b'''abc'''
都被解释为字节类型。前缀字符不区分大小写。
带前缀的带引号的字面量
下表列出了在字符串字面量中表示非字母数字字符的所有有效转义序列。表中未列出的任何序列都会导致错误。
转义序列 | 描述 |
---|---|
\a | 响铃 |
\b | 退格键 |
\f | 换页符 |
\n | 换行符 |
\r | 回车键 |
\t | 制表符 |
\v | 垂直制表符 |
\\ | 反斜杠 (\ ) |
\? | 问号 (? ) |
\" | 双引号 (" ) |
\' | 单引号 (' ) |
\` | 反引号 (` ) |
\ooo | 八进制转义,正好有三位数字(范围为 0-7)。解码为单个 Unicode 字符(在字符串字面量中)。 |
\xhh 或 \Xhh | 十六进制转义,正好有两个十六进制数字(0-9 或 A-F 或 a-f)。解码为单个 Unicode 字符(在字符串字面量中)。示例
|
\uhhhh | Unicode 转义,用小写字母 'u' 和正好四个十六进制数字。仅在字符串字面量或标识符中有效。 请注意,范围 D800-DFFF 不允许,因为这些是代理 Unicode 值。 |
\Uhhhhhhhh | Unicode 转义,用大写字母 'U' 和正好八个十六进制数字。仅在字符串字面量或标识符中有效。 请注意,范围 D800-DFFF 不允许,因为这些是代理 Unicode 值。此外,大于 10FFFF 的值也不允许。 |
整数字面量
整数字面量是十进制数字 (0 到 9) 的序列,或者以 "0x
" 为前缀的十六进制值。整数可以以 "+
" 或 "-
" 为前缀,分别表示正值和负值。
示例
123
0xABC
-123
整数字面量被解释为 INT64
。
浮点字面量
语法选项
[+-]DIGITS.[DIGITS][e[+-]DIGITS]
[DIGITS].DIGITS[e[+-]DIGITS]
DIGITSe[+-]DIGITS
DIGITS
表示一个或多个十进制数字 (0 到 9),e
表示指数标记 (e 或 E)。
示例
123.456e-67
.1E4
58.
4e2
包含小数点或指数标记的数字字面量被假定为双精度类型。
如果值在有效的 float 范围内,则可以将浮点字面量隐式强制转换为 float 类型。
没有 NaN 或无穷大的字面量表示形式。
数组字面量
数组字面量是用方括号括起来的以逗号分隔的元素列表。ARRAY
关键字是可选的,显式元素类型 T 也是可选的。
示例
[1, 2, 3]
['x', 'y', 'xy']
ARRAY[1, 2, 3]
ARRAY<string>['x', 'y', 'xy']
时间戳字面量
语法
TIMESTAMP 'YYYY-[M]M-[D]D [[H]H:[M]M:[S]S[.DDDDDD]] [timezone]'
时间戳字面量包含 TIMESTAMP
关键字和符合规范时间戳格式的字符串字面量,用单引号括起来。
时间戳字面量支持 1 年到 9999 年(含)之间的范围。此范围之外的时间戳无效。
时间戳字面量可以包含数字后缀以指示时区
TIMESTAMP '2014-09-27 12:30:00.45-08'
如果此后缀不存在,则使用默认时区 UTC。
例如,以下时间戳使用 UTC 时区表示 2014 年 9 月 27 日下午 12:30。
TIMESTAMP '2014-09-27 12:30:00.45'
有关时区的更多信息,请参阅 时区。
包含规范时间戳格式的字符串字面量(包括带有时区名称的字符串字面量)在预期时间戳表达式的地方使用时,会隐式强制转换为时间戳字面量。例如,在以下查询中,字符串字面量 "2014-09-27 12:30:00.45 America/Los_Angeles"
被强制转换为时间戳字面量。
SELECT * FROM foo
WHERE timestamp_col = "2014-09-27 12:30:00.45 America/Los_Angeles"
时区
由于时间戳字面量必须映射到特定时间点,因此需要时区才能正确解释字面量。如果字面量本身未指定时区,则使用 Beam SQL 实现设置的默认时区值。
时区用以下规范格式的字符串表示,该格式表示相对于协调世界时 (UTC) 的偏移量。
格式
(+|-)H[H][:M[M]]
示例
'-08:00'
'-8:15'
'+3:00'
'+07:30'
'-7'
时区也可以使用来自 tz 数据库 的字符串时区名称来表示。有关更简单但不太全面的参考,请参阅维基百科上的 tz 数据库时区列表。规范的时区名称格式为 <continent/[region/]city>
,例如 America/Los_Angeles
。
请注意,即使时区名称在一年中的某个时间段内恰好报告相同的时间,它们也不一定都可互换。例如,America/Los_Angeles
在夏令时期间报告与 UTC-7:00
相同的时间,但在夏令时以外报告与 UTC-8:00
相同的时间。
示例
TIMESTAMP '2014-09-27 12:30:00 America/Los_Angeles'
TIMESTAMP '2014-09-27 12:30:00 America/Argentina/Buenos_Aires'
大小写敏感性
Beam SQL 遵循以下关于大小写敏感性的规则
类别 | 大小写敏感? | 备注 |
---|---|---|
关键字 | 否 | |
函数名称 | 否 | |
表名称 | 参见备注 | 表名称通常不区分大小写,但在查询使用区分大小写表名称的数据库时,可能会区分大小写。 |
列名称 | 否 | |
字符串值 | 是 | |
字符串比较 | 是 | |
查询中的别名 | 否 | |
正则表达式匹配 | 参见备注 | 正则表达式匹配默认情况下区分大小写,除非表达式本身指定不区分大小写。 |
LIKE 匹配 | 是 |
保留关键字
关键字是一组在 Beam SQL 语言中具有特殊含义的标记,具有以下特征
- 关键字不能用作标识符,除非用反引号 (`) 字符括起来。
- 关键字不区分大小写。
Beam SQL 具有以下保留关键字。
ALL AND ANY ARRAY AS ASC ASSERT_ROWS_MODIFIED AT BETWEEN BY CASE CAST COLLATE CONTAINS CREATE CROSS CUBE CURRENT DEFAULT DEFINE DESC DISTINCT ELSE END | ENUM ESCAPE EXCEPT EXCLUDE EXISTS EXTRACT FALSE FETCH FOLLOWING FOR FROM FULL GROUP GROUPING GROUPS HASH HAVING IF IGNORE IN INNER INTERSECT INTERVAL INTO | IS JOIN LATERAL LEFT LIKE LIMIT LOOKUP MERGE NATURAL NEW NO NOT NULL NULLS OF ON OR ORDER OUTER OVER PARTITION PRECEDING PROTO RANGE | RECURSIVE RESPECT RIGHT ROLLUP ROWS SELECT SET SOME STRUCT TABLESAMPLE THEN TO TREAT TRUE UNBOUNDED UNION UNNEST USING WHEN WHERE WINDOW WITH WITHIN |
终止分号
语句可以在通过应用程序编程接口 (API) 提交的查询字符串的上下文中可选地使用终止分号 (;
)。某些交互式工具要求语句具有终止分号。在包含多个语句的请求中,语句必须用分号隔开,但对于最后一个语句,分号是可选的。
注释
注释是解析器忽略的字符序列。Beam SQL 支持以下类型的注释。
单行注释
单行注释通过在注释之前添加 #
或 --
来支持。
示例
SELECT x FROM T; # x 是一个字段,T 是一个表
注释包括从 '#' 字符到行尾的所有字符。
SELECT x FROM T; --x 是一个字段,T 是一个表
注释包括从 '--
' 序列到行尾的所有字符。您可以在 '--
' 之后可选地添加一个空格。
多行注释
多行注释通过使用 /* <comment> */
将注释括起来来支持。
示例
SELECT x FROM T /* x is a field and T is a table */
WHERE x = 3;
无效示例
SELECT x FROM T /* comment starts here
/* comment ends on this line */
this line is not considered a comment */
WHERE x = 3;
注释包括所有字符,包括换行符,从第一个 '/*
' 的出现到第一个后续 '*/
' 的出现。不支持嵌套注释。第二个示例包含一个嵌套注释,这使得查询无效。