ScalarFunction 类
ScalarFunction
类是 UDSF 的核心。子类必须定义用于执行标量操作的 processBlock()
方法。该类可定义多种方法以设置和分解该函数。
对于使用 C++ 语言编写的标量函数,您可以提供有助于优化查询的信息。请参阅提高查询性能(仅限 C++)。
执行操作
processBlock()
方法可执行您希望 UDSF 执行的所有处理。当用户在 SQL 语句中调用您的函数时,Vertica 会将来自函数参数的数据绑定在一起并将其传递至 processBlock()
。
processBlock()
方法的输入和输出由 BlockReader
和 BlockWriter
类的对象提供。这些类定义了用于为 UDSF 读取输入数据和写入输出数据的方法。
开发 UDSF 的大部分工作是编写 processBlock()
。对函数的所有处理在此阶段进行。UDSF 应遵循以下基本模式:
-
使用特定于数据类型的方法从
BlockReader
对象读入一组实参。 -
以某种方式处理数据。
-
使用
BlockWriter
类的特定于数据类型的方法之一输出结果值。 -
通过调用
BlockWriter.next()
和BlockReader.next()
分别前进到下一个输出行和下一个输入行。
此过程将持续到没有更多数据行可供读取为止(BlockReader.next()
将返回 false)。
您必须确保 processBlock()
读取所有输入行并为每个行输出单个值。如未遵守此规则,将损坏 Vertica 为获取 UDSF 的输出而读取的数据结构。此规则的唯一例外出现在 processBlock()
函数将错误报告回 Vertica 时(请参阅处理错误)。在这种情况下,Vertica 不会尝试读取由 UDSF 生成的不完整结果集。
设置和分解
ScalarFunction
类定义了两种其他方法,您可以选择性地实施这两种方法以分配和释放资源: setup()
和 destroy()
。您应使用这些方法来分配和取消分配那些不通过 UDx API 分配的资源(有关详细信息,请参阅为 UDx 分配资源)。
注意
-
虽然为
ScalarFunction
子类选择的名称不必与稍后为其分配的 SQL 函数名称匹配,但 Vertica 会将名称设为相同视为最佳实践。 -
请勿假设系统会从将函数实例化的同一个线程调用该函数。
-
可以调用
ScalarFunction
子类的同一个实例以处理多个数据块。 -
不保证发送到
processBlock()
的输入行具有特定顺序。 -
写入太多输出行会导致 Vertica 发出超过边界错误。
API
ScalarFunction API 提供了以下通过子类扩展的方法:
virtual void setup(ServerInterface &srvInterface,
const SizedColumnTypes &argTypes);
virtual void processBlock(ServerInterface &srvInterface,
BlockReader &arg_reader, BlockWriter &res_writer)=0;
virtual void getOutputRange (ServerInterface &srvInterface,
ValueRangeReader &inRange, ValueRangeWriter &outRange)
virtual void cancel(ServerInterface &srvInterface);
virtual void destroy(ServerInterface &srvInterface, const SizedColumnTypes &argTypes);
ScalarFunction API 提供了以下通过子类扩展的方法:
public void setup(ServerInterface srvInterface, SizedColumnTypes argTypes);
public abstract void processBlock(ServerInterface srvInterface, BlockReader arg_reader,
BlockWriter res_writer) throws UdfException, DestroyInvocation;
protected void cancel(ServerInterface srvInterface);
public void destroy(ServerInterface srvInterface, SizedColumnTypes argTypes);
ScalarFunction API 提供了以下通过子类扩展的方法:
def setup(self, server_interface, col_types)
def processBlock(self, server_interface, block_reader, block_writer)
def destroy(self, server_interface, col_types)
实施 主函数 API 以定义标量函数:
FunctionName <- function(input.data.frame, parameters.data.frame) {
# Computations
# The function must return a data frame.
return(output.data.frame)
}