CREATE CAST

CREATE CAST

定义一种新的造型。

概要

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 (sourcetype AS targettype)
       WITH INOUT
       [AS ASSIGNMENT | AS IMPLICIT]

描述

CREATE CAST定义一个新的造型。 造型指定如何在两种数据类型之间执行转换。例如,

SELECT CAST(42 AS float8);

通过调用先前指定的函数(在本例中为float8(int4))将整数常量42转换为float8类型。 如果未定义合适的造型,则转换将失败。

两种类型可以是二进制强制的,这意味着可以在不调用任何功能的情况下将这些类型相互转换。 这要求相应的值使用相同的内部表示形式。 例如,类型textvarchar在两个方向上都是二进制可强制的。 二进制强制性不一定是对称关系。 例如,在本实现中,可以无代价执行从xmltext的转换,但是相反的方向需要至少执行语法检查的函数。 (两种都可以二进制强制的类型也称为二进制兼容。)

您可以使用WITH INOUT语法将转换定义为I/O转换造型。 通过调用源数据类型的输出函数并将结果字符串传递给目标数据类型的输入函数来执行I/O转换造型。 在许多常见情况下,此功能无需编写单独的造型函数即可进行转换。 I/O转换造型与基于常规函数的造型相同;只是实现不同。

默认情况下,只能由显式造型请求调用造型, 该请求是显式CAST(x AS typename)x:: typename构造。

如果造型标记为AS ASSIGNMENT, 则在为目标数据类型的列分配值时可以隐式调用它。 例如,假设foo.f1text类型的列,则:

INSERT INTO foo (f1) VALUES (42);

如果从integer类型到text类型的造型标记为AS ASSIGNMENT,则将被允许,否则被禁止。 术语分配转换通常用于描述这种转换。

如果造型标记为AS IMPLICIT,则可以在任何上下文中隐式调用它,无论是赋值还是在表达式内部。 术语隐式造型通常用于描述这种造型。 例如,考虑以下查询:

SELECT 2 + 4.0;

解析器最初将常量标记为integernumeric。 系统catalog中没有integer + numeric运算符,但是有numeric + numeric运算符。 如果存在从integernumeric的造型(确实存在)并且标记为AS IMPLICIT(实际上是),则此查询成功。 解析器仅应用隐式造型,并按以下方式解析查询:

SELECT CAST ( 2 AS numeric ) + 4.0;

catalog还提供了从numericinteger的转换。 如果该类型转换被标记为AS IMPLICIT(实际不是), 则解析器将面临在上述解释与将numeric常量转换为integer并应用integer + integer运算符的选择之间进行选择的选择。 缺乏对选择哪种选择的了解,解析器将放弃并声明模糊查询。 这两个造型中只有一个是隐式的,这是我们教导解析器将混合的numericinteger表达式解析为numeric的方式。 解析器对此没有内置的知识。

保守地将造型标记为隐式是明智的。 过多的隐式转换路径可能会使Greenplum数据库选择令人惊讶的命令解释, 或者因为存在多种可能的解释而根本无法解析命令。 一个好的经验法则是,仅对于同一通用类型类别中的类型之间的信息保留转换,隐式调用造型。 例如,从int2int4的造型可以合理地是隐式的, 但是从float8int4的造型应该仅是赋值的。 跨类型类别的造型(例如,textint4)最好设为显式。

Note: 有时,出于可用性或符合标准的原因, 有必要在一组类型之间提供多个隐式造型,从而导致如上所述的无法避免的歧义。 解析器使用基于类型类别和首选类型的后备启发式方法,有助于在这种情况下提供所需的行为。 有关更多信息,请参见CREATE TYPE

为了能够创建造型,您必须拥有源或目标数据类型,并对其他类型具有USAGE特权。 要创建二进制造型,您必须是超级用户。 (之所以做出此限制,是因为错误的二进制可强制造型转换很容易使服务器崩溃。)

参数

sourcetype
造型的源数据类型的名称。
targettype
造型的目标数据类型的名称。
funcname(argtype [, ...])
用于执行造型的函数。 函数名称可以是模式限定的。 如果不是,Greenplum数据库将在模式搜索路径中查找该函数。 函数的结果数据类型必须与造型的目标类型匹配。
造型实现函数可能具有一到三个参数。 第一个参数类型必须与造型的源类型相同或可以从二进制强制转换。 第二个参数(如果存在)必须为integer类型; 它接收与目标类型关联的类型修饰符;如果没有,则返回-1。 第三个参数(如果存在)必须为boolean类型。 如果造型是显式造型,则为true;否则为false。 在某些情况下,SQL规范要求对显式和隐式造型使用不同的行为。 为必须实现此类造型的函数提供此参数。 不建议您以此方式设计自己的数据类型。
造型函数的返回类型必须与造型的目标类型相同或二进制强制。
通常,造型必须具有不同的源和目标数据类型。 但是,如果它具有一个使用多个参数的造型实现,则可以声明具有相同源类型和目标类型的造型。 它用于表示系统catalog中特定于类型的长度强制函数。 命名函数用于将类型的值强制为由其第二个参数给出的类型修饰符值。
当造型具有不同的源类型和目标类型以及一个函数使用多个参数时, 造型将从一种类型转换为另一种类型,并在一个步骤中施加长度强制。 如果没有此类条目,则强制使用类型修饰符的类型涉及两个步骤, 一个步骤在数据类型之间进行转换,第二个步骤应用该修饰符。
域类型的造型当前无效。 向域或从域进行强制转换使用与其基础类型关联的造型。
WITHOUT FUNCTION
指示源类型对目标类型是二进制强制的,因此不需要任何函数即可执行造型。
WITH INOUT
指示造型是I/O转换造型,通过调用源数据类型的输出函数并将结果字符串传递给目标数据类型的输入函数来执行。
AS ASSIGNMENT
指示造型可以在分配上下文中隐式调用。
AS IMPLICIT
指示在任何上下文中都可以隐式调用造型。

注解

请注意,在此版本的Greenplum数据库中,必须将用户定义的造型中使用的用户定义的函数定义为IMMUTABLE。 用于自定义函数的所有已编译代码(共享库文件)必须放在Greenplum数据库阵列(master和所有segment)中每个主机的相同位置。 此位置也必须位于LD_LIBRARY_PATH中,以便服务器可以找到文件。

请记住,如果您希望能够以两种方式转换类型,则需要显式地声明两种类型的造型。

通常不必在用户定义的类型和标准字符串类型(textvarcharchar(n)以及定义为字符串类别的用户定义的类型)之间创建造型。 Greenplum数据库为此提供了自动的I/O转换造型。 字符串类型的自动造型被视为赋值强制造型,而字符串类型的自动造型仅是显式的。 您可以通过声明自己的造型来替换自动造型来覆盖此行为, 但是通常这样做的唯一原因是,如果您希望转换比标准分配或仅显式设置更容易调用。 另一个可能的原因是,您希望转换的行为不同于类型的I/O函数 - 在执行此操作之前请三思。 (少数内置类型的确确实具有不同的转换行为,主要是由于SQL标准的要求。)

建议您在目标数据类型之后遵循命名造型实现函数的约定,因为已命名内置造型实现函数。 许多用户习惯于使用函数样式表示法(即typename(x))来转换数据类型。

在两种情况下,函数调用构造被视为转换请求,而没有将其与实际函数匹配。 如果函数调用name(x)与现有函数不完全匹配,但是name是数据类型的名称, 并且pg_cast提供了从x类型到该类型的二进制强制转换,则该调用将被解释为二进制强制转换。 Greenplum数据库例外,因此即使缺少任何函数,也可以使用函数语法调用二进制强制转换。 同样,如果没有pg_cast条目,但强制类型转换为字符串类型或从字符串类型强制类型转换, 则该调用将被解释为I/O转换造型。 此异常允许使用函数语法调用I/O转换造型。

上述异常是一个例外:不能使用函数语法调用从复合类型到字符串类型的I/O转换造型, 而必须使用显式的转换语法(CAST或::表示法)编写。 之所以存在该异常,是因为在引入自动提供的I/O转换造型后, 当您打算使用函数或列引用时,发现很容易意外调用此类造型。

示例

要使用函数int4(bigint)创建从类型bigint到类型int4的赋值造型 (此造型已在系统中预先定义):

CREATE CAST (bigint AS int4) WITH FUNCTION int4(bigint) AS ASSIGNMENT;

参数

CREATE CAST命令符合SQL标准,但SQL不为二进制可强制类型或实现函数的额外参数提供准备。 AS IMPLICIT也是Greenplum数据库扩展。