CREATE CAST

Name

CREATE CAST -- 定义一个用户定义的转换

Synopsis

CREATE CAST (sourcetype AS targettype)
    WITH FUNCTION funcname (argtype)
    [ AS ASSIGNMENT | AS IMPLICIT ]

CREATE CAST (sourcetype AS targettype)
    WITHOUT FUNCTION
    [ AS ASSIGNMENT | AS IMPLICIT ]

描述

CREATE CAST 定义一个新的转换。 一个转换说明如何在两个类型之间进行转换。比如:

SELECT CAST(42 AS text);

通过调用前面声明的一个函数,把整数常量 42 转换成类型 text, 在这个例子李是 text(int4)。(如果没有预先定义好合适的转换, 那么这个转换失败。)

两种类型可以是二进制兼容的, 意思是它们之间可以"自由转换"而不用调用任何函数。 这就需要那个对应的数值使用同样的内部表现形式。 比如,类型 textvarchar 是二进制兼容的。

缺省时,只有在明确要求转换的情况下才调用一个转换, 也就是一个明确的 CAST(x AS typename)x::typename,或者 typename(x) 构造。

如果转换标记为 AS ASSIGNMENT,那么在赋予目标数据类型的 字段的时候,可以隐含调用它。比如,假设 foo.f1 是 一个类型为 text 的字段,那么

INSERT INTO foo(f1) VALUES(42);

如果从类型 integer 到类型 text 的转换 标记为 AS ASSIGNMENT,上面的这句就被允许,否则就不 允许。(我们通常用术语赋值转换来描述这种转换。)

如果转换标记为 AS IMPLICIT,那么它就可以在任何环境里 调用,不管是赋值还是在表达式的内部。比如,因为 || 接受 text参数,

SELECT 'The time is ' || now();

将只有在类型 timestamptext 的转换标记为 AS IMPLICIT 的时候才允许。否则我们就必须明确书写转换, 比如

SELECT 'The time is ' || CAST(now() AS text);

(我们通常使用术语隐含转换来描述这种类型的转换。)

在标记转换为隐含的这个问题上保守一些是明智的。 过于丰富的隐含转换路径会导致 PostgreSQL 选择 让人奇怪的命令的解释,或者是完全不能解析命令,因为存在多个可能的解释。 一条好的拇指定律是,只有在同一个通用类型表里面的那些可以保留转换信息的 类型之间才标记为可隐含调用转换。比如,从 int2int4 可以合理地标记为隐含转换,但是从 float8int4 可能应该是标记为赋值转换。夸类型表地转换,比如 textint4,最好是只能明确地转换。

要想创建一个转换,你必须拥有源或者目的数据类型。要创建一个二进制 兼容的转换,你必须是超级用户(做这个限制是因为一种有问题的二进制 兼容转换可以很容易摧毁服务器)。

参数

sourcetype

转换的源数据类型。

targettype

转换的目标数据类型。

funcname(argtype)

用于执行转换的函数。这个函数名可以是用模式名修饰的。 如果它没有用模式名修饰,那么该函数将从路径中找出来。 参数类型必须和源数据类型相同,结果数据类型必须匹配 转换的目标类型。转换函数必须标记为不变的或者稳定的。

WITHOUT FUNCTION

表示源数据类型和目标数据类型是二进制兼容的, 所以不需要什么函数来执行转换。

AS ASSIGNMENT

表示转换可以在赋值环境里隐含调用。

AS IMPLICIT

表示这个转换可以在任何环境里隐含调用。

注意

DROP CAST 删除用户定义的转换。

请注意,如果你想能双向转换类型,那么你需要明确地定义两个方向 的转换。

PostgreSQL 7.3 之前,如果一个函数的名字 和一个数据类型相同,并且返回该种数据类型,而且还接受另外一种 类型的参数自动就是一个转换函数。这个传统随着模式的引入以及 为了能在系统表种表示二进制兼容的转换就被废弃了。 (内置的转换函数仍然遵循这个命名规则,但是它们现在必须在 pg_cast 里显示为转换。)

例子

要使用函数 int4(text) 创建一个从类型 text 到类型 int4的转换:

CREATE CAST (text AS int4) WITH FUNCTION int4(text);

(这个转换在系统中已经预先定义了。)

兼容性

CREATE CAST 命令遵循 SQL99,只不过 SQL99 没有提供二进制兼容类型。AS IMPLICIT 也是 PostgreSQL 的扩展。

又见

CREATE FUNCTION, CREATE TYPE, DROP CAST, PostgreSQL 程序员手册