PostgreSQL - CAST vs :: LATERAL 表函数上的运算符

geo*_*lot 5 postgresql type-conversion cast operator

虽然我可以

SELECT elem[1], elem[2]
FROM   ( VALUES ('1,2'::TEXT) ) AS q(arr),
       LATERAL CAST(String_To_Array(q.arr, ',') AS INT[]) AS elem
;
Run Code Online (Sandbox Code Playgroud)

使用显式调用CAST,我不能

SELECT elem[1], elem[2]
FROM   ( VALUES ('1,2'::TEXT) ) AS q(arr),
       LATERAL String_To_Array(q.arr, ',')::INT[] AS elem
;
Run Code Online (Sandbox Code Playgroud)

使用隐式调用::运算符:

错误:“::”处或附近的语法错误

另一个CAST需要显式的位置:

CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
Run Code Online (Sandbox Code Playgroud)

我怀疑是否存在句法原因,例如使用额外的括号 - 这在这里是不正确的。

此时是否只需要显式函数调用作为低级实现的一部分?或者它是否遵循任何语言规则?

Lau*_*lbe 5

是的,这有点奇怪,但是语法只会接受在语法上类似于函数 in-FROM 表达式中的函数调用的东西。

因此,如果您想在FROM子句中使用任意表达式,这确实是一个可以使用的技巧:用不必要的CAST表达式将其括起来。

在这样的上下文中,PostgreSQL 很乐意将任何看起来像函数的东西视为表函数。


Erw*_*ter 5

优秀的角落案例示例。这两种语法变体都是“显式类型转换”,作用完全相同。碰巧的是,SQL 代码中的某些特殊位置只允许使用功能符号来避免歧义。

至于你的第二个观察:

另一个CAST需要显式的位置:

CREATE INDEX ON ... ( CAST(<straw> AS <gold>) );
Run Code Online (Sandbox Code Playgroud)

实际上可以在此处使用速记语法 - 附加一组括号以使其明确:

CREATE INDEX ON ... ((<straw>::<gold>));
Run Code Online (Sandbox Code Playgroud)

db<>在这里摆弄

并且任一语法变体也与查询中的另一个表达式匹配。看:

(有更有效的方法来做你的第一个例子所做的事情,但这可能不是重点。)