C++ 示例:重载 UDx
以下示例代码演示了创建一个将两个或三个整数相加的用户定义标量函数 (UDSF)。Add2or3ints
类已准备好处理两个或三个参数。processBlock()
函数将检查已传入的参数个数,并将两个或三个参数全部相加。此外,如果对此函数发出的调用具有少于 2 个参数或具有多于 3 个参数,此函数将退出并显示错误消息。理论上,这不应当发生,因为如果用户的函数调用与您为函数创建的某一个工厂类上的签名相匹配,则 Vertica 仅调用 UDSF。在实践中,如果您的(或其他人的)工厂类不正确地报告函数类无法处理一组参数,最好执行此健全性检查。
此示例具有两个 ScalarFunctionFactory
类,函数所接受的每个签名(两个整数和三个整数)各一个。除了其 ScalarFunctionFactory::createScalarFunction()
实施都将创建 Add2or3ints
对象之外,这两个工厂类没有其他例外情况。
最后一步是将同一个 SQL 函数名称绑定到这两个工厂类。只要每个工厂的 getPrototype()
实施所定义的签名不相同,您就可以将多个工厂分配给同一个 SQL 函数。
=> CREATE LIBRARY add2or3IntsLib AS '/home/dbadmin/Add2or3Ints.so';
CREATE LIBRARY
=> CREATE FUNCTION add2or3Ints as NAME 'Add2intsFactory' LIBRARY add2or3IntsLib FENCED;
CREATE FUNCTION
=> CREATE FUNCTION add2or3Ints as NAME 'Add3intsFactory' LIBRARY add2or3IntsLib FENCED;
CREATE FUNCTION
=> SELECT add2or3Ints(1,2);
add2or3Ints
-------------
3
(1 row)
=> SELECT add2or3Ints(1,2,4);
add2or3Ints
-------------
7
(1 row)
=> SELECT add2or3Ints(1,2,3,4); -- Will generate an error
ERROR 3467: Function add2or3Ints(int, int, int, int) does not exist, or
permission is denied for add2or3Ints(int, int, int, int)
HINT: No function matches the given name and argument types. You may
need to add explicit type casts
Vertica 在对 add2or3Ints 函数的最终调用的响应中生成了错误消息,因为它无法找到与接受了四个整数实参的 add2or3Ints 关联的工厂类。要进一步扩展 add2or3Ints,您可以创建可接受此签名的另一个工厂类,然后更改 Add2or3ints ScalarFunction 类,或者创建完全不同的类以处理更多整数的相加。但是,添加更多类可以快速接受参数中的每个变体,这具有压倒性优势。在这种情况下,您应考虑创建多态 UDx。