跳到主要内容

关键字与标识符

标识符

与其他 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));
aa_1b
428899

数据库名称

数据库名称遵循标识符规则。

此外,最佳实践是避免使用 Goose 的两个内部数据库 schema 名称systemtemp。 默认情况下,持久化数据库名称取自其文件名(不含扩展名)。 因此,文件名 system.dbtemp.db(以及 system.goosetemp.goose)会分别得到数据库名 systemtemp。 如果你需要附加其中一个名称的数据库,请使用别名,例如:

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_Acol_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

UNIONSTRUCT 的键不区分大小写:

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;
idfieldxy
1123456

禁用大小写保留

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