关于 YMatrix
标准集群部署
数据写入
数据迁移
数据查询
运维监控
参考指南
工具指南
数据类型
存储引擎
执行引擎
流计算引擎
灾难恢复
系统配置参数
索引
扩展
SQL 参考
常见问题(FAQ)
定义一个新的聚集函数。
CREATE [ OR REPLACE ] AGGREGATE <name> ( [ <argmode> ] [ <argname> ] <arg_data_type> [ , ... ] ) (
SFUNC = <sfunc>,
STYPE = <state_data_type>
[ , SSPACE = <state_data_size> ]
[ , FINALFUNC = <ffunc> ]
[ , FINALFUNC_EXTRA ]
[ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
[ , COMBINEFUNC = <combinefunc> ]
[ , SERIALFUNC = <serialfunc> ]
[ , DESERIALFUNC = <deserialfunc> ]
[ , INITCOND = <initial_condition> ]
[ , MSFUNC = <msfunc> ]
[ , MINVFUNC = <minvfunc> ]
[ , MSTYPE = <mstate_data_type> ]
[ , MSSPACE = <mstate_data_size> ]
[ , MFINALFUNC = <mffunc> ]
[ , MFINALFUNC_EXTRA ]
[ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
[ , MINITCOND = <minitial_condition> ]
[ , SORTOP = <sort_operator> ]
[ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
[ , REPSAFE = <boolean> ]
)
CREATE [ OR REPLACE ] AGGREGATE <name> ( [ [ <argmode> ] [ <argname> ] <arg_data_type> [ , ... ] ]
ORDER BY [ <argmode> ] [ <argname> ] <arg_data_type> [ , ... ] ) (
SFUNC = <sfunc>,
STYPE = <state_data_type>
[ , SSPACE = <state_data_size> ]
[ , FINALFUNC = <ffunc> ]
[ , FINALFUNC_EXTRA ]
[ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
[ , COMBINEFUNC = <combinefunc> ]
[ , INITCOND = <initial_condition> ]
[ , PARALLEL = { SAFE | RESTRICTED | UNSAFE } ]
[ , REPSAFE = <boolean> ]
[ , HYPOTHETICAL ]
)
or the old syntax
CREATE [ OR REPLACE ] AGGREGATE <name> (
BASETYPE = <base_type>,
SFUNC = <sfunc>,
STYPE = <state_data_type>
[ , SSPACE = <state_data_size> ]
[ , FINALFUNC = <ffunc> ]
[ , FINALFUNC_EXTRA ]
[ , FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
[ , COMBINEFUNC = <combinefunc> ]
[ , SERIALFUNC = <serialfunc> ]
[ , DESERIALFUNC = <deserialfunc> ]
[ , INITCOND = <initial_condition> ]
[ , MSFUNC = <msfunc> ]
[ , MINVFUNC = <minvfunc> ]
[ , MSTYPE = <mstate_data_type> ]
[ , MSSPACE = <mstate_data_size> ]
[ , MFINALFUNC = <mffunc> ]
[ , MFINALFUNC_EXTRA ]
[ , MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE } ]
[ , MINITCOND = <minitial_condition> ]
[ , SORTOP = <sort_operator> ]
[ , REPSAFE = <boolean> ]
)
CREATE AGGREGATE 定义一个新的聚合函数。CREATE OR REPLACE AGGREGATE 将定义新聚合函数或替换现有定义。数据库中已提供若干基本常用聚合函数,如 count()、min()、max()、sum()、avg() 等。若需定义新类型或使用未提供的聚合函数,可通过 CREATE AGGREGATE 实现所需功能。
替换现有定义时,参数类型、结果类型及直接参数数量均不得更改。此外,新定义必须与旧定义属于相同类型(普通聚合函数、有序集聚合函数或假设集聚合函数)。
若指定模式名称(例如 CREATE AGGREGATE myschema.myagg ...),则聚合函数将创建于指定模式中;否则默认创建于当前模式。
聚合函数通过其名称和输入数据类型进行标识。同一模式中两个聚合函数若操作不同输入类型,可使用相同名称。聚合函数的名称和输入数据类型还必须与同一模式中所有普通函数的名称及输入数据类型保持唯一性。此行为与普通函数名称重载规则完全一致。参见CREATE FUNCTION。
简单聚合函数由一个或两个普通函数构成:状态转换函数sfunc和可选的最终计算函数ffunc。
这些函数的使用方式如下:
sfunc( internal-state, next-data-values ) ---> next-internal-state
ffunc( internal-state ) ---> aggregate-value
数据库创建一个数据类型为state_data_type的临时变量,用于存储聚合函数的当前内部状态。在处理每行输入数据时,会计算聚合函数的参数值,并调用状态转换函数——该函数以当前状态值和新参数值为参数,计算出新的内部状态值。当所有行数据处理完毕后,最终函数将被调用一次以计算聚合函数的返回值。若未定义最终函数,则直接返回结束状态值。
聚合函数可提供初始条件,即内部状态值的初始值。该值以文本类型存储于数据库中,但必须是状态值数据类型常量的有效外部表示形式。若未提供初始值,则状态值初始化为空。
若状态转换函数声明为STRICT类型,则不能使用空值作为输入参数调用该函数。在此类转换函数下,聚合执行行为如下:包含任何空值输入的行将被忽略(函数不被调用,且保留前一状态值)。若初始状态值为空,则在首个所有输入值均非空的行处,首个参数值将替换状态值,此后所有输入值非空的行均会调用该转换函数。此特性适用于实现max()等聚合函数。需注意:该行为仅在state_data_type与第一个arg_data_type类型相同时生效。当类型不一致时,必须提供非空初始条件或使用非严格转换函数。
如果状态转换函数未声明为STRICT,则它将在每个输入行处无条件调用,并必须自行处理空值输入和空值状态。这使得聚合函数的作者能够完全掌控聚合函数对空值的处理方式。
如果最终函数声明为STRICT类型,则当结束状态值为空时不会调用该函数,而是自动返回空结果(这是STRICT函数的常规行为)。无论如何,最终函数均可选择返回空值。例如,当avg()函数检测到输入行数为零时,其最终函数会返回空值。
有时将最终函数声明为不仅接受状态值,还接受与聚合输入值对应的额外参数会很有用。这样做的主要原因是:当最终函数具有多态性时,状态值的数据类型可能不足以确定结果类型。这些额外参数始终以NULL形式传递(因此当使用FINALFUNC_EXTRA选项时,最终函数必须避免使用strict修饰),但它们仍是有效的参数。最终函数可通过调用get_fn_expr_argtype等方法,识别当前调用中的实际参数类型。
聚合函数可选地支持移动聚合模式,具体说明详见PostgreSQL文档中的移动聚合模式。这需要指定MSFUNC、MINVFUNC和MSTYPE函数,并可选地指定MSSPACE、MFINALFUNC、MFINALFUNC_EXTRA、MFINALFUNC_MODIFY和MINITCOND函数。除MINVFUNC外,这些函数的工作方式与不带M的对应简单聚合函数相同;它们定义了包含逆转换函数的独立聚合实现。
在参数列表中使用ORDER BY的语法会创建一种称为有序集合聚合的特殊聚合类型;若指定HYPOTHETICAL,则创建假设集合聚合。这些聚合以依赖顺序的方式对排序值组进行操作,因此指定输入排序顺序是调用的关键部分。此外,它们可包含直接参数——这类参数仅在每次聚合时评估一次,而非针对每行输入单独计算。假设集合聚合是有序集合聚合的子类,其中部分直接参数在数量和数据类型上必须与聚合参数列匹配。这使得这些直接参数的值能作为额外的"假设"行添加到聚合输入行集合中。
聚合函数可选地支持部分聚合。这需要指定COMBINEFUNC参数。若state_data_type为内部类型,通常还需提供SERIALFUNC和DESERIALFUNC参数以实现并行聚合。请注意,聚合函数还必须标记为PARALLEL SAFE才能启用并行聚合。
行为类似于 min() 或 max() 的聚合函数有时可通过查询索引而非扫描每行输入数据来优化。若该聚合函数可进行此类优化,请通过指定排序运算符来标识。基本要求是该聚合函数必须返回运算符所诱导排序顺序中的首项元素;换言之:
SELECT agg(col) FROM tab;
必须等同于:
SELECT col FROM tab ORDER BY col USING sortop LIMIT 1;
进一步假设聚合函数会忽略空值输入,并且仅当所有输入均为空值时才会返回空值结果。通常情况下,数据类型的<运算符是min()的正确排序运算符,而>运算符是max()的正确排序运算符。请注意,除非指定的运算符是B树索引运算符类中的"小于"或"大于"策略成员,否则该优化策略永远不会实际生效。
要创建聚合函数,必须对参数类型、状态类型和返回类型拥有USAGE权限,并对支持函数拥有EXECUTE权限。
您可以将combinefunc指定为优化聚合执行的方法。通过指定combinefunc,聚合操作可先在分段节点并行执行,再由协调节点进行汇总。当执行两级聚合时,sfunc在分段节点运行以生成部分聚合结果,combinefunc则在协调节点运行以汇总各分段节点的部分结果。若执行单级聚合,则所有行数据将发送至协调节点,并在该节点上对行数据应用 sfunc 操作。
单层聚合与双层聚合是等效的执行策略。这两种聚合方式均可在查询计划中实现。当实现组合函数(combinefunc)和子函数(sfunc)时,必须确保对分段实例调用子函数后,再由协调器执行组合函数所产生的结果,与将所有行发送至协调器后仅对行应用子函数的单层聚合结果完全一致。
name
argmode
argname
arg_data_type
base_type
sfunc
state_data_type
state_data_size
ffunc
在遍历所有输入行后用于计算聚合结果的最终函数名称。该函数必须接受一个类型为 state_data_type 的参数。聚合函数的返回数据类型即定义为该函数的返回类型。若未指定 ffunc,则使用结束状态值作为聚合结果,且返回类型为 state_data_type。
对于有序集合(包括假设集合)聚合,最终函数不仅接收最终状态值,还接收所有直接参数的值。
若指定了 FINALFUNC_EXTRA,则最终函数除接收最终状态值和任何直接参数外,还会获得额外的 NULL 值,这些值对应于聚合函数的常规(聚合)参数。此特性主要用于在定义多态聚合函数时,确保聚合结果类型的正确解析。
FINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE }
combinefunc
serialfunc
deserialfunc
initial_condition
msfunc
minvfunc -在移动聚合模式下使用的逆向状态转换函数名称。该函数与 msfunc 具有相同的参数和结果类型,但用于从当前聚合状态中移除值,而非向其添加值。逆向转换函数必须与正向状态转换函数具有相同的严格性属性。
mstate_data_type
mstate_data_size
mffunc
MFINALFUNC_MODIFY = { READ_ONLY | SHAREABLE | READ_WRITE }
minitial_condition
sort_operator
PARALLEL = { SAFE | RESTRICTED | UNSAFE }
REPSAFE = boolean
REPSAFE = true 将指示优化器执行额外的优化操作,这些操作专门用于抑制某些广播操作。注意 对于顺序相关的聚合函数,若错误地设置
REPSAFE = true,可能会导致结果不正确。
CREATE AGGREGATE 语句的参数可以按任意顺序编写,而不仅限于上文所示的顺序。
以下简单示例创建了一个计算两列之和的聚合函数。
在创建聚合函数之前,需先创建两个函数,它们将作为聚合函数的sfunc和combinefunc函数使用。
该函数被指定为聚合函数中的 sfunc 函数。
CREATE FUNCTION mysfunc_accum(numeric, numeric, numeric)
RETURNS numeric
AS ‘select $1 + $2 + $3’
LANGUAGE SQL
RETURNS NULL ON NULL INPUT;
该函数在聚合函数中被指定为 combinefunc 函数。
CREATE FUNCTION mycombine_accum(numeric, numeric )
RETURNS numeric
AS ‘select $1 + $2’
LANGUAGE SQL
RETURNS NULL ON NULL INPUT;
此 CREATE AGGREGATE 命令创建用于累加两列的聚合函数。
CREATE AGGREGATE agg_twocols(numeric, numeric) (
SFUNC = mysfunc_accum,
STYPE = numeric,
COMBINEFUNC = mycombine_accum,
INITCOND = 0 );
以下命令创建表、插入数据并运行聚合函数:
CREATE TABLE t1 (a int, b int) DISTRIBUTED BY (a);
INSERT INTO t1 VALUES
(10, 1),
(20, 2),
(30, 3);
SELECT agg_twocols(a, b) FROM t1;
有关创建聚合函数的更多示例,请参阅PostgreSQL文档中的《用户自定义聚合函数》。
CREATE AGGREGATE 是一种 YMatrix 的语言扩展。SQL 标准没有提供 用户定义的聚集函数。