COLLATE
运算符的优先级是什么?例如,在以下内容中:
SELECT 'a' || 'B' COLLATE someting
我相信在这种特殊情况下它被解释为:
SELECT 'a' || ('B' COLLATE something)
但是是否有关于
COLLATE
关键字所在位置的确切规则列表?该部分是否写着“所有其他运营商”?
一如既往,PostgreSQL 文档提供:
子句比运算符绑定更紧密;必要时可以使用括号。COLLATE
我发现 PostgreSQL 运算符优先级文档 令人沮丧地缺乏。虽然 SQL 语法文档 确实指出:
COLLATE 子句比运算符绑定更紧密
这是不正确的。
PostgreSQL 文档将
.
、::
和 []
列为运算符优先级表中的运算符,它们的绑定比 COLLATE
更强,如以下不会导致错误的表达式所示:
SELECT foo.bar COLLATE "POSIX" FROM foo;
SELECT 'Hello' :: VARCHAR COLLATE "POSIX";
SELECT t.arr[1] COLLATE "C" FROM (SELECT ARRAY['Hello'] AS arr) t;
同时,“任何其他运算符”类别中的运算符的绑定比
COLLATE
更松散。例如,有问题的 ||
运算符:
SELECT 2 || 'Hello' COLLATE "C"; -- works fine
SELECT 'Hello' || 2 COLLATE "C"; -- throws error
它的绑定也比
AT TIME ZONE
运算符(未在运算符优先级表中列出的另一个运算符)更强。如下代码所示:
SELECT TIME '12:30' AT TIME ZONE 'UTC' COLLATE "C"; -- works fine
SELECT TIME '12:30' COLLATE "C"; -- throws error
我通过实验确定
AT TIME ZONE
的结合力比一元 +
/-
的结合力更强,而比幂运算 (^
) 的结合力更弱。
COLLATE
运算符的结合力也比一元+
/-
:更强
-- throws error: collations are not supported by type double precision
SELECT +'2' COLLATE "C";
我在此提出修改后的 PostgreSQL 运算符优先级表:
.
(表/列名称分隔符)::
(类型转换)[]
(数组访问器)+
-
~
(一元加、减、按位求反)COLLATE
AT TIME ZONE
^
(求幂)*
/
%
(乘法、除法、取模)+
-
(加法、减法)||
、>>
、|/
、#
)BETWEEN
IN
LIKE
ILIKE
SIMILAR
<
>
=
<=
>=
<>
!=
(比较)IS
ISNULL
NOTNULL
IS DISTINCT FROM
等等NOT
AND
OR