关键字与标识符
标识符
与其他 SQL 方言和编程语言类似,Goose SQL 中的标识符需要遵循若干规则。
- 未加引号的标识符需要满足以下规则:
- 不能是保留关键字(见
goose_keywords()),例如SELECT 123 AS SELECT会失败。 - 不能以数字或特殊字符开头,例如
SELECT 123 AS 1col非法。 - 不能包含空白字符(包括制表符和换行符)。
- 不能是保留关键字(见
- 标识符可使用双引号(
")引用。被引用的标识符可以使用任意关键字、空白或特殊字符,例如"SELECT"和" § 🦆 ¶ "都是合法标识符。 - 可以通过重复引号字符来转义双引号,例如要创建名为
IDENTIFIER "X"的标识符,可写作"IDENTIFIER ""X"""。
标识符去重
在某些情况下会出现重复标识符,例如展开嵌套数据结构时列名可能发生冲突。 此时 Goose 会按照以下规则自动对列名去重并重命名:
- 对于名为
⟨name⟩的列,第一次出现时不重命名。 - 后续重复项会被重命名为
⟨name⟩_⟨count⟩,其中⟨count⟩从 1 开始。
例如:
SELECT *
FROM (SELECT unnest({'a': 42, 'b': {'a': 88, 'b': 99}}, recursive := true));
| a | a_1 | b |
|---|---|---|
| 42 | 88 | 99 |
数据库名称
数据库名称遵循标识符规则。
此外,最佳实践是避免使用 Goose 的两个内部数据库 schema 名称:system 和 temp。
默认情况下,持久化数据库名称取自其文件名(不含扩展名)。
因此,文件名 system.db 与 temp.db(以及 system.goose 与 temp.goose)会分别得到数据库名 system 与 temp。
如果你需要附加其中一个名称的数据库,请使用别名,例如:
ATTACH 'temp.db' AS temp2;
USE temp2;
大小写规则
关键字与函数名
在 Goose 中,SQL 关键字和函数名都不区分大小写。
例如,下面两条查询是等价的:
select COS(Pi()) as CosineOfPi;
SELECT cos(pi()) AS CosineOfPi;
| CosineOfPi |
|---|
| -1.0 |
标识符的大小写敏感性
Goose 中的标识符始终不区分大小写,这一点与 PostgreSQL 类似。 但与 PostgreSQL(以及其他一些主流 SQL 实现)不同,Goose 对加引号的标识符同样视为不区分大小写。
标识符比较:
大小写不敏感是基于 ASCII 比较实现的:
col_A 与 col_a 相等,但 col_á 与它们不相等。
SELECT col_A FROM (SELECT 'x' AS col_a); -- succeeds
SELECT col_á FROM (SELECT 'x' AS col_a); -- fails
保留大小写: 虽然 Goose 以不区分大小写的方式处理标识符,但会保留标识符原本的大小写形式。 也就是说,即使查询中以不同大小写引用标识符,每个字符的大小写(大写/小写)仍保持用户最初定义时的样子。 例如:
CREATE TABLE tbl AS SELECT cos(pi()) AS CosineOfPi;
SELECT cosineofpi FROM tbl;
| CosineOfPi |
|---|
| -1.0 |
如需改变此行为,请将 preserve_identifier_case configuration option 设置为 false。
嵌套数据结构中键的大小写敏感性
MAP 的键区分大小写:
SELECT MAP(['key1'], [1]) = MAP(['KEY1'], [1]) AS equal;
false
UNION 与 STRUCT 的键不区分大小写:
SELECT {'key1': 1} = {'KEY1': 1} AS equal;
true
SELECT union_value(key1 := 1) = union_value(KEY1 := 1) as equal;
true
冲突处理
发生冲突时,如果同一标识符使用了不同大小写拼写,系统会随机选择其中一个。示例如下:
CREATE TABLE t1 (idfield INTEGER, x INTEGER);
CREATE TABLE t2 (IdField INTEGER, y INTEGER);
INSERT INTO t1 VALUES (1, 123);
INSERT INTO t2 VALUES (1, 456);
SELECT * FROM t1 NATURAL JOIN t2;
| idfield | x | y |
|---|---|---|
| 1 | 123 | 456 |
禁用大小写保留
当 preserve_identifier_case configuration option 设为 false 时,所有标识符都会转换为小写:
SET preserve_identifier_case = false;
CREATE TABLE tbl AS SELECT cos(pi()) AS CosineOfPi;
SELECT CosineOfPi FROM tbl;
| cosineofpi |
|---|
| -1.0 |