|
4.1.3. 操作符
一个操作符是最多 NAMEDATALEN-1 (缺省 63 个字符)个下列字符的序列:
+ - * / < > = ~ ! @ # % ^ & | ` ?
不过,对操作符名字有几个限制:
- -- 和 /* 不能出现在操作符名字中的任何地方,因为它们会被当做注释开始对待。
- 多字符操作符不能以 + 或 - 结束, 除非其名字至少还包含下列操作符之一:
~ ! @ # % ^ & | ` ?
比如,@- 是允许的操作符名字, 但 *- 不是。这个限制允许 PostgreSQL 在不要求记号之间有空白的情况下分析 SQL 兼容的查询。
当你使用非 SQL 标准的操作符名字的时候,你通常需要用空白分隔相邻的操作符以避免歧义。 比如,如果你定义了一个叫 "@" 的左单目操作符,那么你就不能写 X*@Y;而是要写成 X* @Y 以确保 PostgreSQL 把它读成两个操作符,而不是一个。
4.1.4. 特殊字符
有些非字母数字字符有一些特殊含义,因此不能用做操作符。 它们的用法的细节可以在相应的描述语法元素的地方找到。 本节只是描述它们的存在和概括一下这些字符的目的。
- 美元符号($)后面跟着数字用于在一个函数体定义或者准备好的语句中 表示参数的位置。在其他环境里美元符号可能是一个标识符名字或者是一个美元符包围的字串常量的一部分。
- 圆括弧(())用于分组和强制优先级的时候含义与平常一样。 有些场合里圆括弧是作为一个特定 SQL 命令的固定语法的一部分要求的。
- 方括弧([])用于选取数组元素。 参阅 Section 8.10 获取更多信息。
- 逗号(,在一些语法构造里用于分隔一个列表的元素。
- 分号(;)结束一条 SQL 命令。 它不能出现在一条命令里的任何地方,除非引号包围的来当做字符串常量或者标识符用。
- 冒号 (:)用于从数组中选取"片段"。(参阅 Section 8.10。)在一些 SQL 方言里(比如嵌入 SQL ), 冒号用于前缀变量名。
- 星号 (* 在某些环境里表示一个表行或者一个符合类型值的全部字段。 在用作聚集函数 COUNT 的参数时还有特殊含义。
- 句点 (.用在数字常量里,并用于分隔模式,表和字段名字。
4.1.5. 注释
注释是任意以双划线开头并延伸到行尾的任意字符序列,比如:
-- 这是标准的 SQL92 注释
另外,还可以使用 C-风格的块注释:
/* 多行注释
* 可以嵌套∶/* 嵌套的块注释 */
*/
这里注释以 /* 开头并扩展到对应的 */。这些块注释可以嵌套,就象 SQL99 里说的那样, 但和 C 不一样,因此我们可以注释掉一大块已经包含块注释的代码。
注释在进一步的语法分析之前被从输入流删除并用空白代替。
4.1.6. 词法优先级
Table 4-1 显示了 PostgreSQL 里面的操作符的优先级和关联性。 大多数操作符都有相同的优先级并且都是左关联的。 这种情况可能会有不那么直观的行为;比如,布尔操作符 < 和 > 和布尔操作符 <= 和 >= 之间有着不同的优先级。同样,当你把双目和单目操作符组合使用的时候, 有时候也需要加圆括弧。比如
SELECT 5 ! - 6;
会被分析成
SELECT 5 ! (- 6);
因为分析器不知道 ! 定义成了后缀操作符, 而不是中缀操作符。— 知道的时候只能是太晚了 — 要在本例中获得你需要的特性,你要写成
SELECT (5 !) - 6;
这是我们为扩展性付出的代价。
Table 4-1. 操作符优先级(递减)
操作符/元素
关联性
描述
.
左
表/字段名分隔符
::
左
PostgreSQL-特有的类型转换操作符
[ ]
左
数组元素选则
-
右
单目负号
^
左
幂操作
* / %
左
乘,除,模
+ -
左
加,减
IS
IS TRUE, IS FALSE, IS UNKNOWN, IS NULL
ISNULL
测试是否为空值
NOTNULL
测试是否为非空值
(任何其它的)
左
所有其它的本地和用户定义操作符
IN
集合成员
BETWEEN
范围包含
OVERLAPS
时间间隔重叠
LIKE ILIKE SIMILAR
字符串模式匹配
< >
小于,大于
=
右
等于,赋值
NOT
右
逻辑反
AND
左
逻辑与
OR
左
逻辑或
请注意操作符优先级也适用于和上面提到的同名的内置操作符用户定义操作符。 比如,如果你为一些客户数据类型定义一个 "+" 操作符, 那么它和内置的 "+" 操作符有同样的优先级,不管你干了什么。
如果在 OPERATOR 语法里使用了模式修饰的操作符名, 比如
SELECT 3 OPERATOR(pg_catalog.+) 4;
那么 OPERATOR 构造就会有 Table 4-1 表里面为"任何其它"操作符显示的缺省优先级。 不管什么特定的操作符出现在 OPERATOR()里,都是这样。 |
|
|