# 38.2.PostgreSQL类型系统

38.2.1. 基本类型

38.2.2. 容器类型

38.2.3. 领域

38.2.4. 伪类型

38.2.5. 多态类型

PostgreSQL数据类型可以分为基本类型、容器类型、域和伪类型。

# 38.2.1.基本类型

基本类型是这样的整数,它们在SQL语言级别以下实现(通常使用C等低级语言)。它们通常对应于通常所说的抽象数据类型。PostgreSQL只能通过用户提供的函数对此类类型进行操作,并且只能在用户描述的范围内理解此类类型的行为。中介绍了内置的基本类型第八章.

枚举(enum)类型可以视为基类型的子类别。主要区别在于,它们可以仅使用SQL命令创建,而无需任何低级编程。提到第8.7节了解更多信息。

# 38.2.2.容器类型

PostgreSQL有三种“容器”类型,它们包含其他类型的多个值。这些是阵列、复合材料和范围。

数组可以包含多个类型相同的值。将为每个基本类型、复合类型、范围类型和域类型自动创建一个数组类型。但是没有数组的数组。就类型系统而言,多维数组与一维数组相同。提到第8.15节了解更多信息。

每当用户创建表时,就会创建复合类型或行类型。也可以使用创建类型定义没有关联表的“独立”复合类型。复合类型只是带有相关字段名的类型列表。复合类型的值是字段值的行或记录。提到第8.16节了解更多信息。

范围类型可以包含同一类型的两个值,即范围的下限和上限。范围类型是用户创建的,尽管存在一些内置类型。提到第8.17节了解更多信息。

# 38.2.3.领域

域基于特定的底层类型,并且在许多情况下可以与其底层类型互换。但是,域可以有一些约束,将其有效值限制为基础类型允许的子集。域是使用SQL命令创建的创建域提到第8.18节了解更多信息。

# 38.2.4.伪类型

有几个“伪类型”用于特殊目的。伪类型不能显示为表的列或容器类型的组件,但它们可以用于声明函数的参数和结果类型。这在类型系统中提供了一种识别特殊函数类的机制。表8.27列出现有的伪类型。

# 38.2.5.多态类型

一些特别感兴趣的伪类型是多态类型的,用于声明多态函数。此强大功能允许单个函数定义对许多不同的数据类型进行操作,具体的数据类型由在特定调用中实际传递给它的数据类型决定。多态类型如所示表38.1.一些使用它们的例子见第38.5.11节.

表38.1.多态类型

名称 家庭 描述
任何元素 易于理解的 指示函数接受任何数据类型
任意数组 易于理解的 指示函数接受任何数组数据类型
安诺纳雷 易于理解的 指示函数接受任何非数组数据类型
任何枚举 易于理解的 指示函数接受任何枚举数据类型(请参见第8.7节)
任意范围 易于理解的 指示函数接受任何范围数据类型(请参阅第8.17节)
任意多量程 易于理解的 指示函数接受任何多范围数据类型(请参见第8.17节)
任何兼容的 常见的 指示函数接受任何数据类型,并自动将多个参数升级为公共数据类型
随便什么 常见的 指示函数接受任何数组数据类型,并自动将多个参数升级为公共数据类型
任何兼容的Narray 常见的 指示函数接受任何非数组数据类型,并自动将多个参数升级为公共数据类型
任何兼容语言 常见的 指示函数接受任何范围数据类型,并自动将多个参数升级为公共数据类型
任意兼容多量程 常见的 指示函数接受任何多范围数据类型,并自动将多个参数升级为公共数据类型

多态参数和结果相互关联,并在解析调用多态函数的查询时解析为特定的数据类型。当存在多个多态参数时,输入值的实际数据类型必须匹配,如下所述。如果函数的结果类型是多态的,或者它有多态类型的输出参数,那么这些结果的类型将从多态输入的实际类型中推导出来,如下所述。

对于多态类型的“简单”系列,匹配和推断规则如下:

每个位置(参数或返回值)声明为任何元素允许有任何特定的实际数据类型,但在任何给定调用中,它们都必须是相同的实际类型。每个职位被宣布为任意数组可以有任何数组数据类型,但同样地,它们必须都是相同的类型。同样,声明为任意范围都必须是相同的范围类型。同样适用于任意多量程.

此外,如果宣布了立场任意数组还有一些人宣称任何元素中的实际数组类型任意数组位置必须是一个数组,其元素的类型与任何元素位置。安诺纳雷被完全等同于任何元素,但添加了一个附加约束,即实际类型不能是数组类型。任何枚举被完全等同于任何元素,但添加了一个附加约束,即实际类型必须是枚举类型。

同样,如果有职位声明任意范围还有一些人宣称任何元素任意数组中的实际范围类型任意范围位置必须是一个范围,其子类型与列表中显示的类型相同任何元素和的元素类型相同任意数组位置。如果有申报的职位任意多量程,它们的实际多范围类型必须包含与声明的参数匹配的范围任意范围以及与声明的参数匹配的基本元素任何元素任意数组.

因此,当使用多态类型声明多个参数位置时,净效果是只允许实际参数类型的某些组合。例如,一个声明为相等(任意元素,任意元素)将接受任意两个输入值,只要它们是相同的数据类型。

当函数的返回值声明为多态类型时,必须至少有一个参数位置也是多态的,并且为多态参数提供的实际数据类型确定该调用的实际结果类型。例如,如果还没有数组订阅机制,可以定义一个函数,将订阅实现为下标(anyarray,integer)返回anyelement。此声明将实际的第一个参数约束为数组类型,并允许解析器从实际的第一个参数的类型推断正确的结果类型。另一个例子是,函数声明为f(anyarray)返回anyenum将只接受枚举类型的数组。

在大多数情况下,解析器可以从同一家族中不同多态类型的参数推断多态结果类型的实际数据类型;例如任意数组可以从任何元素反之亦然。一个例外是类型为的多态结果任意范围需要类型为的参数任意范围; 这不能从任意数组任何元素论据。这是因为同一子类型可能有多个范围类型。

注意安诺纳雷任何枚举不代表单独的类型变量;它们和我的类型一样任何元素,只是有一个额外的限制。例如,将函数声明为f(任意元素,任意枚举)相当于将其声明为f(任意枚举,任意枚举):两个实际参数必须是相同的枚举类型。

对于多态类型的“公共”族,匹配和推断规则的工作原理与“简单”族大致相同,但有一个主要区别:参数的实际类型不必相同,只要它们可以隐式转换为单个公共类型。公共类型的选择遵循与的相同规则协会和相关结构(参见第10.5节).普通类型的选择考虑了任何兼容的任何兼容的Narray输入,数组元素类型随便什么输入,范围子类型任何兼容语言输入,以及任意兼容多量程输入。如果任何兼容的Narray则公共类型必须是非数组类型。一旦确定了一个公共类型,参数就会任何兼容的任何兼容的Narray位置会自动转换为该类型,参数随便什么位置会自动转换为该类型的数组类型。

由于无法选择仅知道其子类型的范围类型,因此使用任何兼容语言和/或任意兼容多量程要求使用该类型声明的所有参数具有相同的实际范围和/或多范围类型,并且该类型的子类型与选定的公共类型一致,因此不需要强制转换范围值。就像任意范围任意多量程,使用任何兼容语言任意多量程作为函数,结果类型要求任何兼容语言任意兼容多量程论点

请注意,没有任何相容物类型这样的类型不会非常有用,因为通常不会对枚举类型进行任何隐式转换,这意味着无法为不同的枚举输入解析公共类型。

“简单”和“常见”多态族代表两组独立的类型变量。例如考虑

CREATE FUNCTION myfunc(a anyelement, b anyelement,
                       c anycompatible, d anycompatible)
RETURNS anycompatible AS ...

在该函数的实际调用中,前两个输入必须具有完全相同的类型。最后两个输入必须可升级为公共类型,但此类型不必与前两个输入的类型有任何关系。结果将具有最后两个输入的公共类型。

一个变量函数(一个参数数目可变的函数,如第38.5.6节)可以是多态的:这是通过将其最后一个参数声明为可变的 任意数组可变的 随便什么.出于参数匹配和确定实际结果类型的目的,此类函数的行为与您编写了适当数量的安诺纳雷任何兼容的Narray参数。