pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
PostgreSQL 数据类型可以分为基础类型、复合类型、域和伪类型。
基础类型是在 SQL 语言层之下实现的类型(通常使用 C 等低级语言),例如 int4。它们通常对应于所谓的抽象数据类型。PostgreSQL 只能通过用户提供的函数操作这些类型,对其行为的理解也仅限于用户所描述的内容。基础类型进一步分为标量类型和数组类型。对于每个标量类型,都会自动创建相应的数组类型,以存储由该标量类型组成的可变大小数组。
用户每次创建表时,都会创建复合类型(也称行类型)。还可以使用 CREATE TYPE 定义不关联任何表的“独立”复合类型。复合类型就是一个带有对应字段名的类型列表。复合类型的值是由字段值组成的一行或一条记录。用户可以在 SQL 查询中访问各个组成字段。关于复合类型的更多信息,参见 第 8.15 节。
域基于某一种特定的基础类型,并且在很多场合下都可以与其基础类型互换。不过,域可以带有约束,把其合法值限制在底层基础类型所允许值的一个子集内。
可以使用 SQL 命令 CREATE DOMAIN 创建域。本章不讨论域的创建和使用。
有少数几种“伪类型”用于特殊目的。伪类型不能作为表的列或复合类型的属性出现,但它们可以用来声明函数的参数类型和结果类型。这为在类型系统内部识别特殊类别的函数提供了一种机制。表 8.24 列出了现有的伪类型。
四种特别值得关注的伪类型是 anyelement、anyarray、anynonarray 和 anyenum,它们统称为多态类型。使用这些类型声明的函数称为多态函数。多态函数可以操作多种不同的数据类型,具体的数据类型由特定调用中实际传递给它的数据类型决定。
多态参数和结果相互关联,在解析调用多态函数的查询时,会被解析为某种具体的数据类型 a query calling a polymorphic function is parsed. Each position (either argument or return value) declared as anyelement is allowed to have any specific actual data type, but in any given call they must all be the same actual type. 每个声明为 anyarray 的位置可以具有任意数组数据类型,但同样必须全部具有相同的类型。如果同时有声明为 anyarray 的位置和声明为 anyelement 的位置,anyarray 位置上的实际数组类型必须是一个元素类型与 anyelement 位置上出现的类型相同的数组。 anynonarray 的处理方式与 anyelement 完全相同,但额外要求实际类型不能是数组类型。anyenum 的处理方式也与 anyelement 完全相同,但额外要求实际类型必须是枚举类型。
因此,当多个参数位置被声明为多态类型时,其总体效果就是只允许某些实际 参数类型组合。例如,声明为 equal(anyelement, anyelement) 的函数可以接受任意两 个输入值,只要它们属于同一数据类型。
如果函数的返回值声明为多态类型,那么至少有一个参数位置也必须是多态的,并且实际传入的参数数据类型决定该次调用的实际结果类型。例如,如果尚不存在数组下标机制,可以将实现下标访问的函数定义为 subscript(anyarray, integer) returns anyelement。这一声明将实际的第一个参数约束为数组类型,并允许解析器根据第一个参数的实际类型推导正确的结果类型。另一个例子是,声明为 f(anyarray) returns anyenum 的函数只接受枚举类型的数组。
注意,anynonarray 和 anyenum 并不表示独立 的类型变量;它们与 anyelement 是同一个类型,只是附加了额 外约束。例如,把函数声明为 f(anyelement, anyenum),等价于把它声明为 f(anyenum, anyenum):两个实际参数都必须是同一种枚 举类型。
可变参数函数(接受可变数量参数的函数,见 第 35.4.5 节)可以是多态的:将其最后一个参数声明为 VARIADIC anyarray 即可。就参数匹配和确定实际结果类型而言,这样的函数与写出相应数量的 anynonarray 参数时行为相同。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。