字面量类型
Goose 提供了特殊的字面量类型,用于在查询中表示 NULL、整数和字符串字面量。它们有各自的绑定与转换规则。
在 Goose 0.10.0 之前,整数和字符串字面量的行为与
INTEGER和VARCHAR类型完全一致。
NULL 字面量
NULL 字面量使用关键字 NULL 表示。NULL 字面量可以被隐式转换为任意其他类型。
整数字面量
整数字面量表示为由一个或多个十进制数字组成的序列。在运行时,它们会产生 INTEGER_LITERAL 类型的值。INTEGER_LITERAL 可以隐式转换为任意可容纳该值的整数类型。例如,整数字面量 42 可以隐式转换为 TINYINT,但整数字面量 1000 不可以。
Goose 不直接支持十六进制或二进制字面量。不过,带有
0x或0b前缀的十六进制/二进制格式字符串或字符串字面量可以转换为整数类型,例如'0xFF'::INT = 255或0b101::INT = 5。
其他数字字面量
非整数字面量可以使用十进制表示法,通过点号(.)分隔整数部分和小数部分。
整数部分或小数部分都可以省略:
SELECT 1.5; -- 1.5
SELECT .50; -- 0.5
SELECT 2.; -- 2.0
非整数字面量也可以使用 E notation 表示。在 E 表示法中,整数或小数字面量后会跟一个指数部分,指数部分由 e 或 E 引出,并跟随一个表示指数的整数字面量。
指数部分表示前面的数值应乘以 10 的该指数次幂:
SELECT 1e2; -- 100
SELECT 6.02214e23; -- Avogadro's constant
SELECT 1e-10; -- 1 ångström
数字字面量中的下划线
Goose 的 SQL 方言允许在数字字面量中使用下划线 _ 作为可选分隔符。使用规则如下:
- 整数、十进制、十六进制和二进制表示法中都允许使用下划线。
- 下划线不能位于字面量的首尾。
- 下划线两侧都必须是整数/数字部分,也就是说不能连续出现多个下划线,也不能紧邻小数点或指数部分前后。
示例:
SELECT 100_000_000; -- 100000000
SELECT '0xFF_FF'::INTEGER; -- 65535
SELECT 1_2.1_2E0_1; -- 121.2
SELECT '0b0_1_0_1'::INTEGER; -- 5
字符串字面量
字符串字面量使用单引号(')作为定界符,并产生 STRING_LITERAL 值。
注意,双引号(")不能用于字符串定界;双引号用于界定带引号标识符。
隐式字符串字面量拼接
仅由空白字符分隔且空白中至少包含一个换行符的连续单引号字符串字面量,会发生隐式拼接:
SELECT 'Hello'
' '
'World' AS greeting;
等价于:
SELECT 'Hello'
|| ' '
|| 'World' AS greeting;
二者都会返回以下结果:
| greeting |
|---|
| Hello World |
注意,隐式拼接仅在字面量之间至少有一个换行符时生效。若仅以空白分隔而不含换行,使用相邻字符串字面量会导致语法错误:
SELECT 'Hello' ' ' 'World' AS greeting;
Parser Error:
syntax error at or near "' '"
LINE 1: SELECT 'Hello' ' ' 'World' AS greeting;
^
还要注意,隐式拼接只适用于单引号字符串字面量,不适用于其他类型的字符串值。
隐式字符串转换
STRING_LITERAL 实例可以被隐式转换为_任意_其他类型。
例如,我们可以将字符串字面量与日期进行比较:
SELECT d > '1992-01-01' AS result
FROM (VALUES (DATE '1992-01-01')) t(d);
| result |
|---|
| false |
但我们不能将 VARCHAR 值与日期比较。
SELECT d > '1992-01-01'::VARCHAR
FROM (VALUES (DATE '1992-01-01')) t(d);
Binder Error:
Cannot compare values of type DATE and type VARCHAR - an explicit cast is required
转义字符串字面量
要在字符串字面量中转义单引号字符(apostrophe),使用 ''。例如,SELECT '''' AS s 会返回 '。
若要启用一些常见转义序列(例如换行符 \n),请在字符串字面量前加上前缀 e(或 E)。
SELECT e'Hello\nworld' AS msg;
┌──────────────┐
│ msg │
│ varchar │
├──────────────┤
│ Hello\nworld │
└──────────────┘
支持以下反斜杠转义序列:
| Escape sequence | Name | ASCII code |
|---|---|---|
\b | backspace | 8 |
\f | form feed | 12 |
\n | newline | 10 |
\r | carriage return | 13 |
\t | tab | 9 |
Dollar 引号字符串字面量
Goose 支持 Dollar 引号字符串字面量,即使用双美元符号($$)包裹字符串:
SELECT $$Hello
world$$ AS msg;
┌──────────────┐
│ msg │
│ varchar │
├──────────────┤
│ Hello\nworld │
└──────────────┘
SELECT $$The price is $9.95$$ AS msg;
| msg |
|---|
| The price is $9.95 |
此外,你还可以在双美元符号中加入字母数字标签,从而在字符串字面量内部使用普通的双美元符号:
SELECT $tag$ this string can contain newlines,
'single quotes',
"double quotes",
and $$dollar quotes$$ $tag$ AS msg;
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ msg │
│ varchar │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ this string can contain newlines,\n'single quotes',\n"double quotes",\nand $$dollar quotes$$ │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
隐式拼接仅适用于单引号字符串字面量,不适用于 Dollar 引号字符串。