伪类型

伪类型

Greenplum 数据库支持一个特殊目的数据类型集合,叫做 伪类型. 一个伪类型不能被用作列数据类型, 但是可以用来声明一个函数的参数或返回值. 当一个函数的行为并不是简单获取或者返回一个特定 SQL 数据类型值的时候,这些伪类型非常有用.

过程语言实现的函数只能使用实现语言中支持的伪类型. 过程与语言全都禁止使用伪类型作为参数类型,仅仅允许 voidrecord 作为返回类型.

一个使用 record 伪类型作为返回数据类型的函数返回一个待定的行数据类型. record 表示可能的匿名复合类型数组. 由于复合数据带有自己的类型标识, 因此不需要额外的数组级信息.

伪类型 void 表示一个函数不返回值.

Note: Greenplum 数据库不支持触发器和 trigger 伪类型.

另外, anyelement, anyarray, anynonarray, 和 anyenum 几个伪类型被称为多态类型. 一些过程语言也支持多态函数使用 anyarray, anyelement, anyenum, 和 anynonarray 函数.

anytable 伪类型是一个 Greenplum 数据库类型, 表示一个二维表表达式 — 评估为一张二维表的表达式. Greenplum 数据库只允许这个类型作为用户定义函数的参数. 参见 二维表表达式 了解更多关于 anytable 伪类型信息.

更多关于伪类型的介绍, 查看 PostgreSQL 文档中 关于 伪数据类型.

多态类型

四种特殊目的的数据类型: anyelement, anyarray, anynonarray, 和 anyenum, 被称作 多态 类型. 任何使用这些类型的函数被称做多态函数. 通过在运行时检查实际传递的数据,一个多态函数可以操作许多不同的数据类型.

多态参数和返回值互相关联,当查询调用一个多态函数的时候,真实类型才被决定。每个位置 (或者参数或者返回值) 声明为 anyelement 类型时,允许有任何特定的实际类型, 但是,任何调用中,必须是同一种真实数据类型. 每个位置声明为 anyarray 允许有任何类型的数组, 但同样的,(在一个特定查询中,)必须是同一种数据类型. 如果有位置声明为 anyarray 同时别的位置声明为 anyelement, 在 anyarray 位置中的实际数组类型的元素必须与 anyelement 位置 中的类型相同. anynonarrayanyelement 类型同样对待, 但是包含附加的约束就是,实际类型不能是数组类型. anyenum 被当作 anyelement 同样对待, 但是实际类型必须是 enum 类型.

当超过一个参数位置声明为多态类型,最终效果是只允许仅有特定的实际参数组合. 举例说, 函数声明为 equal( anyelement, anyelement ) 则这个函数接受两个输入值,并且他们是同样的数据类型就可以.

当一个函数的返回值声明为多态类型时, 必须有一个参数位置也声明为多态类型, 并且实际参数的数据类型决定调用的实际返回值类型. 举例说, 如果还没有数组订阅机制,你可以像这样定义一个函数实现订阅: subscript( anyarray, integer) returns anyelement . 这里声明约束第一个参数必须是数组类型, 并且允许解析器根据第一个实际参数类型, 推断新的正确的返回值类型. 另一个例子是一个函数声明为 myfunc( anyarray ) returns anyenum 则只能接受一个 enum 类型数组(作为参数).

注意: anynonarrayanyenum 不表示单个类型变量; 可以用 anyelement, 只是带一点附加约束. 例如, 声明函数为 myfunc( anyelement, anyenum ) 与声明为 myfunc( anyenum, anyenum ) 是一样的: 两者的实际参数都必须是同样的 enum 类型.

一个可变参数函数 (接收可变数目参数) 中,如果最后的参数声明为 VARIADIC anyarray , 就是多态的. 为了匹配和决定实际参数类型, 这样的函数与你生命合适数量的 anynonarray 参数的函数一样.

了解更多多态类型信息, 参见 PostgreSQL 文档关于 多态参数和返回值.

二维表表达式

当用 anytable 伪类型声明了一个函数参数, 这就是一个二维表表达式. 一个二维表表达式的写法是把 SELECT 语句放在一个 TABLE() 函数中. 你可以通过添加这样的语句来指定表的分布规则: SCATTER RANDOMLY, 或者 SCATTER BY 子句以及列列表指定分布键.

SELECT 语句在函数被调用时执行, 结果集被分布到 segments 节点中, 因此每一个 segment 节点在一部分结果表上执行函数.

举例说, 下面这个表表达式从一个叫做 customer 的表中选了三列,并将分布键设置为第一列:

TABLE(SELECT cust_key, name, address FROM customer SCATTER BY 1)

SELECT 语句可以包括连接多个基础表, WHERE 语句, 聚集, 以及任何有效的查询语法.

对于 C 或 C++ 语言实现的函数, anytable 类型 是唯一允许的(多态)类型. 函数体可以用 Greenplum 数据库服务器编程接口 (SPI) 或者 Greenplum 伙伴连接器接口 (GPPC) API 访问.