设置 null 输入和波动性行为

一般情况下,Vertica 会为查询中的每个数据行调用 UDSF。在某些情况下,Vertica 可以避免执行您的 UDSF。您可以告知 Vertica 何时能够跳过函数调用,而只需通过更改函数的波动性和严格性设置来提供返回值本身。

  • 函数的波动性 是指在传递相同的参数时,它是否始终返回相同的输出值。根据其行为,Vertica 可以缓存实参和返回值。如果用户使用相同的实参集来调用 UDSF,Vertica 会返回缓存值,而不会调用 UDSF。

  • 函数的严格性 是指它如何对 NULL 实参作出响应。如果“任何”实参为 NULL 时它始终返回 NULL,则 Vertica 可以只返回 NULL,而无需调用函数。此优化还可以节省工作量,因为您无需在 UDSF 代码中测试并处理 Null 参数。

可以通过在 ScalarFunctionFactory 类的构造函数中设置 volstrict 字段来指示函数的可变性和空值处理。

可变性设置

要指示函数的可变性,请将 vol 字段设置为以下值之一:

示例

以下示例显示了使函数不可变的 Add2ints 示例工厂类的某个版本。

class Add2intsImmutableFactory : public Vertica::ScalarFunctionFactory
{
    virtual Vertica::ScalarFunction *createScalarFunction(Vertica::ServerInterface &srvInterface)
    { return vt_createFuncObj(srvInterface.allocator, Add2ints); }
    virtual void getPrototype(Vertica::ServerInterface &srvInterface,
                              Vertica::ColumnTypes &argTypes,
                              Vertica::ColumnTypes &returnType)
    {
        argTypes.addInt();
        argTypes.addInt();
        returnType.addInt();
    }

public:
    Add2intsImmutableFactory() {vol = IMMUTABLE;}
};
RegisterFactory(Add2intsImmutableFactory);

以下示例演示了将 Add2IntsFactoryvol 字段设置为 IMMUTABLE 以向 Vertica 说明可以缓存实参和返回值。

public class Add2IntsFactory extends ScalarFunctionFactory {

    @Override
    public void getPrototype(ServerInterface srvInterface, ColumnTypes argTypes, ColumnTypes returnType){
        argTypes.addInt();
        argTypes.addInt();
        returnType.addInt();
    }

    @Override
    public ScalarFunction createScalarFunction(ServerInterface srvInterface){
        return new Add2Ints();
    }

    // Class constructor
    public Add2IntsFactory() {
        // Tell Vertica that the same set of arguments will always result in the
        // same return value.
        vol = volatility.IMMUTABLE;
    }
}

Null 输入行为

要指示函数如何响应 Null 输入,请将 strictness 字段设置为以下值之一:

示例

以下 C++ 示例演示了设置 Add2ints 的 null 行为以使 Vertica 不调用带有 NULL 值的函数。

class Add2intsNullOnNullInputFactory : public Vertica::ScalarFunctionFactory
{
    virtual Vertica::ScalarFunction *createScalarFunction(Vertica::ServerInterface &srvInterface)
    { return vt_createFuncObj(srvInterface.allocator, Add2ints); }
    virtual void getPrototype(Vertica::ServerInterface &srvInterface,
                              Vertica::ColumnTypes &argTypes,
                              Vertica::ColumnTypes &returnType)
    {
        argTypes.addInt();
        argTypes.addInt();
        returnType.addInt();
    }

public:
    Add2intsNullOnNullInputFactory() {strict = RETURN_NULL_ON_NULL_INPUT;}
};
RegisterFactory(Add2intsNullOnNullInputFactory);