创建多态 UDx

多态 UDx 可接受用户提供的任何数量的参数和任何类型的参数。转换函数 (UDTF)、分析函数 (UDAnF) 和聚合函数 (UDAF) 通常可以在运行时基于输入实参来定义输出返回类型。例如,将两个数字相加的 UDTF 可以返回整数或浮点数,具体取决于输入类型。

Vertica 不会检查用户传递到 UDx 的实参数量或类型,而只会向 UDx 传递用户提供的所有实参。多态 UDx 的主要处理函数(例如,用户定义的标量函数中的 processBlock())负责检查收到的实参数量和类型以及确定是否能够处理这些实参。UDx 最多支持 9800 个实参。

多态 UDx 比使用函数的多个工厂类更灵活(请参阅重载 UDx)。使用它们还可以编写更简洁的代码,而不是为每种数据类型编写不同的代码版本。代价是您的多态函数需要执行更多操作来确定它是否可以处理其实参。

多态 UDx 通过对 ColumnTypes 对象(定义其实参)调用 addAny() 函数,在其工厂的 getPrototype() 函数中声明它接受任何数量的实参,如下所示:

    // C++ example
    void getPrototype(ServerInterface &srvInterface,
                      ColumnTypes &argTypes,
                      ColumnTypes &returnType)
    {
        argTypes.addAny(); // Must be only argument type.
        returnType.addInt(); // or whatever the function returns
    }

您的函数只能声明此“any parameter”参数类型。不能定义必需参数,然后调用 addAny() 以声明其余签名作为可选参数。如果您的函数对其接受的实参有所要求,您的 process() 函数必须强制使用这些实参。

前面显示的 getPrototype() 示例接受任何类型并声明它会返回整数。以下示例显示将解析返回类型推迟到运行时的方法版本。您只能将“any”返回类型用于转换函数和分析函数。

    void getPrototype(ServerInterface &srvInterface,
                      ColumnTypes &argTypes,
                      ColumnTypes &returnType)
    {
        argTypes.addAny();
        returnType.addAny(); // type determined at runtime
    }

如果使用多态返回类型,则还必须在工厂中定义 getReturnType()。在运行时调用此函数可确定实际返回类型。有关示例,请参阅 C++ 示例:PolyNthValue

多态 UDx 和架构搜索路径

如果用户在调用 UDx 时未提供架构名称,Vertica 会在架构搜索路径中的每个架构中搜索其名称和签名与函数调用相匹配的函数。有关架构搜索路径的详细信息,请参阅设置搜索路径

由于多态 UDx 没有与其关联的特定签名,Vertica 最初在搜索函数以处理函数调用时会跳过它们。如果搜索路径中没有架构包含其名称和签名与函数调用相匹配的 UDx,Vertica 会再次在架构搜索路径中搜索其名称与函数调用中的函数名称相匹配的多态 UDx。

此行为会为其签名与函数调用完全匹配的 UDx 赋予优先权。它允许您创建“捕获全部”多态 UDx,仅当没有任何同名非多态 UDx 具有匹配的签名时,Vertica 才调用该多态 UDx。

如果用户期望架构搜索路径中的第一个多态函数处理函数调用,此行为可能会造成混乱。为了避免混乱,您应该:

  • 避免不同 UDx 使用相同的名称。应始终唯一命名 UDx,除非您要创建具有多个签名的过载 UDx。

  • 当无法避免在不同架构中使用同名 UDx 时,请始终在函数调用中提供架构名称。使用架构名称可避免产生歧义,并确保 Vertica 使用正确的 Udx 来处理函数调用。