Fortran语言标量函数
下面的示例展示了一个简单的标量函数,用于对一组数字求和。 本例从一开始就构建了一个简单的 AE。 它使用以下文件名:"applyop.f
代码
- 创建程序并调用 "
nzaeRun()。 该调用会设置 AE,然后回调到 "nzaeHandleRequest(),这是实现Fortran所必需的。 这通常可以通过使用program applyopProgram call nzaeRun() stop end subroutine nzaeHandleRequest(handle) c Our custom Fortran code will go here. return end - 完成定制的Fortran代码。 在此 UDF 中,您需要输入一个字符串运算符,即 "+"(加)或 "*"(乘),以及两个整数。 代码会返回乘积或整数之和。 在 SQL 中,其简单版本可以通过以下任一方式调用:
或SELECT applyop('+', 3, 5);SELECT applyop('*', 3, 5);虽然上述例子只有一个输入,但核动力源系统处理的是输入流。 因此,新农保系统更容易使用:SELECT applyop(mytable.operator, mytable.value1, mytable.value2) FROM mytable;在第一个例子中,NPS 系统将常数 "+"、3 和 5 转化为长度为 1 的包含三个元素的数据流。 在内部,所有提到的情况都是以同样的方式处理的,可以假设 "
applyopAE 有多个输入。 - 需要一个处理输入的循环,这在Fortran77 中可以通过 "
if语句和 "goto语句来实现。 例如:program applyopProgram call nzaeRun() stop end subroutine nzaeHandleRequest(handle) integer hasNext, leftInput, rightInput, result character operator hasNext = -1 10 call nzaeGetNext(handle, hasNext) if (hasNext .eq. 0) then goto 20 endif c Our loop work will go here. goto 10 20 return end注意 "
hasNext变量的初始化。 这对于调用底层接口的 "out "变量来说是必要的。 否则,"hasNext指针将保持未分配状态,无法从底层调用中接收数据。 ThenzaeGetNext()function sets the variablehasNextto 1 (TRUE) if there is another element in the stream, and to 0 (FALSE) if the stream is done. - 添加逻辑:
program applyOpProgram call nzaeRun() stop end subroutine nzaeHandleRequest(handle) integer hasNext, leftInput, rightInput, isNull, result character operator hasNext = -1 leftInput = 0 rightInput = 0 operator = 'f' isNull = 0 10 call nzaeGetNext(handle, hasNext) if (hasNext .eq. 0) then goto 20 endif c GET OUR INPUT. call nzaeGetInputString(handle, 0, operator, isNull) call nzaeGetInputInt32(handle, 1, leftInput, isNull) call nzaeGetInputInt32(handle, 2, rightInput, isNull) c OPERATE. if (operator .eq. '+') then result = leftInput + rightInput else if (operator .eq. '*') then result = leftInput * rightInput else call nzaeUserError(handle, 'Unhandled operator.') endif c OUTPUT. call nzaeSetOutputInt32(handle, 0, result) call nzaeOutputResult(handle) goto 10 20 return end循环中的每个输入都包含传入函数的三个元素。 函数 "
nzaeGetInputX()接收代表一个用户请求的句柄、一列索引(在本例中,0 表示操作符,1 表示左输入,2 表示右输入)和输出变量。 函数 "nzaeUserError()向 SQL 用户报告错误。 函数 "nzaeSetOutputX()输出结果。 由于这是作为 UDF 运行的,因此结果中只能有一列。 后面的示例演示了如何使用 UDTF 输出多列。 代码完成后,必须进行编译和注册。
编译
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language fortran --version 3 \
--template compile --exe applyopFortran applyop.f输出的可执行文件,一个用于主机,一个用于 SPU,分别置于 "/nz/export/ae/applications/$NZ_USER/$NZ_DATABASE中的 "host和 "spu目录下。
注册
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language fortran --version 3 \
--template udf --exe applyopFortran \
--sig "applyop_fortran(varchar(1), int4, int4)" --return int4正在运行
SELECT applyop_fortran('+', 4, 10);
APPLYOP
---------
14
(1 row)
nzaeHandleRequest()中的类型时,会调用 "nzaeUserError()来发送错误信息。 以下示例会引发错误:SELECT applyop_fortran('-',1,2);
ERROR: Unhandled operator.