Java UDF Return Values

In the documentation, if you have a return value that is not numeric you need to specify the size/precision of the return type in a method in the Factory class. In the example, this is done by using the length of an input argument. My problem is that my processing block takes this data and potentially makes the size smaller than the input value. When I return the value, it seems to back fill any chars to the new Varchar until it fills all the space specified in the Factory class(e.g. input arg = 'ATGC' and the output value = 'TGC' dropping the 'A'. What appears when I use the function in SQL is 'TCGT'). This is unexpected and undesired for my application. Is there anyway for setting the size of the return value dynamically so that no back filling takes place?

Comments

  • Hi Bill,

    You can specify the return type dynamically in the getReturnType() method. But that can be done only once before the actual processing of the data starts, so if you want to look at the length of each row and set the return type accordingly then that is not feasible. But what yo can do is look at the size of the input column at run time and set the return type based on that.
    Here is a simple example in which we are trying to concatenate two strings :
    class ConcatStringEA : public ScalarFunction{
    virtual void processBlock(ServerInterface &srvInterface,                              BlockReader &arg_reader,
                              BlockWriter &res_writer) {    do {
            const VString &a = arg_reader.getStringRef(0);
            const VString &b = arg_reader.getStringRef(1);
            std::string c = a.str() + b.str();
            VString &result = res_writer.getStringRef();
            result.copy(c);
            res_writer.next();
        } while (arg_reader.next());
    }
    };
    class ConcatStringEAInfo : public ScalarFunctionFactory
    {
        virtual ScalarFunction *createScalarFunction(ServerInterface &srvInterface)
        { return vt_createFuncObject<ConcatStringEA>(srvInterface.allocator); }
       // This looks at the length of both the input columns, adds them and sets the length of the output column
    virtual void getReturnType(ServerInterface &srvInterface,
                               const SizedColumnTypes &argTypes,
                               SizedColumnTypes &returnType)
        {
            returnType.addVarchar( argTypes.getColumnType(0).getStringLength() +
                argTypes.getColumnType(1).getStringLength());
        }
        virtual void getPrototype(ServerInterface &srvInterface,
                                  ColumnTypes &argTypes,
                                  ColumnTypes &returnType)
        {
            argTypes.addVarchar();
            argTypes.addVarchar();
            returnType.addVarchar();
        }
    };


    Pratibha
  • Thanks Pratbha,

     I found that I had a bug in my code in that I was using the substring() method of String intead of charAT() to build the string one char at a time. This change fixed the issue I was having. Thanks for your response though.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file