pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
CREATE TYPE — 定义一种新的数据类型
CREATE TYPEtypename( INPUT =input_function, OUTPUT =output_function, INTERNALLENGTH = {internallength| VARIABLE } [ , EXTERNALLENGTH = {externallength| VARIABLE } ] [ , DEFAULT =default] [ , ELEMENT =element] [ , DELIMITER =delimiter] [ , SEND =send_function] [ , RECEIVE =receive_function] [ , PASSEDBYVALUE ] [ , ALIGNMENT =alignment] [ , STORAGE =storage] )
typename要创建的类型的名称。
internallength一个字面值,指定新类型的内部长度。
externallength一个字面值,指定新类型的外部(显示)长度。
input_function一个由 CREATE FUNCTION 创建的函数的名称,它把数据从外部形式转换为该类型的内部形式。
output_function一个由 CREATE FUNCTION 创建的函数的名称,它把数据从内部形式转换为适合显示的形式。
element正在创建的类型是数组;该参数指定数组元素类型。
delimiter在由该类型构成的数组中各值之间使用的分隔符字符。
default该数据类型的默认值。通常省略此项,使默认值为 NULL。
send_function一个由 CREATE FUNCTION 创建的函数的名称,它把该类型的数据转换为适合传输到另一台机器的形式。
receive_function一个由 CREATE FUNCTION 创建的函数的名称,它把该类型的数据从适合从另一台机器传输的形式转换为内部形式。
alignment该数据类型的存储对齐要求。如果指定,必须是 char、int2、 int4 或 double;默认为 int4。
storage该数据类型的存储技术。如果指定,必须是 plain、external、 extended 或 main;默认为 plain。
CREATE类型创建成功时返回的消息。
CREATE TYPE 允许用户向 PostgreSQL 注册一种新的用户数据类型,供当前数据库使用。定义类型的用户将成为其所有者。 typename 是新类型的名称,在该数据库已定义的类型中必须唯一。
CREATE TYPE 要求在定义类型之前(用 CREATE FUNCTION)先注册两个函数。新基本类型的表示由 input_function 决定,它把该类型的外部表示转换为为该类型定义的操作符和函数可用的内部表示。自然, output_function 执行反向的转换。输入函数可以声明为接受一个 opaque 类型的参数,或者接受 opaque、OID、int4 三个类型的参数。(第一个参数是作为 C 字符串的输入文本,第二个参数是数组类型情况下的元素类型,第三个是目标列的 typmod(如果已知)。)输出函数可以声明为接受一个 opaque 类型的参数,或者接受 opaque、OID 两个类型的参数。(第一个参数实际上就是该数据类型本身,但由于输出函数必须先声明,把它声明为接受 opaque 类型更容易。第二个参数同样是数组类型时的数组元素类型。)
新的基本数据类型可以是定长的,这时 internallength 是一个正整数;也可以是变长的,通过把 internallength 设为 VARIABLE 来表示。(在内部,这通过把 typlen 设为 -1 来表示。)所有变长类型的内部表示都必须以一个给出该类型该值总长度的整数开头。
外部表示的长度用 externallength 关键字以类似的方式指定。(这个值目前未被使用,通常省略,让它默认为 VARIABLE。)
要指明一个类型是数组,可以用 ELEMENT 关键字指定数组元素的类型。例如,要定义一个 4 字节整数("int4")的数组,指定
ELEMENT = int4
关于数组类型的更多细节见下文。
要指明该类型数组的外部表示中值与值之间使用的分隔符,可以把 delimiter 设为某个特定的字符。默认分隔符是逗号(',')。注意,分隔符与数组元素类型相关联,而不是与数组类型本身。
如果用户希望该数据类型的列默认为 NULL 以外的值,可以指定一个默认值。用 DEFAULT 关键字指定默认值。(这样的默认值可以被附加在特定列上的显式 DEFAULT 子句覆盖。)
可选参数 send_function 和 receive_function 目前未被使用,通常省略(让它们分别默认为 output_function 和 input_function)。这两个函数将来可能会恢复用于指定与机器无关的二进制表示。
可选标志 PASSEDBYVALUE 表示该数据类型的值按值传递而不是按引用传递。注意,内部表示比 Datum 类型宽度(多数机器上 4 字节,少数机器上 8 字节)更长的类型不能按值传递。
alignment 关键字指定该数据类型所需的存储对齐。允许的取值分别相当于按 1、2、4 或 8 字节边界对齐。注意,变长类型的对齐至少必须是 4,因为它们必然以一个 int4 作为第一个成分。
storage 关键字允许为变长数据类型选择存储策略(定长类型只允许 plain)。 plain 对该数据类型禁用 TOAST:它总是内联存储且不压缩。 extended 提供完整的 TOAST 能力:系统会先尝试压缩较长的数据值,如果仍然太长,就把该值移出主表行。 external 允许把值移出主表,但系统不会尝试压缩它。 main 允许压缩,但不鼓励把值移出主表。(采用这种存储方法的数据项在实在没有其他办法让行放得下时仍可能被移出主表,但相比 extended 和 external 的数据项,它们会被优先保留在主表中。)
每当创建用户定义的数据类型时, PostgreSQL 都会自动创建一个关联的数组类型,其名称由基础类型名前加一个下划线组成。解析器理解这一命名约定,会把对 foo[]类型列的请求转换为对 _foo类型的请求。这种隐式创建的数组类型是变长的,并使用内置的输入和输出函数 array_in 和 array_out。
如果系统会自动创建正确的数组类型,你可能会合理地问“为什么还需要 ELEMENT 选项?”ELEMENT唯一有用的情况是:你正在创建一种定长类型,而它在内部恰好是 N 个相同元素组成的数组,并且除了为整个类型计划提供的操作之外,你还希望允许通过下标直接访问这 N 个元素。 例如,类型name 就允许用这种方式访问其组成元素char。一个二维的 point类型可以允许像point[0]和point[1]这样访问它的两个分量浮点数。注意,这一机制只对内部形式恰好是 N 个相同字段序列的定长类型有效。可下标访问的变长类型必须使用 array_in和array_out所使用的广义内部表示。 由于历史原因(也就是说,这显然是错的,但要改已经太迟了),定长数组类型的下标从零开始,而不像变长数组那样从一开始。
用户定义的类型名不能以下划线字符(“_”)开头,且长度只能是 30 个字符(或者一般来说是 NAMEDATALEN-2,而不是其他名称允许的 NAMEDATALEN-1 个字符)。以下划线开头的类型名保留给内部创建的数组类型名使用。
这个示例创建 box 数据类型,然后在表定义中使用该类型:
CREATE TYPE box (INTERNALLENGTH = 16,
INPUT = my_procedure_1, OUTPUT = my_procedure_2);
CREATE TABLE myboxes (id INT4, description box);
如果 box 的内部结构是四个 float4 组成的数组,我们也可以改成这样写:
CREATE TYPE box (INTERNALLENGTH = 16,
INPUT = my_procedure_1, OUTPUT = my_procedure_2,
ELEMENT = float4);
这样就允许通过下标访问 box 值的各分量浮点数。除此之外该类型的行为与之前完全相同。
这个示例创建一种大对象类型,并在表定义中使用它:
CREATE TYPE bigobj (INPUT = lo_filein, OUTPUT = lo_fileout,
INTERNALLENGTH = VARIABLE);
CREATE TABLE big_objs (id int4, obj bigobj);
这个 CREATE TYPE 命令是 PostgreSQL 的扩展。SQL99 中也有一个 CREATE TYPE 语句,但在细节上大不相同。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。